From 029bf038708559c0393d7ad3f7307fe2902cbef3 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 2 Nov 2021 13:41:55 -0700 Subject: [PATCH 001/272] Changed PassBuilder's job dependencies to be OrderOnce. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a normal job dependency was overkill. As a result, modifying a shader would trigger a pass to rebuild, and that would cause the entire render pipeline to reinitialize. This causes a lot of unnecessary churn that made debugging shader hot reloads difficult. When a builder depends on knowing the UUID of another asset, it does need to have a job dependency on that asset. But when the builder doesn’t actually consume any data from inside the asset, and it just needs the ID, it is best to use JobDependencyType::OrderOnce to simply make sure the AP knows about the asset. Also, the call to GetSourceInfoBySourcePath was an unnecessary check because the AP does not require the file to exist at the time a dependency is reported. GetSourceInfoBySourcePath will only succeed after the AP has scanned the requested source file. We can’t just assume that a false result indicates the file does not exist, it just isn’t known yet. There are a couple additional use cases to be aware of (from @antonmic)... 1. Passes are critical assets, and some passes depend on shaders, so those shaders need to be processed, that's one reason for the dependency (otherwise you can start the engine, load all critical passes, try to load the shader, shader isn't ready, and bad things happen) 2. If a shader is deleted/removed, the pass should try to rebuild and fail. This was a recent issue that I fixed, you could have some odd condition where you delete a shader, but the pass that references that shader doesn't update or throw any errors because it doesn't rebuild, so the user is unaware that they need to change the .pass file and bad things happen OrderOnce is sufficient for both these cases. #1 is related to first time processing which exactly the time when OrderOnce would be applied. I tested #2 as well; deleting a .shader file with OrderOnce dependency did trigger the .pass file to rebuild and fail. Testing: Ran an ASV pass test with both an exiting cache and after deleting the local cache. Started the Editor with a clean cache and didn't encounter any startup issues. Was able to successfully load a level the first time. Deleted SkyBox.shader and saw SkyBox.pass fail in the AP. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Source/RPI.Builders/Pass/PassBuilder.cpp | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp index 6a0b10633e..e2d4bd629a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp @@ -53,7 +53,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc builder; builder.m_name = PassBuilderJobKey; - builder.m_version = 14; // making .pass files emit product dependencies for the shaders they reference so they are picked up by the asset bundler + builder.m_version = 15; // Changed dependency type to OrderOnce builder.m_busId = azrtti_typeid(); builder.m_createJobFunction = AZStd::bind(&PassBuilder::CreateJobs, this, AZStd::placeholders::_1, AZStd::placeholders::_2); builder.m_processJobFunction = AZStd::bind(&PassBuilder::ProcessJob, this, AZStd::placeholders::_1, AZStd::placeholders::_2); @@ -97,27 +97,16 @@ namespace AZ // Helper function to get a file reference and create a corresponding job dependency bool AddDependency(FindPassReferenceAssetParams& params, AssetBuilderSDK::JobDescriptor* job) { - AZStd::string_view& file = params.dependencySourceFile; - AZ::Data::AssetInfo sourceInfo; - AZStd::string watchFolder; - bool fileFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fileFound, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, file.data(), sourceInfo, watchFolder); - - if (fileFound) - { - AssetBuilderSDK::JobDependency jobDependency; - jobDependency.m_jobKey = params.jobKey; - jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order; - jobDependency.m_sourceFile.m_sourceFileDependencyPath = file; - job->m_jobDependencyList.push_back(jobDependency); - AZ_TracePrintf(PassBuilderName, "Creating job dependency on file [%s] \n", file.data()); - return true; - } - else - { - AZ_Error(PassBuilderName, false, "Could not find referenced file [%s]", file.data()); - return false; - } + // We use an OrderOnce job dependency to ensure that the Asset Processor knows about the + // referenced asset, so we can make an AssetId for it later in ProcessJob. OrderOnce is + // enough because we don't need to read any data from the asset, we just needs its ID. + AssetBuilderSDK::JobDependency jobDependency; + jobDependency.m_jobKey = params.jobKey; + jobDependency.m_type = AssetBuilderSDK::JobDependencyType::OrderOnce; + jobDependency.m_sourceFile.m_sourceFileDependencyPath = params.dependencySourceFile; + job->m_jobDependencyList.push_back(jobDependency); + AZ_TracePrintf(PassBuilderName, "Creating job dependency on file [%.*s] \n", AZ_STRING_ARG(params.dependencySourceFile)); + return true; } bool SetJobKeyForExtension(const AZStd::string& filePath, FindPassReferenceAssetParams& params) From f36255b22ad0115c2cd86b184ff9f8518419857e Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 8 Dec 2021 13:57:24 -0800 Subject: [PATCH 002/272] Initial value implementation Signed-off-by: Nicholas Van Sickle --- .../AzCore/AzCore/DOM/DomDocument.cpp | 0 .../Framework/AzCore/AzCore/DOM/DomDocument.h | 0 Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 747 ++++++++++++++++++ Code/Framework/AzCore/AzCore/DOM/DomValue.h | 289 +++++++ .../AzCore/AzCore/azcore_files.cmake | 4 + 5 files changed, 1040 insertions(+) create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomDocument.h create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomValue.cpp create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomValue.h diff --git a/Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp b/Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Code/Framework/AzCore/AzCore/DOM/DomDocument.h b/Code/Framework/AzCore/AzCore/DOM/DomDocument.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp new file mode 100644 index 0000000000..ad6e648620 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include + +namespace AZ::Dom +{ + template + AZStd::shared_ptr& CheckCopyOnWrite(AZStd::shared_ptr& refCountedPointer) + { + if (refCountedPointer.use_count() > 1) + { + AZStd::shared_ptr newPointer = AZStd::make_shared(); + *newPointer = *refCountedPointer; + refCountedPointer = AZStd::move(newPointer); + } + return refCountedPointer; + } + + AZ::Name Node::GetName() const + { + return m_name; + } + + void Node::SetName(AZ::Name name) + { + m_name = name; + } + + ObjectPtr Node::GetMutableProperties() + { + CheckCopyOnWrite(m_object); + return m_object; + } + + ConstObjectPtr Node::GetProperties() const + { + return m_object; + } + + ArrayPtr Node::GetMutableChildren() + { + CheckCopyOnWrite(m_array); + return m_array; + } + + ConstArrayPtr Node::GetChildren() const + { + return m_array; + } + + bool Node::operator==(const Node& rhs) const + { + return m_name == rhs.m_name && m_array == rhs.m_array && m_object == rhs.m_object; + } + + Value::Value() + { + } + + Value::Value(const Value& value) + : m_value(value.m_value) + { + } + + Value::Value(Value&& value) noexcept + : m_value(value.m_value) + { + } + + Value::Value(AZStd::string_view string, bool copy) + { + if (copy) + { + CopyFromString(string); + } + else + { + SetString(string); + } + } + + Value::Value(AZStd::any* value) + : m_value(value) + { + } + + Value Value::FromOpaqueValue(AZStd::any& value) + { + return Value(&value); + } + + Value::Value(int64_t value) + : m_value(value) + { + } + + Value::Value(uint64_t value) + : m_value(value) + { + } + + Value::Value(double value) + : m_value(value) + { + } + + Value::Value(bool value) + : m_value(value) + { + } + + Value& Value::operator=(const Value& other) + { + m_value = other.m_value; + return *this; + } + + Value& Value::operator=(Value&& other) noexcept + { + m_value = other.m_value; + return *this; + } + + bool Value::operator==(const Value& rhs) const + { + if (IsString() && rhs.IsString()) + { + return GetString() == rhs.GetString(); + } + else if (IsNumber() && rhs.IsNumber()) + { + if (IsInt()) + { + return GetInt() == rhs.GetInt(); + } + else if (IsUint()) + { + return GetUint() == rhs.GetUint(); + } + else + { + return GetDouble() == rhs.GetDouble(); + } + } + else + { + return m_value == rhs.m_value; + } + } + + bool Value::operator!=(const Value& rhs) const + { + return !operator==(rhs); + } + + void Value::Swap(Value& other) noexcept + { + AZStd::swap(m_value, other.m_value); + } + + Type Dom::Value::GetType() const + { + switch (m_value.index()) + { + case 0: // AZStd::monostate + return Type::NullType; + case 1: // int64_t + case 2: // uint64_t + case 3: // double + return Type::NumberType; + case 4: // bool + return AZStd::get(m_value) ? Type::TrueType : Type::FalseType; + case 5: // AZStd::string_view + case 6: // AZStd::shared_ptr + return Type::StringType; + case 7: // ObjectPtr + return Type::ObjectType; + case 8: // ArrayPtr + return Type::ArrayType; + case 9: // Node + return Type::NodeType; + case 10: // AZStd::any* + return Type::OpaqueType; + } + AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + return Type::NullType; + } + + bool Value::IsNull() const + { + return GetType() == Type::NullType; + } + + bool Value::IsFalse() const + { + return GetType() == Type::FalseType; + } + + bool Value::IsTrue() const + { + return GetType() == Type::TrueType; + } + + bool Value::IsBool() const + { + return AZStd::holds_alternative(m_value); + } + + bool Value::IsNode() const + { + return GetType() == Type::NodeType; + } + + bool Value::IsObject() const + { + return GetType() == Type::ObjectType; + } + + bool Value::IsArray() const + { + return GetType() == Type::ArrayType; + } + + bool Value::IsOpaqueValue() const + { + return GetType() == Type::OpaqueType; + } + + bool Value::IsNumber() const + { + return GetType() == Type::NumberType; + } + + bool Value::IsInt() const + { + return AZStd::holds_alternative(m_value); + } + + bool Value::IsUint() const + { + return AZStd::holds_alternative(m_value); + } + + bool Value::IsDouble() const + { + return AZStd::holds_alternative(m_value); + } + + bool Value::IsString() const + { + return GetType() == Type::StringType; + } + + Value& Value::SetObject() + { + m_value = AZStd::make_shared(); + return *this; + } + + const Object::ContainerType& Value::GetObjectInternal() const + { + const Type type = GetType(); + AZ_Assert( + type == Type::ObjectType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an object from a non-object value"); + if (type == Type::ObjectType) + { + return AZStd::get(m_value)->m_values; + } + else + { + return AZStd::get(m_value).GetProperties()->m_values; + } + } + + Object::ContainerType& Value::GetObjectInternal() + { + const Type type = GetType(); + AZ_Assert( + type == Type::ObjectType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an object from a non-object value"); + if (type == Type::ObjectType) + { + return CheckCopyOnWrite(AZStd::get(m_value))->m_values; + } + else + { + return AZStd::get(m_value).GetMutableProperties()->m_values; + } + } + + const Array::ContainerType& Value::GetArrayInternal() const + { + const Type type = GetType(); + AZ_Assert( + type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a non-array value"); + if (type == Type::ObjectType) + { + return AZStd::get(m_value)->m_values; + } + else + { + return AZStd::get(m_value).GetChildren()->m_values; + } + } + + Array::ContainerType& Value::GetArrayInternal() + { + const Type type = GetType(); + AZ_Assert( + type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a non-array value"); + if (type == Type::ObjectType) + { + return CheckCopyOnWrite(AZStd::get(m_value))->m_values; + } + else + { + return AZStd::get(m_value).GetMutableChildren()->m_values; + } + } + + size_t Value::MemberCount() const + { + return GetObjectInternal().size(); + } + + size_t Value::MemberCapacity() const + { + return GetObjectInternal().size(); + } + + bool Value::ObjectEmpty() const + { + return GetObjectInternal().empty(); + } + + Value& Value::operator[](KeyType name) + { + return FindMember(name)->second; + } + + const Value& Value::operator[](KeyType name) const + { + return FindMember(name)->second; + } + + Value& Value::operator[](AZStd::string_view name) + { + return operator[](AZ::Name(name)); + } + + const Value& Value::operator[](AZStd::string_view name) const + { + return operator[](AZ::Name(name)); + } + + Object::ConstIterator Value::MemberBegin() const + { + return GetObjectInternal().begin(); + } + + Object::ConstIterator Value::MemberEnd() const + { + return GetObjectInternal().end(); + } + + Object::Iterator Value::MemberBegin() + { + return GetObjectInternal().begin(); + } + + Object::Iterator Value::MemberEnd() + { + return GetObjectInternal().end(); + } + + Object::ConstIterator Value::FindMember(KeyType name) const + { + const Object::ContainerType& object = GetObjectInternal(); + return AZStd::find_if( + object.begin(), object.end(), + [&name](const Object::EntryType& entry) + { + return entry.first == name; + }); + } + + Object::ConstIterator Value::FindMember(AZStd::string_view name) const + { + return FindMember(AZ::Name(name)); + } + + Object::Iterator Value::FindMember(KeyType name) + { + Object::ContainerType& object = GetObjectInternal(); + return AZStd::find_if( + object.begin(), object.end(), + [&name](const Object::EntryType& entry) + { + return entry.first == name; + }); + } + + Object::Iterator Value::FindMember(AZStd::string_view name) + { + return FindMember(AZ::Name(name)); + } + + Value& Value::MemberReserve(size_t newCapacity) + { + GetObjectInternal().reserve(newCapacity); + return *this; + } + + bool Value::HasMember(KeyType name) const + { + return FindMember(name) != GetObjectInternal().end(); + } + + bool Value::HasMember(AZStd::string_view name) const + { + return HasMember(AZ::Name(name)); + } + + Value& Value::AddMember(KeyType name, const Value& value) + { + Object::ContainerType& object = GetObjectInternal(); + if (auto memberIt = FindMember(name); memberIt != object.end()) + { + memberIt->second = value; + } + else + { + object.emplace_back(name, value); + } + return *this; + } + + Value& Value::AddMember(AZStd::string_view name, const Value& value) + { + return AddMember(AZ::Name(name), value); + } + + Value& Value::AddMember(AZ::Name name, Value&& value) + { + Object::ContainerType& object = GetObjectInternal(); + if (auto memberIt = FindMember(name); memberIt != object.end()) + { + memberIt->second = value; + } + else + { + object.emplace_back(name, value); + } + return *this; + } + + Value& Value::AddMember(AZStd::string_view name, Value&& value) + { + return AddMember(AZ::Name(name), value); + } + + void Value::RemoveAllMembers() + { + GetObjectInternal().clear(); + } + + void Value::RemoveMember(KeyType name) + { + Object::ContainerType& object = GetObjectInternal(); + object.erase(AZStd::remove_if( + object.begin(), object.end(), + [&name](const Object::EntryType& entry) + { + return entry.first == name; + })); + } + + void Value::RemoveMember(AZStd::string_view name) + { + RemoveMember(AZ::Name(name)); + } + + Object::Iterator Value::RemoveMember(Object::Iterator pos) + { + Object::ContainerType& object = GetObjectInternal(); + Object::Iterator nextIndex = object.end(); + auto lastEntry = object.end() - 1; + if (pos != lastEntry) + { + AZStd::swap(*pos, *lastEntry); + nextIndex = pos; + } + object.resize(object.size() - 1); + return nextIndex; + } + + Object::Iterator Value::EraseMember(Object::ConstIterator pos) + { + return GetObjectInternal().erase(pos); + } + + Object::Iterator Value::EraseMember(Object::ConstIterator first, Object::ConstIterator last) + { + return GetObjectInternal().erase(first, last); + } + + Object::Iterator Value::EraseMember(KeyType name) + { + return GetObjectInternal().erase(FindMember(name)); + } + + Object::Iterator Value::EraseMember(AZStd::string_view name) + { + return EraseMember(AZ::Name(name)); + } + + Object::ContainerType& Value::GetObject() + { + return GetObjectInternal(); + } + + const Object::ContainerType& Value::GetObject() const + { + return GetObjectInternal(); + } + + Value& Value::SetArray() + { + m_value = AZStd::make_shared(); + return *this; + } + + size_t Value::Size() const + { + return GetArrayInternal().size(); + } + + size_t Value::Capacity() const + { + return GetArrayInternal().capacity(); + } + + bool Value::Empty() const + { + return GetArrayInternal().empty(); + } + + void Value::Clear() + { + GetArrayInternal().clear(); + } + + Value& Value::operator[](size_t index) + { + return GetArrayInternal()[index]; + } + + const Value& Value::operator[](size_t index) const + { + return GetArrayInternal()[index]; + } + + Array::ConstIterator Value::Begin() const + { + return GetArrayInternal().begin(); + } + + Array::ConstIterator Value::End() const + { + return GetArrayInternal().end(); + } + + Array::Iterator Value::Begin() + { + return GetArrayInternal().begin(); + } + + Array::Iterator Value::End() + { + return GetArrayInternal().end(); + } + + Value& Value::Reserve(size_t newCapacity) + { + GetArrayInternal().reserve(newCapacity); + return *this; + } + + Value& Value::PushBack(Value value) + { + GetArrayInternal().push_back(AZStd::move(value)); + return *this; + } + + Value& Value::PopBack() + { + GetArrayInternal().pop_back(); + return *this; + } + + Array::Iterator Value::Erase(Array::ConstIterator pos) + { + return GetArrayInternal().erase(pos); + } + + Array::Iterator Value::Erase(Array::ConstIterator first, Array::ConstIterator last) + { + return GetArrayInternal().erase(first, last); + } + + Array::ContainerType& Value::GetArray() + { + return GetArrayInternal(); + } + + const Array::ContainerType& Value::GetArray() const + { + return GetArrayInternal(); + } + + int64_t Value::GetInt() const + { + switch (m_value.index()) + { + case 1: // int64_t + return AZStd::get(m_value); + case 2: // uint64_t + return aznumeric_cast(AZStd::get(m_value)); + case 3: // double + return aznumeric_cast(AZStd::get(m_value)); + } + AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); + return {}; + } + + void Value::SetInt(int64_t value) + { + m_value = value; + } + + uint64_t Value::GetUint() const + { + switch (m_value.index()) + { + case 1: // int64_t + return aznumeric_cast(AZStd::get(m_value)); + case 2: // uint64_t + return AZStd::get(m_value); + case 3: // double + return aznumeric_cast(AZStd::get(m_value)); + } + AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); + return {}; + } + + void Value::SetUint(uint64_t value) + { + m_value = value; + } + + bool Value::GetBool() const + { + if (IsBool()) + { + return AZStd::get(m_value); + } + AZ_Assert(false, "AZ::Dom::Value: Called GetBool on a non-bool type"); + return {}; + } + + void Value::SetBool(bool value) + { + m_value = value; + } + + double Value::GetDouble() const + { + switch (m_value.index()) + { + case 1: // int64_t + return aznumeric_cast(AZStd::get(m_value)); + case 2: // uint64_t + return aznumeric_cast(AZStd::get(m_value)); + case 3: // double + return AZStd::get(m_value); + } + AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); + return {}; + } + + void Value::SetDouble(double value) + { + m_value = value; + } + + AZStd::string_view Value::GetString() const + { + switch (m_value.index()) + { + case 5: // AZStd::string_view + return AZStd::get(m_value); + case 6: // AZStd::shared_ptr + return *AZStd::get>(m_value); + } + AZ_Assert(false, "AZ::Dom::Value: Called GetString on a non-string type"); + return {}; + } + + size_t Value::GetStringLength() const + { + return GetString().size(); + } + + void Value::SetString(AZStd::string_view value) + { + m_value = value; + } + + void Value::CopyFromString(AZStd::string_view value) + { + m_value = AZStd::make_shared(value); + } + + AZStd::any& Value::GetOpaqueValue() const + { + return *AZStd::get(m_value); + } + + void Value::SetOpaqueValue(AZStd::any& value) + { + m_value = &value; + } + + void Value::SetNull() + { + m_value = AZStd::monostate(); + } +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h new file mode 100644 index 0000000000..f73dbb2549 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace AZ::Dom +{ + using KeyType = AZ::Name; + + enum class Type + { + NullType = 0, + FalseType = 1, + TrueType = 2, + ObjectType = 3, + ArrayType = 4, + StringType = 5, + NumberType = 6, + NodeType = 7, + OpaqueType = 8, + }; + + class Value; + + class Array + { + public: + using ContainerType = AZStd::vector; + using Iterator = ContainerType::iterator; + using ConstIterator = ContainerType::const_iterator; + + private: + ContainerType m_values; + + friend class Value; + }; + + using ArrayPtr = AZStd::shared_ptr; + using ConstArrayPtr = AZStd::shared_ptr; + + class Object + { + public: + using EntryType = AZStd::pair; + using ContainerType = AZStd::vector; + using Iterator = ContainerType::iterator; + using ConstIterator = ContainerType::const_iterator; + + private: + ContainerType m_values; + + friend class Value; + }; + + using ObjectPtr = AZStd::shared_ptr; + using ConstObjectPtr = AZStd::shared_ptr; + + class Node + { + public: + AZ::Name GetName() const; + void SetName(AZ::Name name); + + ObjectPtr GetMutableProperties(); + ConstObjectPtr GetProperties() const; + + ArrayPtr GetMutableChildren(); + ConstArrayPtr GetChildren() const; + + bool operator==(const Node& rhs) const; + + private: + AZ::Name m_name; + ArrayPtr m_array; + ObjectPtr m_object; + + friend class Value; + }; + + class Value + { + public: + // Constructors... + Value(); + Value(const Value&); + Value(Value&&) noexcept; + Value(AZStd::string_view string, bool copy); + + explicit Value(int64_t value); + explicit Value(uint64_t value); + explicit Value(double value); + explicit Value(bool value); + + static Value FromOpaqueValue(AZStd::any& value); + + // Equality / comparison / swap... + Value& operator=(const Value&); + Value& operator=(Value&&) noexcept; + + bool operator==(const Value& rhs) const; + bool operator!=(const Value& rhs) const; + + void Swap(Value& other) noexcept; + + // Type info... + Type GetType() const; + bool IsNull() const; + bool IsFalse() const; + bool IsTrue() const; + bool IsBool() const; + bool IsNode() const; + bool IsObject() const; + bool IsArray() const; + bool IsOpaqueValue() const; + bool IsNumber() const; + bool IsInt() const; + bool IsUint() const; + bool IsDouble() const; + bool IsString() const; + + // Object API (also used by Node)... + Value& SetObject(); + size_t MemberCount() const; + size_t MemberCapacity() const; + bool ObjectEmpty() const; + + Value& operator[](KeyType name); + const Value& operator[](KeyType name) const; + Value& operator[](AZStd::string_view name); + const Value& operator[](AZStd::string_view name) const; + + Object::ConstIterator MemberBegin() const; + Object::ConstIterator MemberEnd() const; + Object::Iterator MemberBegin(); + Object::Iterator MemberEnd(); + + Object::ConstIterator FindMember(KeyType name) const; + Object::ConstIterator FindMember(AZStd::string_view name) const; + Object::Iterator FindMember(KeyType name); + Object::Iterator FindMember(AZStd::string_view name); + + Value& MemberReserve(size_t newCapacity); + bool HasMember(KeyType name) const; + bool HasMember(AZStd::string_view name) const; + + Value& AddMember(KeyType name, const Value& value); + Value& AddMember(AZStd::string_view name, const Value& value); + Value& AddMember(KeyType name, Value&& value); + Value& AddMember(AZStd::string_view name, Value&& value); + + void RemoveAllMembers(); + void RemoveMember(KeyType name); + void RemoveMember(AZStd::string_view name); + Object::Iterator RemoveMember(Object::Iterator pos); + Object::Iterator EraseMember(Object::ConstIterator pos); + Object::Iterator EraseMember(Object::ConstIterator first, Object::ConstIterator last); + Object::Iterator EraseMember(KeyType name); + Object::Iterator EraseMember(AZStd::string_view name); + + Object::ContainerType& GetObject(); + const Object::ContainerType& GetObject() const; + + // Array API (also used by Node)... + Value& SetArray(); + + size_t Size() const; + size_t Capacity() const; + bool Empty() const; + void Clear(); + + Value& operator[](size_t index); + const Value& operator[](size_t index) const; + + Array::ConstIterator Begin() const; + Array::ConstIterator End() const; + Array::Iterator Begin(); + Array::Iterator End(); + + Value& Reserve(size_t newCapacity); + Value& PushBack(Value value); + Value& PopBack(); + + Array::Iterator Erase(Array::ConstIterator pos); + Array::Iterator Erase(Array::ConstIterator first, Array::ConstIterator last); + + Array::ContainerType& GetArray(); + const Array::ContainerType& GetArray() const; + + // Node API (supports both object + array API, plus a dedicated NodeName)... + // bool CanConvertToNodeFromObject() const; + // Value& ConvertToNodeFromObject(); + // Value& ConvertToObjectFromNode(); + + void SetNode(AZ::Name name); + void SetNode(AZStd::string_view name); + + AZ::Name GetNodeName() const; + void SetNodeName(AZ::Name name); + void SetNodeName(AZStd::string_view name); + //! Convenience method, sets the first non-node element of a Node. + void SetNodeValue(Value value); + //! Convenience method, gets the first non-node element of a Node. + Value GetNodeValue() const; + + // int API... + int64_t GetInt() const; + void SetInt(int64_t); + + // uint API... + uint64_t GetUint() const; + void SetUint(uint64_t); + + // bool API... + bool GetBool() const; + void SetBool(bool); + + // double API... + double GetDouble() const; + void SetDouble(double); + + // string API... + AZStd::string_view GetString() const; + size_t GetStringLength() const; + void SetString(AZStd::string_view); + void CopyFromString(AZStd::string_view); + + // opaque type API... + AZStd::any& GetOpaqueValue() const; + //! This sets this Value to represent a value of an type that the DOM has + //! no formal knowledge of. Where possible, it should be preferred to + //! serialize an opaque type into a DOM value instead, as serializers + //! and other systems will have no means of dealing with fully arbitrary + //! values. + void SetOpaqueValue(AZStd::any&); + + // null API... + void SetNull(); + + private: + const Object::ContainerType& GetObjectInternal() const; + Object::ContainerType& GetObjectInternal(); + const Array::ContainerType& GetArrayInternal() const; + Array::ContainerType& GetArrayInternal(); + + explicit Value(AZStd::any* opaqueValue); + + // If using the the copy on write model, anything stored internally as a shared_ptr will + // detach and copy when doing a mutating operation if use_count() > 1. + + // This internal storage will not have a 1:1 mapping to the public Type, as there may be + // multiple storage options (e.g. strings being stored as non-owning string_view or + // owning shared_ptr) + using ValueType = AZStd::variant< + // NullType + AZStd::monostate, + // NumberType + int64_t, + uint64_t, + double, + // FalseType & TrueType + bool, + // StringType + AZStd::string_view, + AZStd::shared_ptr, + // ObjectType + ObjectPtr, + // ArrayType + ArrayPtr, + // NodeType + Node, + // OpaqueType + AZStd::any*>; + + ValueType m_value; + }; +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index ef6c7434cc..fa9f94505f 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -127,8 +127,12 @@ set(FILES Debug/TraceReflection.h DOM/DomBackend.cpp DOM/DomBackend.h + DOM/DomDocument.cpp + DOM/DomDocument.h DOM/DomUtils.cpp DOM/DomUtils.h + DOM/DomValue.cpp + DOM/DomValue.h DOM/DomVisitor.cpp DOM/DomVisitor.h DOM/Backends/JSON/JsonBackend.h From fada7ace232457b578730be5870df61fb9c7cfa6 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 8 Dec 2021 22:22:18 -0800 Subject: [PATCH 003/272] Add visitor support to Value Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 306 ++++++++++++++++++ Code/Framework/AzCore/AzCore/DOM/DomValue.h | 49 ++- 3 files changed, 355 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index 9751b9cecc..2e78661518 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -21,4 +21,4 @@ namespace AZ::Dom::Utils { return backend.ReadFromBufferInPlace(string.data(), string.size(), visitor); } -} +} // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index ad6e648620..032e5795da 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -744,4 +744,310 @@ namespace AZ::Dom { m_value = AZStd::monostate(); } + + Visitor::Result Value::Accept(Visitor& visitor, bool copyStrings) const + { + Visitor::Result result = AZ::Success(); + + AZStd::visit( + [&](auto&& arg) + { + using Alternative = AZStd::decay_t; + + if constexpr (AZStd::is_same_v) + { + result = visitor.Null(); + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.Int64(arg); + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.Uint64(arg); + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.Double(arg); + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); + } + else if constexpr (AZStd::is_same_v>) + { + result = visitor.String(*arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.StartObject(); + if (result.IsSuccess()) + { + const Object::ContainerType& object = GetObjectInternal(); + for (const Object::EntryType& entry : object) + { + result = entry.second.Accept(visitor, copyStrings); + if (!result.IsSuccess()) + { + return; + } + } + result = visitor.EndObject(object.size()); + } + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.StartArray(); + if (result.IsSuccess()) + { + const Array::ContainerType& arrayContainer = GetArrayInternal(); + for (const Value& entry : arrayContainer) + { + result = entry.Accept(visitor, copyStrings); + if (!result.IsSuccess()) + { + return; + } + } + result = visitor.EndArray(arrayContainer.size()); + } + } + else if constexpr (AZStd::is_same_v) + { + const Node& node = AZStd::get(m_value); + result = visitor.StartNode(node.GetName()); + if (result.IsSuccess()) + { + const Object::ContainerType& object = GetObjectInternal(); + for (const Object::EntryType& entry : object) + { + result = entry.second.Accept(visitor, copyStrings); + if (!result.IsSuccess()) + { + return; + } + } + + const Array::ContainerType& arrayContainer = GetArrayInternal(); + for (const Value& entry : arrayContainer) + { + result = entry.Accept(visitor, copyStrings); + if (!result.IsSuccess()) + { + return; + } + } + + result = visitor.EndNode(object.size(), arrayContainer.size()); + } + } + else if constexpr (AZStd::is_same_v) + { + result = visitor.OpaqueValue(*arg); + } + }, + m_value); + return result; + } + + ValueWriter::ValueWriter(Value& outputValue) + : m_result(outputValue) + { + } + + VisitorFlags ValueWriter::GetVisitorFlags() const + { + return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects | VisitorFlags::SupportsNodes; + } + + ValueWriter::ValueInfo::ValueInfo(Value& container) + : m_container(container) + { + } + + Visitor::Result ValueWriter::Null() + { + CurrentValue().SetNull(); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Bool(bool value) + { + CurrentValue().SetBool(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Int64(AZ::s64 value) + { + CurrentValue().SetInt(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Uint64(AZ::u64 value) + { + CurrentValue().SetUint(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Double(double value) + { + CurrentValue().SetDouble(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::String(AZStd::string_view value, Lifetime lifetime) + { + if (lifetime == Lifetime::Persistent) + { + CurrentValue().SetString(value); + } + else + { + CurrentValue().CopyFromString(value); + } + return FinishWrite(); + } + + Visitor::Result ValueWriter::StartObject() + { + CurrentValue().SetObject(); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount) + { + const char* endMethodName; + switch (containerType) + { + case Type::ObjectType: + endMethodName = "EndObject"; + break; + case Type::ArrayType: + endMethodName = "EndArray"; + break; + case Type::NodeType: + endMethodName = "EndNode"; + break; + default: + AZ_Assert(false, "Invalid container type specified"); + return VisitorFailure(VisitorErrorCode::InternalError, "AZ::Dom::ValueWriter: EndContainer called with invalid container type"); + } + + if (m_entryStack.empty()) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format("AZ::Dom::ValueWriter: %s called without a matching call", endMethodName)); + } + + const ValueInfo& topEntry = m_entryStack.top(); + if (topEntry.m_container.GetType() != containerType) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); + } + + if (topEntry.m_attributeCount != attributeCount) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format( + "AZ::Dom::ValueWriter: %s expected %llu attributes but received %llu attributes instead", endMethodName, attributeCount, + topEntry.m_attributeCount)); + } + + if (topEntry.m_elementCount != elementCount) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format( + "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, + topEntry.m_elementCount)); + } + + m_entryStack.pop(); + return FinishWrite(); + } + + Visitor::Result ValueWriter::EndObject(AZ::u64 attributeCount) + { + return EndContainer(Type::ObjectType, attributeCount, 0); + } + + Visitor::Result ValueWriter::Key(AZ::Name key) + { + AZ_Assert(!m_entryStack.empty(), "Attempmted to push a key with no object"); + AZ_Assert(!m_entryStack.top().m_container.IsArray(), "Attempted to push a key to an array"); + m_entryStack.top().m_key = key; + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::RawKey(AZStd::string_view key, [[maybe_unused]] Lifetime lifetime) + { + return Key(AZ::Name(key)); + } + + Visitor::Result ValueWriter::StartArray() + { + CurrentValue().SetArray(); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::EndArray(AZ::u64 elementCount) + { + return EndContainer(Type::ArrayType, 0, elementCount); + } + + Visitor::Result ValueWriter::StartNode(AZ::Name name) + { + CurrentValue().SetNode(name); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) + { + return EndContainer(Type::NodeType, attributeCount, elementCount); + } + + Visitor::Result ValueWriter::FinishWrite() + { + if (m_entryStack.empty()) + { + return VisitorSuccess(); + } + + Value value; + m_entryStack.top().m_value.Swap(value); + ValueInfo& newEntry = m_entryStack.top(); + + if (!newEntry.m_key.IsEmpty()) + { + newEntry.m_container.AddMember(newEntry.m_key, AZStd::move(value)); + newEntry.m_key = AZ::Name(); + ++newEntry.m_attributeCount; + } + else + { + newEntry.m_container.PushBack(AZStd::move(value)); + ++newEntry.m_elementCount; + } + + return VisitorSuccess(); + } + + Value& ValueWriter::CurrentValue() + { + if (m_entryStack.empty()) + { + return m_result; + } + return m_entryStack.top().m_value; + } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index f73dbb2549..439971a5a0 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace AZ::Dom @@ -249,6 +250,9 @@ namespace AZ::Dom // null API... void SetNull(); + // Visitor API + Visitor::Result Accept(Visitor& visitor, bool copyStrings) const; + private: const Object::ContainerType& GetObjectInternal() const; Object::ContainerType& GetObjectInternal(); @@ -286,4 +290,47 @@ namespace AZ::Dom ValueType m_value; }; -} // namespace AZ::Dom + + class ValueWriter : public Visitor + { + public: + ValueWriter(Value& outputValue); + + VisitorFlags GetVisitorFlags() const override; + Result Null() override; + Result Bool(bool value) override; + Result Int64(AZ::s64 value) override; + Result Uint64(AZ::u64 value) override; + Result Double(double value) override; + + Result String(AZStd::string_view value, Lifetime lifetime) override; + Result StartObject() override; + Result EndObject(AZ::u64 attributeCount) override; + Result Key(AZ::Name key) override; + Result RawKey(AZStd::string_view key, Lifetime lifetime) override; + Result StartArray() override; + Result EndArray(AZ::u64 elementCount) override; + Result StartNode(AZ::Name name) override; + Result RawStartNode(AZStd::string_view name, Lifetime lifetime) override; + Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) override; + + private: + Result FinishWrite(); + Value& CurrentValue(); + Visitor::Result EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount); + + struct ValueInfo + { + ValueInfo(Value& container); + + KeyType m_key; + Value m_value; + Value& m_container; + AZ::u64 m_attributeCount = 0; + AZ::u64 m_elementCount = 0; + }; + + Value& m_result; + AZStd::stack m_entryStack; + }; + } // namespace AZ::Dom From e7c92b5658a0829885a729039356fbad1bf939bb Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 9 Dec 2021 15:25:20 -0800 Subject: [PATCH 004/272] Move ValueWriter out, add DeepCompareIsEqual Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 405 +++++++++--------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 81 ++-- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 218 ++++++++++ .../AzCore/AzCore/DOM/DomValueWriter.h | 58 +++ .../AzCore/AzCore/azcore_files.cmake | 2 + 5 files changed, 504 insertions(+), 260 deletions(-) create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp create mode 100644 Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 032e5795da..68a88ed35a 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -9,7 +9,7 @@ #pragma once #include - +#include #include namespace AZ::Dom @@ -26,6 +26,11 @@ namespace AZ::Dom return refCountedPointer; } + Node::Node(AZ::Name name) + : m_name(name) + { + } + AZ::Name Node::GetName() const { return m_name; @@ -36,31 +41,24 @@ namespace AZ::Dom m_name = name; } - ObjectPtr Node::GetMutableProperties() + Object::ContainerType& Node::GetProperties() { - CheckCopyOnWrite(m_object); - return m_object; + return m_properties; } - ConstObjectPtr Node::GetProperties() const + const Object::ContainerType& Node::GetProperties() const { - return m_object; + return m_properties; } - ArrayPtr Node::GetMutableChildren() + Array::ContainerType& Node::GetChildren() { - CheckCopyOnWrite(m_array); - return m_array; + return m_children; } - ConstArrayPtr Node::GetChildren() const + const Array::ContainerType& Node::GetChildren() const { - return m_array; - } - - bool Node::operator==(const Node& rhs) const - { - return m_name == rhs.m_name && m_array == rhs.m_array && m_object == rhs.m_object; + return m_children; } Value::Value() @@ -187,7 +185,7 @@ namespace AZ::Dom return Type::ObjectType; case 8: // ArrayPtr return Type::ArrayType; - case 9: // Node + case 9: // NodePtr return Type::NodeType; case 10: // AZStd::any* return Type::OpaqueType; @@ -267,18 +265,31 @@ namespace AZ::Dom return *this; } + const Node& Value::GetNodeInternal() const + { + AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); + return *AZStd::get(m_value); + } + + Node& Value::GetNodeInternal() + { + AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); + return *CheckCopyOnWrite(AZStd::get(m_value)); + } + const Object::ContainerType& Value::GetObjectInternal() const { const Type type = GetType(); AZ_Assert( - type == Type::ObjectType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an object from a non-object value"); + type == Type::ObjectType || type == Type::NodeType, + "AZ::Dom::Value: attempted to retrieve an object from a value that isn't an object or a node"); if (type == Type::ObjectType) { return AZStd::get(m_value)->m_values; } else { - return AZStd::get(m_value).GetProperties()->m_values; + return AZStd::get(m_value)->GetProperties(); } } @@ -286,14 +297,15 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ObjectType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an object from a non-object value"); + type == Type::ObjectType || type == Type::NodeType, + "AZ::Dom::Value: attempted to retrieve an object from a value that isn't an object or a node"); if (type == Type::ObjectType) { return CheckCopyOnWrite(AZStd::get(m_value))->m_values; } else { - return AZStd::get(m_value).GetMutableProperties()->m_values; + return CheckCopyOnWrite(AZStd::get(m_value))->GetProperties(); } } @@ -301,14 +313,15 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a non-array value"); + type == Type::ArrayType || type == Type::NodeType, + "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or a node"); if (type == Type::ObjectType) { return AZStd::get(m_value)->m_values; } else { - return AZStd::get(m_value).GetChildren()->m_values; + return AZStd::get(m_value)->GetChildren(); } } @@ -316,14 +329,15 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a non-array value"); + type == Type::ArrayType || type == Type::NodeType, + "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or node"); if (type == Type::ObjectType) { return CheckCopyOnWrite(AZStd::get(m_value))->m_values; } else { - return AZStd::get(m_value).GetMutableChildren()->m_values; + return CheckCopyOnWrite(AZStd::get(m_value))->GetChildren(); } } @@ -627,6 +641,67 @@ namespace AZ::Dom return GetArrayInternal(); } + void Value::SetNode(AZ::Name name) + { + m_value = AZStd::make_shared(name); + } + + void Value::SetNode(AZStd::string_view name) + { + SetNode(AZ::Name(name)); + } + + AZ::Name Value::GetNodeName() const + { + return GetNodeInternal().GetName(); + } + + void Value::SetNodeName(AZ::Name name) + { + GetNodeInternal().SetName(name); + } + + void Value::SetNodeName(AZStd::string_view name) + { + SetNodeName(AZ::Name(name)); + } + + void Value::SetNodeValue(Value value) + { + AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: Attempted to set value for non-node type"); + Array::ContainerType& nodeChildren = GetArrayInternal(); + + // Set the first non-node child, if one is found + for (Value& entry : nodeChildren) + { + if (entry.GetType() != Type::NodeType) + { + entry = AZStd::move(value); + return; + } + } + + // Otherwise, append the value entry + nodeChildren.push_back(AZStd::move(value)); + } + + Value Value::GetNodeValue() const + { + AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: Attempted to get value for non-node type"); + const Array::ContainerType& nodeChildren = GetArrayInternal(); + + // Get the first non-node child, if one is found + for (const Value& entry : nodeChildren) + { + if (entry.GetType() != Type::NodeType) + { + return entry; + } + } + + return Value(); + } + int64_t Value::GetInt() const { switch (m_value.index()) @@ -812,9 +887,9 @@ namespace AZ::Dom result = visitor.EndArray(arrayContainer.size()); } } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { - const Node& node = AZStd::get(m_value); + const Node& node = *AZStd::get(m_value); result = visitor.StartNode(node.GetName()); if (result.IsSuccess()) { @@ -850,204 +925,124 @@ namespace AZ::Dom return result; } - ValueWriter::ValueWriter(Value& outputValue) - : m_result(outputValue) + AZStd::unique_ptr Value::GetWriteHandler() { + return AZStd::make_unique(*this); } - VisitorFlags ValueWriter::GetVisitorFlags() const + bool Value::DeepCompareIsEqual(const Value& other) const { - return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects | VisitorFlags::SupportsNodes; - } - - ValueWriter::ValueInfo::ValueInfo(Value& container) - : m_container(container) - { - } - - Visitor::Result ValueWriter::Null() - { - CurrentValue().SetNull(); - return FinishWrite(); - } - - Visitor::Result ValueWriter::Bool(bool value) - { - CurrentValue().SetBool(value); - return FinishWrite(); - } - - Visitor::Result ValueWriter::Int64(AZ::s64 value) - { - CurrentValue().SetInt(value); - return FinishWrite(); - } - - Visitor::Result ValueWriter::Uint64(AZ::u64 value) - { - CurrentValue().SetUint(value); - return FinishWrite(); - } - - Visitor::Result ValueWriter::Double(double value) - { - CurrentValue().SetDouble(value); - return FinishWrite(); - } - - Visitor::Result ValueWriter::String(AZStd::string_view value, Lifetime lifetime) - { - if (lifetime == Lifetime::Persistent) + if (m_value.index() != other.m_value.index()) { - CurrentValue().SetString(value); - } - else - { - CurrentValue().CopyFromString(value); - } - return FinishWrite(); - } - - Visitor::Result ValueWriter::StartObject() - { - CurrentValue().SetObject(); - - m_entryStack.emplace(CurrentValue()); - return VisitorSuccess(); - } - - Visitor::Result ValueWriter::EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount) - { - const char* endMethodName; - switch (containerType) - { - case Type::ObjectType: - endMethodName = "EndObject"; - break; - case Type::ArrayType: - endMethodName = "EndArray"; - break; - case Type::NodeType: - endMethodName = "EndNode"; - break; - default: - AZ_Assert(false, "Invalid container type specified"); - return VisitorFailure(VisitorErrorCode::InternalError, "AZ::Dom::ValueWriter: EndContainer called with invalid container type"); + return false; } - if (m_entryStack.empty()) - { - return VisitorFailure( - VisitorErrorCode::InternalError, - AZStd::string::format("AZ::Dom::ValueWriter: %s called without a matching call", endMethodName)); - } + return AZStd::visit( + [&](auto&& ourValue) -> bool + { + using Alternative = AZStd::decay_t; + auto&& theirValue = AZStd::get>(other.m_value); - const ValueInfo& topEntry = m_entryStack.top(); - if (topEntry.m_container.GetType() != containerType) - { - return VisitorFailure( - VisitorErrorCode::InternalError, - AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); - } + if constexpr (AZStd::is_same_v) + { + return true; + } + else if constexpr (AZStd::is_same_v) + { + if (ourValue == theirValue) + { + return true; + } - if (topEntry.m_attributeCount != attributeCount) - { - return VisitorFailure( - VisitorErrorCode::InternalError, - AZStd::string::format( - "AZ::Dom::ValueWriter: %s expected %llu attributes but received %llu attributes instead", endMethodName, attributeCount, - topEntry.m_attributeCount)); - } + if (ourValue->m_values.size() != theirValue->m_values.size()) + { + return false; + } - if (topEntry.m_elementCount != elementCount) - { - return VisitorFailure( - VisitorErrorCode::InternalError, - AZStd::string::format( - "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, - topEntry.m_elementCount)); - } + for (size_t i = 0; i < ourValue->m_values.size(); ++i) + { + const Object::EntryType& lhs = ourValue->m_values[i]; + const Object::EntryType& rhs = theirValue->m_values[i]; + if (lhs.first != rhs.first || !lhs.second.DeepCompareIsEqual(rhs.second)) + { + return false; + } + } - m_entryStack.pop(); - return FinishWrite(); - } + return true; + } + else if constexpr (AZStd::is_same_v) + { + if (ourValue == theirValue) + { + return true; + } - Visitor::Result ValueWriter::EndObject(AZ::u64 attributeCount) - { - return EndContainer(Type::ObjectType, attributeCount, 0); - } + if (ourValue->m_values.size() != theirValue->m_values.size()) + { + return false; + } - Visitor::Result ValueWriter::Key(AZ::Name key) - { - AZ_Assert(!m_entryStack.empty(), "Attempmted to push a key with no object"); - AZ_Assert(!m_entryStack.top().m_container.IsArray(), "Attempted to push a key to an array"); - m_entryStack.top().m_key = key; - return VisitorSuccess(); - } + for (size_t i = 0; i < ourValue->m_values.size(); ++i) + { + const Value& lhs = ourValue->m_values[i]; + const Value& rhs = theirValue->m_values[i]; + if (!lhs.DeepCompareIsEqual(rhs)) + { + return false; + } + } - Visitor::Result ValueWriter::RawKey(AZStd::string_view key, [[maybe_unused]] Lifetime lifetime) - { - return Key(AZ::Name(key)); - } + return true; + } + else if constexpr (AZStd::is_same_v) + { + if (ourValue == theirValue) + { + return true; + } - Visitor::Result ValueWriter::StartArray() - { - CurrentValue().SetArray(); + const Node& ourNode = *ourValue; + const Node& theirNode = *theirValue; - m_entryStack.emplace(CurrentValue()); - return VisitorSuccess(); - } + const Object::ContainerType& ourProperties = ourNode.GetProperties(); + const Object::ContainerType& theirProperties = theirNode.GetProperties(); - Visitor::Result ValueWriter::EndArray(AZ::u64 elementCount) - { - return EndContainer(Type::ArrayType, 0, elementCount); - } + if (ourProperties.size() != theirProperties.size()) + { + return false; + } - Visitor::Result ValueWriter::StartNode(AZ::Name name) - { - CurrentValue().SetNode(name); + for (size_t i = 0; i < ourProperties.size(); ++i) + { + const Object::EntryType& lhs = ourProperties[i]; + const Object::EntryType& rhs = theirProperties[i]; + if (lhs.first != rhs.first || !lhs.second.DeepCompareIsEqual(rhs.second)) + { + return false; + } + } - m_entryStack.emplace(CurrentValue()); - return VisitorSuccess(); - } + const Array::ContainerType& ourChildren = ourNode.GetChildren(); + const Array::ContainerType& theirChildren = theirNode.GetChildren(); - Visitor::Result ValueWriter::EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) - { - return EndContainer(Type::NodeType, attributeCount, elementCount); - } + for (size_t i = 0; i < ourChildren.size(); ++i) + { + const Value& lhs = ourChildren[i]; + const Value& rhs = theirChildren[i]; + if (!lhs.DeepCompareIsEqual(rhs)) + { + return false; + } + } - Visitor::Result ValueWriter::FinishWrite() - { - if (m_entryStack.empty()) - { - return VisitorSuccess(); - } - - Value value; - m_entryStack.top().m_value.Swap(value); - ValueInfo& newEntry = m_entryStack.top(); - - if (!newEntry.m_key.IsEmpty()) - { - newEntry.m_container.AddMember(newEntry.m_key, AZStd::move(value)); - newEntry.m_key = AZ::Name(); - ++newEntry.m_attributeCount; - } - else - { - newEntry.m_container.PushBack(AZStd::move(value)); - ++newEntry.m_elementCount; - } - - return VisitorSuccess(); - } - - Value& ValueWriter::CurrentValue() - { - if (m_entryStack.empty()) - { - return m_result; - } - return m_entryStack.top().m_value; + return true; + } + else + { + return ourValue == theirValue; + } + }, + m_value); } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 439971a5a0..a460274602 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -8,13 +8,13 @@ #pragma once +#include #include - #include +#include #include #include #include -#include #include namespace AZ::Dom @@ -72,25 +72,34 @@ namespace AZ::Dom class Node { public: + Node() = default; + Node(AZ::Name name); + Node(const Node&) = default; + Node(Node&&) = default; + + Node& operator=(const Node&) = default; + Node& operator=(Node&&) = default; + AZ::Name GetName() const; void SetName(AZ::Name name); - ObjectPtr GetMutableProperties(); - ConstObjectPtr GetProperties() const; + Object::ContainerType& GetProperties(); + const Object::ContainerType& GetProperties() const; - ArrayPtr GetMutableChildren(); - ConstArrayPtr GetChildren() const; - - bool operator==(const Node& rhs) const; + Array::ContainerType& GetChildren(); + const Array::ContainerType& GetChildren() const; private: AZ::Name m_name; - ArrayPtr m_array; - ObjectPtr m_object; + Object::ContainerType m_properties; + Array::ContainerType m_children; friend class Value; }; + using NodePtr = AZStd::shared_ptr; + using ConstNodePtr = AZStd::shared_ptr; + class Value { public: @@ -252,8 +261,13 @@ namespace AZ::Dom // Visitor API Visitor::Result Accept(Visitor& visitor, bool copyStrings) const; + AZStd::unique_ptr GetWriteHandler(); + + bool DeepCompareIsEqual(const Value& other) const; private: + const Node& GetNodeInternal() const; + Node& GetNodeInternal(); const Object::ContainerType& GetObjectInternal() const; Object::ContainerType& GetObjectInternal(); const Array::ContainerType& GetArrayInternal() const; @@ -284,53 +298,10 @@ namespace AZ::Dom // ArrayType ArrayPtr, // NodeType - Node, + NodePtr, // OpaqueType AZStd::any*>; ValueType m_value; }; - - class ValueWriter : public Visitor - { - public: - ValueWriter(Value& outputValue); - - VisitorFlags GetVisitorFlags() const override; - Result Null() override; - Result Bool(bool value) override; - Result Int64(AZ::s64 value) override; - Result Uint64(AZ::u64 value) override; - Result Double(double value) override; - - Result String(AZStd::string_view value, Lifetime lifetime) override; - Result StartObject() override; - Result EndObject(AZ::u64 attributeCount) override; - Result Key(AZ::Name key) override; - Result RawKey(AZStd::string_view key, Lifetime lifetime) override; - Result StartArray() override; - Result EndArray(AZ::u64 elementCount) override; - Result StartNode(AZ::Name name) override; - Result RawStartNode(AZStd::string_view name, Lifetime lifetime) override; - Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) override; - - private: - Result FinishWrite(); - Value& CurrentValue(); - Visitor::Result EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount); - - struct ValueInfo - { - ValueInfo(Value& container); - - KeyType m_key; - Value m_value; - Value& m_container; - AZ::u64 m_attributeCount = 0; - AZ::u64 m_elementCount = 0; - }; - - Value& m_result; - AZStd::stack m_entryStack; - }; - } // namespace AZ::Dom +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp new file mode 100644 index 0000000000..71710f543b --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ::Dom +{ + ValueWriter::ValueWriter(Value& outputValue) + : m_result(outputValue) + { + } + + VisitorFlags ValueWriter::GetVisitorFlags() const + { + return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects | VisitorFlags::SupportsNodes; + } + + ValueWriter::ValueInfo::ValueInfo(Value& container) + : m_container(container) + { + } + + Visitor::Result ValueWriter::Null() + { + CurrentValue().SetNull(); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Bool(bool value) + { + CurrentValue().SetBool(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Int64(AZ::s64 value) + { + CurrentValue().SetInt(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Uint64(AZ::u64 value) + { + CurrentValue().SetUint(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::Double(double value) + { + CurrentValue().SetDouble(value); + return FinishWrite(); + } + + Visitor::Result ValueWriter::String(AZStd::string_view value, Lifetime lifetime) + { + if (lifetime == Lifetime::Persistent) + { + CurrentValue().SetString(value); + } + else + { + CurrentValue().CopyFromString(value); + } + return FinishWrite(); + } + + Visitor::Result ValueWriter::StartObject() + { + CurrentValue().SetObject(); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount) + { + const char* endMethodName; + switch (containerType) + { + case Type::ObjectType: + endMethodName = "EndObject"; + break; + case Type::ArrayType: + endMethodName = "EndArray"; + break; + case Type::NodeType: + endMethodName = "EndNode"; + break; + default: + AZ_Assert(false, "Invalid container type specified"); + return VisitorFailure(VisitorErrorCode::InternalError, "AZ::Dom::ValueWriter: EndContainer called with invalid container type"); + } + + if (m_entryStack.empty()) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format("AZ::Dom::ValueWriter: %s called without a matching call", endMethodName)); + } + + const ValueInfo& topEntry = m_entryStack.top(); + if (topEntry.m_container.GetType() != containerType) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); + } + + if (topEntry.m_attributeCount != attributeCount) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format( + "AZ::Dom::ValueWriter: %s expected %llu attributes but received %llu attributes instead", endMethodName, attributeCount, + topEntry.m_attributeCount)); + } + + if (topEntry.m_elementCount != elementCount) + { + return VisitorFailure( + VisitorErrorCode::InternalError, + AZStd::string::format( + "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, + topEntry.m_elementCount)); + } + + m_entryStack.pop(); + return FinishWrite(); + } + + Visitor::Result ValueWriter::EndObject(AZ::u64 attributeCount) + { + return EndContainer(Type::ObjectType, attributeCount, 0); + } + + Visitor::Result ValueWriter::Key(AZ::Name key) + { + AZ_Assert(!m_entryStack.empty(), "Attempmted to push a key with no object"); + AZ_Assert(!m_entryStack.top().m_container.IsArray(), "Attempted to push a key to an array"); + m_entryStack.top().m_key = key; + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::RawKey(AZStd::string_view key, [[maybe_unused]] Lifetime lifetime) + { + return Key(AZ::Name(key)); + } + + Visitor::Result ValueWriter::StartArray() + { + CurrentValue().SetArray(); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::EndArray(AZ::u64 elementCount) + { + return EndContainer(Type::ArrayType, 0, elementCount); + } + + Visitor::Result ValueWriter::StartNode(AZ::Name name) + { + CurrentValue().SetNode(name); + + m_entryStack.emplace(CurrentValue()); + return VisitorSuccess(); + } + + Visitor::Result ValueWriter::RawStartNode(AZStd::string_view name, [[maybe_unused]] Lifetime lifetime) + { + return StartNode(AZ::Name(name)); + } + + Visitor::Result ValueWriter::EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) + { + return EndContainer(Type::NodeType, attributeCount, elementCount); + } + + Visitor::Result ValueWriter::FinishWrite() + { + if (m_entryStack.empty()) + { + return VisitorSuccess(); + } + + Value value; + m_entryStack.top().m_value.Swap(value); + ValueInfo& newEntry = m_entryStack.top(); + + if (!newEntry.m_key.IsEmpty()) + { + newEntry.m_container.AddMember(newEntry.m_key, AZStd::move(value)); + newEntry.m_key = AZ::Name(); + ++newEntry.m_attributeCount; + } + else + { + newEntry.m_container.PushBack(AZStd::move(value)); + ++newEntry.m_elementCount; + } + + return VisitorSuccess(); + } + + Value& ValueWriter::CurrentValue() + { + if (m_entryStack.empty()) + { + return m_result; + } + return m_entryStack.top().m_value; + } +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h new file mode 100644 index 0000000000..fb5f4324a6 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +namespace AZ::Dom +{ + class ValueWriter : public Visitor + { + public: + ValueWriter(Value& outputValue); + + VisitorFlags GetVisitorFlags() const override; + Result Null() override; + Result Bool(bool value) override; + Result Int64(AZ::s64 value) override; + Result Uint64(AZ::u64 value) override; + Result Double(double value) override; + + Result String(AZStd::string_view value, Lifetime lifetime) override; + Result StartObject() override; + Result EndObject(AZ::u64 attributeCount) override; + Result Key(AZ::Name key) override; + Result RawKey(AZStd::string_view key, Lifetime lifetime) override; + Result StartArray() override; + Result EndArray(AZ::u64 elementCount) override; + Result StartNode(AZ::Name name) override; + Result RawStartNode(AZStd::string_view name, Lifetime lifetime) override; + Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) override; + + private: + Result FinishWrite(); + Value& CurrentValue(); + Visitor::Result EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount); + + struct ValueInfo + { + ValueInfo(Value& container); + + KeyType m_key; + Value m_value; + Value& m_container; + AZ::u64 m_attributeCount = 0; + AZ::u64 m_elementCount = 0; + }; + + Value& m_result; + AZStd::stack m_entryStack; + }; +} // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index fa9f94505f..e17fb941b8 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -133,6 +133,8 @@ set(FILES DOM/DomUtils.h DOM/DomValue.cpp DOM/DomValue.h + DOM/DomValueWriter.cpp + DOM/DomValueWriter.h DOM/DomVisitor.cpp DOM/DomVisitor.h DOM/Backends/JSON/JsonBackend.h From a2d474cc4f30c17b7354221a1c0e55dfb20c6de4 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 9 Dec 2021 17:47:01 -0800 Subject: [PATCH 005/272] Add some intial tests Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 123 +++++++++- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 28 ++- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 4 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 0 .../AzCore/Tests/DOM/DomValueTests.cpp | 211 ++++++++++++++++++ .../AzCore/Tests/azcoretests_files.cmake | 2 + 6 files changed, 350 insertions(+), 18 deletions(-) create mode 100644 Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp create mode 100644 Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 68a88ed35a..2f41835a37 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -97,6 +97,16 @@ namespace AZ::Dom return Value(&value); } + Value::Value(int32_t value) + : m_value(aznumeric_cast(value)) + { + } + + Value::Value(uint32_t value) + : m_value(aznumeric_cast(value)) + { + } + Value::Value(int64_t value) : m_value(value) { @@ -107,6 +117,11 @@ namespace AZ::Dom { } + Value::Value(float value) + : m_value(aznumeric_cast(value)) + { + } + Value::Value(double value) : m_value(value) { @@ -117,6 +132,40 @@ namespace AZ::Dom { } + Value::Value(Type type) + { + switch (type) + { + case Type::NullType: + // Null is the default initialized value + break; + case Type::FalseType: + m_value = false; + break; + case Type::TrueType: + m_value = true; + break; + case Type::ObjectType: + SetObject(); + break; + case Type::ArrayType: + SetArray(); + break; + case Type::StringType: + SetString(""); + break; + case Type::NumberType: + m_value = 0.0; + break; + case Type::NodeType: + SetNode(""); + break; + case Type::OpaqueType: + AZ_Assert(false, "AZ::Dom::Value may not be constructed with an empty opaque type"); + break; + } + } + Value& Value::operator=(const Value& other) { m_value = other.m_value; @@ -139,11 +188,11 @@ namespace AZ::Dom { if (IsInt()) { - return GetInt() == rhs.GetInt(); + return GetInt64() == rhs.GetInt64(); } else if (IsUint()) { - return GetUint() == rhs.GetUint(); + return GetUint64() == rhs.GetUint64(); } else { @@ -315,7 +364,7 @@ namespace AZ::Dom AZ_Assert( type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or a node"); - if (type == Type::ObjectType) + if (type == Type::ArrayType) { return AZStd::get(m_value)->m_values; } @@ -331,7 +380,7 @@ namespace AZ::Dom AZ_Assert( type == Type::ArrayType || type == Type::NodeType, "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or node"); - if (type == Type::ObjectType) + if (type == Type::ArrayType) { return CheckCopyOnWrite(AZStd::get(m_value))->m_values; } @@ -702,7 +751,7 @@ namespace AZ::Dom return Value(); } - int64_t Value::GetInt() const + int64_t Value::GetInt64() const { switch (m_value.index()) { @@ -717,12 +766,22 @@ namespace AZ::Dom return {}; } - void Value::SetInt(int64_t value) + void Value::SetInt64(int64_t value) { m_value = value; } - uint64_t Value::GetUint() const + int32_t Value::GetInt32() const + { + return aznumeric_cast(GetInt64()); + } + + void Value::SetInt32(int32_t value) + { + m_value = aznumeric_cast(value); + } + + uint64_t Value::GetUint64() const { switch (m_value.index()) { @@ -737,11 +796,21 @@ namespace AZ::Dom return {}; } - void Value::SetUint(uint64_t value) + void Value::SetUint64(uint64_t value) { m_value = value; } + uint32_t Value::GetUint32() const + { + return aznumeric_cast(GetUint64()); + } + + void Value::SetUint32(uint32_t value) + { + m_value = aznumeric_cast(value); + } + bool Value::GetBool() const { if (IsBool()) @@ -777,6 +846,16 @@ namespace AZ::Dom m_value = value; } + float Value::GetFloat() const + { + return aznumeric_cast(GetDouble()); + } + + void Value::SetFloat(float value) + { + m_value = aznumeric_cast(value); + } + AZStd::string_view Value::GetString() const { switch (m_value.index()) @@ -861,6 +940,11 @@ namespace AZ::Dom const Object::ContainerType& object = GetObjectInternal(); for (const Object::EntryType& entry : object) { + result = visitor.Key(entry.first); + if (!result.IsSuccess()) + { + return; + } result = entry.second.Accept(visitor, copyStrings); if (!result.IsSuccess()) { @@ -896,6 +980,11 @@ namespace AZ::Dom const Object::ContainerType& object = GetObjectInternal(); for (const Object::EntryType& entry : object) { + result = visitor.Key(entry.first); + if (!result.IsSuccess()) + { + return; + } result = entry.second.Accept(visitor, copyStrings); if (!result.IsSuccess()) { @@ -932,6 +1021,16 @@ namespace AZ::Dom bool Value::DeepCompareIsEqual(const Value& other) const { + if (IsString() && other.IsString()) + { + // If we both hold the same ref counted string we don't need to do a full comparison + if (AZStd::holds_alternative>(m_value) && m_value == other.m_value) + { + return true; + } + return GetString() == other.GetString(); + } + if (m_value.index() != other.m_value.index()) { return false; @@ -1045,4 +1144,12 @@ namespace AZ::Dom }, m_value); } + + Value Value::DeepCopy(bool copyStrings) const + { + Value newValue; + AZStd::unique_ptr writer = newValue.GetWriteHandler(); + Accept(*writer, copyStrings); + return newValue; + } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index a460274602..61c3207ea4 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -109,10 +109,15 @@ namespace AZ::Dom Value(Value&&) noexcept; Value(AZStd::string_view string, bool copy); - explicit Value(int64_t value); - explicit Value(uint64_t value); - explicit Value(double value); - explicit Value(bool value); + Value(int32_t value); + Value(uint32_t value); + Value(int64_t value); + Value(uint64_t value); + Value(float value); + Value(double value); + Value(bool value); + + explicit Value(Type type); static Value FromOpaqueValue(AZStd::any& value); @@ -226,12 +231,16 @@ namespace AZ::Dom Value GetNodeValue() const; // int API... - int64_t GetInt() const; - void SetInt(int64_t); + int64_t GetInt64() const; + void SetInt64(int64_t); + int32_t GetInt32() const; + void SetInt32(int32_t); // uint API... - uint64_t GetUint() const; - void SetUint(uint64_t); + uint64_t GetUint64() const; + void SetUint64(uint64_t); + uint32_t GetUint32() const; + void SetUint32(uint32_t); // bool API... bool GetBool() const; @@ -240,6 +249,8 @@ namespace AZ::Dom // double API... double GetDouble() const; void SetDouble(double); + float GetFloat() const; + void SetFloat(float); // string API... AZStd::string_view GetString() const; @@ -264,6 +275,7 @@ namespace AZ::Dom AZStd::unique_ptr GetWriteHandler(); bool DeepCompareIsEqual(const Value& other) const; + Value DeepCopy(bool copyStrings = true) const; private: const Node& GetNodeInternal() const; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 71710f543b..a760cc5b28 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -39,13 +39,13 @@ namespace AZ::Dom Visitor::Result ValueWriter::Int64(AZ::s64 value) { - CurrentValue().SetInt(value); + CurrentValue().SetInt64(value); return FinishWrite(); } Visitor::Result ValueWriter::Uint64(AZ::u64 value) { - CurrentValue().SetUint(value); + CurrentValue().SetUint64(value); return FinishWrite(); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp new file mode 100644 index 0000000000..02777bf6dd --- /dev/null +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AZ::Dom::Tests +{ + class DomValueTests : public UnitTest::AllocatorsFixture + { + public: + void SetUp() override + { + UnitTest::AllocatorsFixture::SetUp(); + NameDictionary::Create(); + } + + void TearDown() override + { + m_value = Value(); + + NameDictionary::Destroy(); + UnitTest::AllocatorsFixture::TearDown(); + } + + void PerformValueChecks() + { + Value shallowCopy = m_value; + EXPECT_EQ(m_value, shallowCopy); + EXPECT_TRUE(m_value.DeepCompareIsEqual(shallowCopy)); + + Value deepCopy = m_value.DeepCopy(); + EXPECT_TRUE(m_value.DeepCompareIsEqual(deepCopy)); + } + + Value m_value; + }; + + TEST_F(DomValueTests, EmptyArray) + { + m_value.SetArray(); + + EXPECT_TRUE(m_value.IsArray()); + EXPECT_EQ(m_value.Size(), 0); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, SimpleArray) + { + m_value.SetArray(); + + for (int i = 0; i < 5; ++i) + { + m_value.PushBack(Value(i)); + EXPECT_EQ(m_value.Size(), i + 1); + EXPECT_EQ(m_value[i].GetInt32(), i); + } + + PerformValueChecks(); + } + + TEST_F(DomValueTests, NestedArrays) + { + m_value.SetArray(); + for (int j = 0; j < 5; ++j) + { + Value nestedArray(Type::ArrayType); + for (int i = 0; i < 5; ++i) + { + nestedArray.PushBack(Value(i)); + } + m_value.PushBack(AZStd::move(nestedArray)); + } + + EXPECT_EQ(m_value.Size(), 5); + for (int i = 0; i < 3; ++i) + { + EXPECT_EQ(m_value[i].Size(), 5); + for (int j = 0; j < 5; ++j) + { + EXPECT_EQ(m_value[i][j].GetInt32(), j); + } + } + + PerformValueChecks(); + } + + TEST_F(DomValueTests, EmptyObject) + { + m_value.SetObject(); + EXPECT_EQ(m_value.MemberCount(), 0); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, SimpleObject) + { + m_value.SetObject(); + for (int i = 0; i < 5; ++i) + { + AZStd::string key = AZStd::string::format("Key%i", i); + m_value.AddMember(key, Value(i)); + EXPECT_EQ(m_value.MemberCount(), i + 1); + EXPECT_EQ(m_value[key].GetInt32(), i); + } + + PerformValueChecks(); + } + + TEST_F(DomValueTests, NestedObjects) + { + m_value.SetObject(); + for (int j = 0; j < 3; ++j) + { + Value nestedObject(Type::ObjectType); + for (int i = 0; i < 5; ++i) + { + nestedObject.AddMember(AZStd::string::format("Key%i", i), Value(i)); + } + m_value.AddMember(AZStd::string::format("Obj%i", j), AZStd::move(nestedObject)); + } + + EXPECT_EQ(m_value.MemberCount(), 3); + for (int j = 0; j < 3; ++j) + { + const Value& nestedObject = m_value[AZStd::string::format("Obj%i", j)]; + EXPECT_EQ(nestedObject.MemberCount(), 5); + for (int i = 0; i < 5; ++i) + { + EXPECT_EQ(nestedObject[AZStd::string::format("Key%i", i)].GetInt32(), i); + } + } + + PerformValueChecks(); + } + + TEST_F(DomValueTests, EmptyNode) + { + m_value.SetNode("Test"); + EXPECT_EQ(m_value.GetNodeName(), AZ::Name("Test")); + EXPECT_EQ(m_value.MemberCount(), 0); + EXPECT_EQ(m_value.Size(), 0); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, SimpleNode) + { + m_value.SetNode("Test"); + + for (int i = 0; i < 10; ++i) + { + m_value.PushBack(Value(i)); + EXPECT_EQ(m_value.Size(), i + 1); + EXPECT_EQ(m_value[i].GetInt32(), i); + + if (i < 5) + { + AZ::Name key = AZ::Name(AZStd::string::format("TwoTimes%i", i)); + m_value.AddMember(key, Value(i * 2)); + EXPECT_EQ(m_value.MemberCount(), i + 1); + EXPECT_EQ(m_value[key].GetInt32(), i * 2); + } + } + + PerformValueChecks(); + } + + TEST_F(DomValueTests, NestedNodes) + { + m_value.SetNode("TopLevel"); + + const AZ::Name childNodeName("ChildNode"); + + for (int i = 0; i < 5; ++i) + { + Value childNode(Type::NodeType); + childNode.SetNodeName(childNodeName); + childNode.SetNodeValue(i); + + childNode.AddMember("foo", i); + childNode.AddMember("bar", Value("test", false)); + + m_value.PushBack(childNode); + } + + EXPECT_EQ(m_value.Size(), 5); + for (int i = 0; i < 5; ++i) + { + const Value& childNode = m_value[i]; + EXPECT_EQ(childNode.GetNodeName(), childNodeName); + EXPECT_EQ(childNode.GetNodeValue().GetInt32(), i); + EXPECT_EQ(childNode["foo"].GetInt32(), i); + EXPECT_EQ(childNode["bar"].GetString(), "test"); + } + + PerformValueChecks(); + } +} // namespace AZ::Dom::Tests diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 0fca75e2a8..14a8bbbac0 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -215,6 +215,8 @@ set(FILES AZStd/VectorAndArray.cpp DOM/DomJsonTests.cpp DOM/DomJsonBenchmarks.cpp + DOM/DomValueTests.cpp + DOM/DomValueBenchmarks.cpp ) # Prevent the following files from being grouped in UNITY builds From 15e0bb16939b38b578cd075e297794a72fee4eac Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 9 Dec 2021 21:37:22 -0800 Subject: [PATCH 006/272] Add tests, fix missing bool in Accept and operator[] insert Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 21 ++++- .../AzCore/Tests/DOM/DomValueTests.cpp | 87 +++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 2f41835a37..675a6931f5 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -407,7 +407,22 @@ namespace AZ::Dom Value& Value::operator[](KeyType name) { - return FindMember(name)->second; + Object::ContainerType& object = GetObjectInternal(); + auto existingEntry = AZStd::find_if( + object.begin(), object.end(), + [&name](const Object::EntryType& entry) + { + return entry.first == name; + }); + if (existingEntry != object.end()) + { + return existingEntry->second; + } + else + { + object.emplace_back(name, Value()); + return object[object.size() - 1].second; + } } const Value& Value::operator[](KeyType name) const @@ -924,6 +939,10 @@ namespace AZ::Dom { result = visitor.Double(arg); } + else if constexpr (AZStd::is_same_v) + { + result = visitor.Bool(arg); + } else if constexpr (AZStd::is_same_v) { result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 02777bf6dd..75cb71248f 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace AZ::Dom::Tests { @@ -208,4 +209,90 @@ namespace AZ::Dom::Tests PerformValueChecks(); } + + TEST_F(DomValueTests, Int64) + { + m_value.SetObject(); + m_value["int64_min"] = AZStd::numeric_limits::min(); + m_value["int64_max"] = AZStd::numeric_limits::max(); + + EXPECT_EQ(m_value["int64_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["int64_min"].GetInt64(), AZStd::numeric_limits::min()); + EXPECT_EQ(m_value["int64_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["int64_max"].GetInt64(), AZStd::numeric_limits::max()); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, Uint64) + { + m_value.SetObject(); + m_value["uint64_min"] = AZStd::numeric_limits::min(); + m_value["uint64_max"] = AZStd::numeric_limits::max(); + + EXPECT_EQ(m_value["uint64_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["uint64_min"].GetInt64(), AZStd::numeric_limits::min()); + EXPECT_EQ(m_value["uint64_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["uint64_max"].GetInt64(), AZStd::numeric_limits::max()); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, Double) + { + m_value.SetObject(); + m_value["double_min"] = AZStd::numeric_limits::min(); + m_value["double_max"] = AZStd::numeric_limits::max(); + + EXPECT_EQ(m_value["double_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["double_min"].GetDouble(), AZStd::numeric_limits::min()); + EXPECT_EQ(m_value["double_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["double_max"].GetDouble(), AZStd::numeric_limits::max()); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, Null) + { + m_value.SetObject(); + m_value["null_value"] = Value(Type::NullType); + + EXPECT_EQ(m_value["null_value"].GetType(), Type::NullType); + EXPECT_EQ(m_value["null_type"], Value()); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, Bool) + { + m_value.SetObject(); + m_value["true_value"] = true; + m_value["false_value"] = false; + + EXPECT_EQ(m_value["true_value"].GetType(), Type::TrueType); + EXPECT_EQ(m_value["true_value"].GetBool(), true); + EXPECT_EQ(m_value["false_value"].GetType(), Type::FalseType); + EXPECT_EQ(m_value["false_value"].GetBool(), false); + + PerformValueChecks(); + } + + TEST_F(DomValueTests, String) + { + m_value.SetObject(); + AZStd::string stringToReference = "foo"; + m_value["no_copy"] = Value(stringToReference, false); + AZStd::string stringToCopy = "bar"; + m_value["copy"] = Value(stringToCopy, true); + + EXPECT_EQ(m_value["no_copy"].GetType(), Type::StringType); + EXPECT_EQ(m_value["no_copy"].GetString(), stringToReference); + EXPECT_EQ(m_value["no_copy"].GetString().data(), stringToReference.data()); + + EXPECT_EQ(m_value["copy"].GetType(), Type::StringType); + EXPECT_EQ(m_value["copy"].GetString(), stringToCopy); + EXPECT_NE(m_value["copy"].GetString().data(), stringToCopy.data()); + + PerformValueChecks(); + } } // namespace AZ::Dom::Tests From 947951b6c7473ccd45647e5e5c3938b5122718e7 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 9 Dec 2021 23:43:22 -0800 Subject: [PATCH 007/272] Add copy on write tests Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 34 ++++++-- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 14 ++- .../AzCore/Tests/DOM/DomValueTests.cpp | 86 +++++++++++++++++++ 3 files changed, 123 insertions(+), 11 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 675a6931f5..d9398da116 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -476,7 +476,7 @@ namespace AZ::Dom return FindMember(AZ::Name(name)); } - Object::Iterator Value::FindMember(KeyType name) + Object::Iterator Value::FindMutableMember(KeyType name) { Object::ContainerType& object = GetObjectInternal(); return AZStd::find_if( @@ -487,9 +487,9 @@ namespace AZ::Dom }); } - Object::Iterator Value::FindMember(AZStd::string_view name) + Object::Iterator Value::FindMutableMember(AZStd::string_view name) { - return FindMember(AZ::Name(name)); + return FindMutableMember(AZ::Name(name)); } Value& Value::MemberReserve(size_t newCapacity) @@ -511,7 +511,7 @@ namespace AZ::Dom Value& Value::AddMember(KeyType name, const Value& value) { Object::ContainerType& object = GetObjectInternal(); - if (auto memberIt = FindMember(name); memberIt != object.end()) + if (auto memberIt = FindMutableMember(name); memberIt != object.end()) { memberIt->second = value; } @@ -530,7 +530,7 @@ namespace AZ::Dom Value& Value::AddMember(AZ::Name name, Value&& value) { Object::ContainerType& object = GetObjectInternal(); - if (auto memberIt = FindMember(name); memberIt != object.end()) + if (auto memberIt = FindMutableMember(name); memberIt != object.end()) { memberIt->second = value; } @@ -601,7 +601,7 @@ namespace AZ::Dom return EraseMember(AZ::Name(name)); } - Object::ContainerType& Value::GetObject() + Object::ContainerType& Value::GetMutableObject() { return GetObjectInternal(); } @@ -647,6 +647,16 @@ namespace AZ::Dom return GetArrayInternal()[index]; } + Value& Value::MutableAt(size_t index) + { + return operator[](index); + } + + const Value& Value::At(size_t index) const + { + return operator[](index); + } + Array::ConstIterator Value::Begin() const { return GetArrayInternal().begin(); @@ -695,7 +705,7 @@ namespace AZ::Dom return GetArrayInternal().erase(first, last); } - Array::ContainerType& Value::GetArray() + Array::ContainerType& Value::GetMutableArray() { return GetArrayInternal(); } @@ -766,6 +776,16 @@ namespace AZ::Dom return Value(); } + Node& Value::GetMutableNode() + { + return GetNodeInternal(); + } + + const Node& Value::GetNode() const + { + return GetNodeInternal(); + } + int64_t Value::GetInt64() const { switch (m_value.index()) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 61c3207ea4..39ae5a5c37 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -162,10 +162,10 @@ namespace AZ::Dom Object::Iterator MemberBegin(); Object::Iterator MemberEnd(); + Object::Iterator FindMutableMember(KeyType name); + Object::Iterator FindMutableMember(AZStd::string_view name); Object::ConstIterator FindMember(KeyType name) const; Object::ConstIterator FindMember(AZStd::string_view name) const; - Object::Iterator FindMember(KeyType name); - Object::Iterator FindMember(AZStd::string_view name); Value& MemberReserve(size_t newCapacity); bool HasMember(KeyType name) const; @@ -185,7 +185,7 @@ namespace AZ::Dom Object::Iterator EraseMember(KeyType name); Object::Iterator EraseMember(AZStd::string_view name); - Object::ContainerType& GetObject(); + Object::ContainerType& GetMutableObject(); const Object::ContainerType& GetObject() const; // Array API (also used by Node)... @@ -199,6 +199,9 @@ namespace AZ::Dom Value& operator[](size_t index); const Value& operator[](size_t index) const; + Value& MutableAt(size_t index); + const Value& At(size_t index) const; + Array::ConstIterator Begin() const; Array::ConstIterator End() const; Array::Iterator Begin(); @@ -211,7 +214,7 @@ namespace AZ::Dom Array::Iterator Erase(Array::ConstIterator pos); Array::Iterator Erase(Array::ConstIterator first, Array::ConstIterator last); - Array::ContainerType& GetArray(); + Array::ContainerType& GetMutableArray(); const Array::ContainerType& GetArray() const; // Node API (supports both object + array API, plus a dedicated NodeName)... @@ -230,6 +233,9 @@ namespace AZ::Dom //! Convenience method, gets the first non-node element of a Node. Value GetNodeValue() const; + Node& GetMutableNode(); + const Node& GetNode() const; + // int API... int64_t GetInt64() const; void SetInt64(int64_t); diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 75cb71248f..84e2e16958 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -295,4 +295,90 @@ namespace AZ::Dom::Tests PerformValueChecks(); } + + TEST_F(DomValueTests, CopyOnWrite_Object) + { + Value v1(Type::ObjectType); + v1["foo"] = 5; + + Value nestedObject(Type::ObjectType); + v1["obj"] = nestedObject; + + Value v2 = v1; + EXPECT_EQ(&v1.GetObject(), &v2.GetObject()); + EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject()); + + v2["foo"] = 0; + + EXPECT_NE(&v1.GetObject(), &v2.GetObject()); + EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject()); + + v2["obj"]["key"] = true; + + EXPECT_NE(&v1.GetObject(), &v2.GetObject()); + EXPECT_NE(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject()); + + v2 = v1; + + EXPECT_EQ(&v1.GetObject(), &v2.GetObject()); + EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject()); + } + + TEST_F(DomValueTests, CopyOnWrite_Array) + { + Value v1(Type::ArrayType); + v1.PushBack(1); + v1.PushBack(2); + + Value nestedArray(Type::ArrayType); + v1.PushBack(nestedArray); + Value v2 = v1; + + EXPECT_EQ(&v1.GetArray(), &v2.GetArray()); + EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + + v2[0] = 0; + + EXPECT_NE(&v1.GetArray(), &v2.GetArray()); + EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + + v2[2].PushBack(42); + + EXPECT_NE(&v1.GetArray(), &v2.GetArray()); + EXPECT_NE(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + + v2 = v1; + + EXPECT_EQ(&v1.GetArray(), &v2.GetArray()); + EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + } + + TEST_F(DomValueTests, CopyOnWrite_Node) + { + Value v1; + v1.SetNode("TopLevel"); + + v1.PushBack(1); + v1.PushBack(2); + v1["obj"].SetNode("Nested"); + Value v2 = v1; + + EXPECT_EQ(&v1.GetNode(), &v2.GetNode()); + EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode()); + + v2[0] = 0; + + EXPECT_NE(&v1.GetNode(), &v2.GetNode()); + EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode()); + + v2["obj"].PushBack(42); + + EXPECT_NE(&v1.GetNode(), &v2.GetNode()); + EXPECT_NE(&v1["obj"].GetNode(), &v2["obj"].GetNode()); + + v2 = v1; + + EXPECT_EQ(&v1.GetNode(), &v2.GetNode()); + EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode()); + } } // namespace AZ::Dom::Tests From 1af39a5c5cc26028f04e00c8504b44cfa17a4462 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 10 Dec 2021 15:57:52 -0800 Subject: [PATCH 008/272] Add benchmarks, some light optimizations like SSO Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 12 ++ Code/Framework/AzCore/AzCore/DOM/DomUtils.h | 3 + Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 49 ++++++-- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 37 ++++++ .../AzCore/AzCore/DOM/DomValueWriter.cpp | 51 ++++++-- .../AzCore/AzCore/DOM/DomValueWriter.h | 11 +- .../AzCore/AzCore/Memory/PoolAllocator.h | 18 +-- .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 42 ++++++- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 117 ++++++++++++++++++ .../AzCore/Tests/DOM/DomValueTests.cpp | 19 ++- 10 files changed, 319 insertions(+), 40 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index 2e78661518..46fa5b9bac 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -21,4 +21,16 @@ namespace AZ::Dom::Utils { return backend.ReadFromBufferInPlace(string.data(), string.size(), visitor); } + + AZ::Outcome AZ::Dom::Utils::WriteToValue(Backend::WriteCallback writeCallback) + { + Value value; + AZStd::unique_ptr writer = value.GetWriteHandler(); + Visitor::Result result = writeCallback(*writer); + if (!result.IsSuccess()) + { + return AZ::Failure(result.GetError().FormatVisitorErrorMessage()); + } + return AZ::Success(AZStd::move(value)); + } } // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h index 84a6eb5687..f03e5b66b8 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h @@ -9,9 +9,12 @@ #pragma once #include +#include namespace AZ::Dom::Utils { Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor); Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor); + + AZ::Outcome WriteToValue(Backend::WriteCallback writeCallback); } // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index d9398da116..d8650601ba 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -19,7 +19,7 @@ namespace AZ::Dom { if (refCountedPointer.use_count() > 1) { - AZStd::shared_ptr newPointer = AZStd::make_shared(); + AZStd::shared_ptr newPointer = AZStd::allocate_shared(AZStdAlloc()); *newPointer = *refCountedPointer; refCountedPointer = AZStd::move(newPointer); } @@ -71,8 +71,8 @@ namespace AZ::Dom } Value::Value(Value&& value) noexcept - : m_value(value.m_value) { + operator=(value); } Value::Value(AZStd::string_view string, bool copy) @@ -174,7 +174,7 @@ namespace AZ::Dom Value& Value::operator=(Value&& other) noexcept { - m_value = other.m_value; + m_value.swap(other.m_value); return *this; } @@ -212,7 +212,7 @@ namespace AZ::Dom void Value::Swap(Value& other) noexcept { - AZStd::swap(m_value, other.m_value); + m_value.swap(other.m_value); } Type Dom::Value::GetType() const @@ -229,14 +229,15 @@ namespace AZ::Dom return AZStd::get(m_value) ? Type::TrueType : Type::FalseType; case 5: // AZStd::string_view case 6: // AZStd::shared_ptr + case 7: // ShortStringType return Type::StringType; - case 7: // ObjectPtr + case 8: // ObjectPtr return Type::ObjectType; - case 8: // ArrayPtr + case 9: // ArrayPtr return Type::ArrayType; - case 9: // NodePtr + case 10: // NodePtr return Type::NodeType; - case 10: // AZStd::any* + case 11: // AZStd::any* return Type::OpaqueType; } AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); @@ -310,7 +311,7 @@ namespace AZ::Dom Value& Value::SetObject() { - m_value = AZStd::make_shared(); + m_value = AZStd::allocate_shared(AZStdAlloc()); return *this; } @@ -511,6 +512,7 @@ namespace AZ::Dom Value& Value::AddMember(KeyType name, const Value& value) { Object::ContainerType& object = GetObjectInternal(); + object.reserve((object.size() / Object::ReserveIncrement + 1) * Object::ReserveIncrement); if (auto memberIt = FindMutableMember(name); memberIt != object.end()) { memberIt->second = value; @@ -613,7 +615,7 @@ namespace AZ::Dom Value& Value::SetArray() { - m_value = AZStd::make_shared(); + m_value = AZStd::allocate_shared(AZStdAlloc()); return *this; } @@ -685,7 +687,9 @@ namespace AZ::Dom Value& Value::PushBack(Value value) { - GetArrayInternal().push_back(AZStd::move(value)); + Array::ContainerType& array = GetArrayInternal(); + array.reserve((array.size() / Array::ReserveIncrement + 1) * Array::ReserveIncrement); + array.push_back(AZStd::move(value)); return *this; } @@ -717,7 +721,7 @@ namespace AZ::Dom void Value::SetNode(AZ::Name name) { - m_value = AZStd::make_shared(name); + m_value = AZStd::allocate_shared(AZStdAlloc(), name); } void Value::SetNode(AZStd::string_view name) @@ -899,6 +903,11 @@ namespace AZ::Dom return AZStd::get(m_value); case 6: // AZStd::shared_ptr return *AZStd::get>(m_value); + case 7: // ShortStringType + { + const ShortStringType& ShortString = AZStd::get(m_value); + return { ShortString.m_data.data(), ShortString.m_size }; + } } AZ_Assert(false, "AZ::Dom::Value: Called GetString on a non-string type"); return {}; @@ -911,12 +920,26 @@ namespace AZ::Dom void Value::SetString(AZStd::string_view value) { + if (value.size() <= ShortStringSize) + { + ShortStringType buffer; + buffer.m_size = value.size(); + memcpy(buffer.m_data.data(), value.data(), buffer.m_size); + m_value = buffer; + } m_value = value; } void Value::CopyFromString(AZStd::string_view value) { - m_value = AZStd::make_shared(value); + if (value.size() <= ShortStringSize) + { + SetString(value); + } + else + { + m_value = AZStd::allocate_shared(AZStdAlloc(), value); + } } AZStd::any& Value::GetOpaqueValue() const diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 39ae5a5c37..4dd3bde197 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -11,11 +11,13 @@ #include #include #include +#include #include #include #include #include #include +#include namespace AZ::Dom { @@ -34,6 +36,22 @@ namespace AZ::Dom OpaqueType = 8, }; + class ValueAllocator final : public ThreadPoolBase + { + public: + AZ_CLASS_ALLOCATOR(ValueAllocator, SystemAllocator, 0); + AZ_TYPE_INFO(ValueAllocator, "{5BC8B389-72C7-459E-B502-12E74D61869F}"); + + ValueAllocator() + : ThreadPoolBase("DomValueAllocator", "Allocator for AZ::Dom::Value") + { + } + }; + + // class ValueAllocator : public Internal::PoolAllocatorHelper; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; + static constexpr const size_t ReserveIncrement = 4; private: ContainerType m_values; @@ -59,6 +78,7 @@ namespace AZ::Dom using ContainerType = AZStd::vector; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; + static constexpr const size_t ReserveIncrement = 8; private: ContainerType m_values; @@ -293,6 +313,18 @@ namespace AZ::Dom explicit Value(AZStd::any* opaqueValue); + static constexpr const size_t ShortStringSize = sizeof(AZStd::string_view) - sizeof(size_t); + struct ShortStringType + { + AZStd::array m_data; + size_t m_size; + + bool operator==(const ShortStringType& other) const + { + return m_size == other.m_size ? memcmp(m_data.data(), other.m_data.data(), m_size) == 0 : false; + } + }; + // If using the the copy on write model, anything stored internally as a shared_ptr will // detach and copy when doing a mutating operation if use_count() > 1. @@ -311,6 +343,7 @@ namespace AZ::Dom // StringType AZStd::string_view, AZStd::shared_ptr, + ShortStringType, // ObjectType ObjectPtr, // ArrayType @@ -320,6 +353,10 @@ namespace AZ::Dom // OpaqueType AZStd::any*>; + static_assert( + sizeof(ValueType) == sizeof(AZStd::variant), + "ValueType should have no members larger than ShortStringType"); + ValueType m_value; }; } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index a760cc5b28..cf46a77d54 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -103,35 +103,68 @@ namespace AZ::Dom } const ValueInfo& topEntry = m_entryStack.top(); - if (topEntry.m_container.GetType() != containerType) + Value& container = topEntry.m_container; + ValueBuffer& buffer = GetValueBuffer(); + + if (container.GetType() != containerType) { return VisitorFailure( VisitorErrorCode::InternalError, AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); } - if (topEntry.m_attributeCount != attributeCount) + if (buffer.m_attributes.size() != attributeCount) { return VisitorFailure( VisitorErrorCode::InternalError, AZStd::string::format( "AZ::Dom::ValueWriter: %s expected %llu attributes but received %llu attributes instead", endMethodName, attributeCount, - topEntry.m_attributeCount)); + buffer.m_attributes.size())); } - if (topEntry.m_elementCount != elementCount) + if (buffer.m_elements.size() != elementCount) { return VisitorFailure( VisitorErrorCode::InternalError, AZStd::string::format( "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, - topEntry.m_elementCount)); + buffer.m_elements.size())); + } + if (buffer.m_attributes.size() > 0) + { + container.MemberReserve(buffer.m_attributes.size()); + for (AZStd::pair& entry : buffer.m_attributes) + { + container.AddMember(AZStd::move(entry.first), AZStd::move(entry.second)); + } + buffer.m_attributes.clear(); + } + + if(buffer.m_elements.size() > 0) + { + container.Reserve(buffer.m_elements.size()); + for (Value& entry : buffer.m_elements) + { + container.PushBack(AZStd::move(entry)); + } + buffer.m_elements.clear(); } m_entryStack.pop(); return FinishWrite(); } + ValueWriter::ValueBuffer& ValueWriter::GetValueBuffer() + { + if (m_entryStack.size() <= m_valueBuffers.size()) + { + return m_valueBuffers[m_entryStack.size() - 1]; + } + + m_valueBuffers.resize(m_entryStack.size()); + return m_valueBuffers[m_entryStack.size() - 1]; + } + Visitor::Result ValueWriter::EndObject(AZ::u64 attributeCount) { return EndContainer(Type::ObjectType, attributeCount, 0); @@ -192,16 +225,16 @@ namespace AZ::Dom m_entryStack.top().m_value.Swap(value); ValueInfo& newEntry = m_entryStack.top(); + constexpr const size_t reserveSize = 8; + if (!newEntry.m_key.IsEmpty()) { - newEntry.m_container.AddMember(newEntry.m_key, AZStd::move(value)); + GetValueBuffer().m_attributes.emplace_back(AZStd::move(newEntry.m_key), AZStd::move(value)); newEntry.m_key = AZ::Name(); - ++newEntry.m_attributeCount; } else { - newEntry.m_container.PushBack(AZStd::move(value)); - ++newEntry.m_elementCount; + GetValueBuffer().m_elements.emplace_back(AZStd::move(value)); } return VisitorSuccess(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index fb5f4324a6..617184a926 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -48,11 +48,18 @@ namespace AZ::Dom KeyType m_key; Value m_value; Value& m_container; - AZ::u64 m_attributeCount = 0; - AZ::u64 m_elementCount = 0; }; + struct ValueBuffer + { + AZStd::vector m_elements; + AZStd::vector> m_attributes; + }; + + ValueBuffer& GetValueBuffer(); + Value& m_result; AZStd::stack m_entryStack; + AZStd::vector m_valueBuffers; }; } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h b/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h index 72418b3d6e..bf24f04156 100644 --- a/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h +++ b/Code/Framework/AzCore/AzCore/Memory/PoolAllocator.h @@ -25,12 +25,12 @@ namespace AZ * Template you can use to create your own thread pool allocators, as you can't inherit from ThreadPoolAllocator. * This is the case because we use tread local storage and we need separate "static" instance for each allocator. */ - template + template class PoolAllocatorHelper - : public SimpleSchemaAllocator + : public SimpleSchemaAllocator { public: - using Base = SimpleSchemaAllocator; + using Base = SimpleSchemaAllocator; using pointer_type = typename Base::pointer_type; using size_type = typename Base::size_type; using difference_type = typename Base::difference_type; @@ -140,13 +140,13 @@ namespace AZ * use PoolAllocatorThreadSafe or do the sync yourself. */ class PoolAllocator - : public Internal::PoolAllocatorHelper + : public Internal::PoolAllocatorHelper { public: AZ_CLASS_ALLOCATOR(PoolAllocator, SystemAllocator, 0); AZ_TYPE_INFO(PoolAllocator, "{D3DC61AF-0949-4BFA-87E0-62FA03A4C025}"); - using Base = Internal::PoolAllocatorHelper; + using Base = Internal::PoolAllocatorHelper; PoolAllocator(const char* name = "PoolAllocator", const char* desc = "Generic pool allocator for small objects") : Base(name, desc) @@ -154,21 +154,21 @@ namespace AZ } }; - template - using ThreadPoolBase = Internal::PoolAllocatorHelper >; + template + using ThreadPoolBase = Internal::PoolAllocatorHelper, ProfileAllocations >; /*! * Thread safe pool allocator. If you want to create your own thread pool heap, * inherit from ThreadPoolBase, as we need unique static variable for allocator type. */ class ThreadPoolAllocator final - : public ThreadPoolBase + : public ThreadPoolBase { public: AZ_CLASS_ALLOCATOR(ThreadPoolAllocator, SystemAllocator, 0); AZ_TYPE_INFO(ThreadPoolAllocator, "{05B4857F-CD06-4942-99FD-CA6A7BAE855A}"); - using Base = ThreadPoolBase; + using Base = ThreadPoolBase; ThreadPoolAllocator() : Base("PoolAllocatorThreadSafe", "Generic thread safe pool allocator for small objects") diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index 0baa4aeb53..3e6143e805 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -8,9 +8,10 @@ #if defined(HAVE_BENCHMARK) -#include #include #include +#include +#include #include #include #include @@ -25,22 +26,26 @@ namespace Benchmark { UnitTest::AllocatorsBenchmarkFixture::SetUp(st); AZ::NameDictionary::Create(); + AZ::AllocatorInstance::Create(); } void SetUp(::benchmark::State& st) override { UnitTest::AllocatorsBenchmarkFixture::SetUp(st); AZ::NameDictionary::Create(); + AZ::AllocatorInstance::Create(); } void TearDown(::benchmark::State& st) override { + AZ::AllocatorInstance::Destroy(); AZ::NameDictionary::Destroy(); UnitTest::AllocatorsBenchmarkFixture::TearDown(st); } void TearDown(const ::benchmark::State& st) override { + AZ::AllocatorInstance::Destroy(); AZ::NameDictionary::Destroy(); UnitTest::AllocatorsBenchmarkFixture::TearDown(st); } @@ -143,6 +148,30 @@ namespace Benchmark } BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDocumentInPlace) + BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDomValueInPlace)(benchmark::State& state) + { + AZ::Dom::JsonBackend backend; + AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); + + for (auto _ : state) + { + state.PauseTiming(); + AZStd::string payloadCopy = serializedPayload; + state.ResumeTiming(); + + auto result = AZ::Dom::Utils::WriteToValue( + [&](AZ::Dom::Visitor& visitor) + { + return AZ::Dom::Utils::ReadFromStringInPlace(backend, payloadCopy, visitor); + }); + + benchmark::DoNotOptimize(result.GetValue()); + } + + state.SetBytesProcessed(serializedPayload.size() * state.iterations()); + } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDomValueInPlace) + BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocument)(benchmark::State& state) { AZ::Dom::JsonBackend backend; @@ -179,6 +208,17 @@ namespace Benchmark } BENCHMARK_REGISTER_JSON(DomJsonBenchmark, JsonUtilsDeserializeToDocument) + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonPayloadGeneration)(benchmark::State& state) + { + for (auto _ : state) + { + benchmark::DoNotOptimize(GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1))); + } + + state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); + } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonPayloadGeneration) + #undef BENCHMARK_REGISTER_JSON } // namespace Benchmark diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index e69de29bb2..d11ef7f69e 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace AZ::Dom::Benchmark +{ + class DomValueBenchmark : public UnitTest::AllocatorsBenchmarkFixture + { + public: + void SetUp(const ::benchmark::State& st) override + { + UnitTest::AllocatorsBenchmarkFixture::SetUp(st); + AZ::NameDictionary::Create(); + AZ::AllocatorInstance::Create(); + } + + void SetUp(::benchmark::State& st) override + { + UnitTest::AllocatorsBenchmarkFixture::SetUp(st); + AZ::NameDictionary::Create(); + AZ::AllocatorInstance::Create(); + } + + void TearDown(::benchmark::State& st) override + { + AZ::AllocatorInstance::Destroy(); + AZ::NameDictionary::Destroy(); + UnitTest::AllocatorsBenchmarkFixture::TearDown(st); + } + + void TearDown(const ::benchmark::State& st) override + { + AZ::AllocatorInstance::Destroy(); + AZ::NameDictionary::Destroy(); + UnitTest::AllocatorsBenchmarkFixture::TearDown(st); + } + + Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) + { + Value root(Type::ObjectType); + + AZStd::string entryTemplate; + while (entryTemplate.size() < static_cast(stringTemplateLength)) + { + entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "; + } + entryTemplate.resize(stringTemplateLength); + AZStd::string buffer; + + auto createString = [&](int n) -> Value + { + return Value(AZStd::string::format("#%i %s", n, entryTemplate.c_str()), true); + }; + + auto createEntry = [&](int n) -> Value + { + Value entry(Type::ObjectType); + entry.AddMember("string", createString(n)); + entry.AddMember("int", n); + entry.AddMember("double", static_cast(n) * 0.5); + entry.AddMember("bool", n % 2 == 0); + entry.AddMember("null", Value(Type::NullType)); + return entry; + }; + + auto createArray = [&]() -> Value + { + Value array(Type::ArrayType); + for (int i = 0; i < entryCount; ++i) + { + array.PushBack(createEntry(i)); + } + return array; + }; + + auto createObject = [&]() -> Value + { + Value object; + object.SetObject(); + for (int i = 0; i < entryCount; ++i) + { + buffer = AZStd::string::format("Key%i", i); + object.AddMember(AZ::Name(buffer), createArray()); + } + return object; + }; + + root["entries"] = createObject(); + + return root; + } + }; + + BENCHMARK_DEFINE_F(DomValueBenchmark, ValuePayloadGeneration)(benchmark::State& state) + { + for (auto _ : state) + { + benchmark::DoNotOptimize(GenerateDomBenchmarkPayload(state.range(0), state.range(1))); + } + + state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, ValuePayloadGeneration) + ->Args({ 10, 5 }) + ->Args({ 10, 500 }) + ->Args({ 100, 5 }) + ->Args({ 100, 500 }) + ->Unit(benchmark::kMillisecond); +} // namespace AZ::Dom::Benchmark diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 84e2e16958..125f426e02 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -25,12 +25,14 @@ namespace AZ::Dom::Tests { UnitTest::AllocatorsFixture::SetUp(); NameDictionary::Create(); + AZ::AllocatorInstance::Create(); } void TearDown() override { m_value = Value(); + AZ::AllocatorInstance::Destroy(); NameDictionary::Destroy(); UnitTest::AllocatorsFixture::TearDown(); } @@ -279,19 +281,24 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, String) { + const char* s1 = "reference string long enough to avoid SSO"; + const char* s2 = "copy string long enough to avoid SSO"; + m_value.SetObject(); - AZStd::string stringToReference = "foo"; + AZStd::string stringToReference = s1; m_value["no_copy"] = Value(stringToReference, false); - AZStd::string stringToCopy = "bar"; + AZStd::string stringToCopy = s2; m_value["copy"] = Value(stringToCopy, true); EXPECT_EQ(m_value["no_copy"].GetType(), Type::StringType); - EXPECT_EQ(m_value["no_copy"].GetString(), stringToReference); - EXPECT_EQ(m_value["no_copy"].GetString().data(), stringToReference.data()); + EXPECT_EQ(m_value["no_copy"].GetString(), s1); + stringToReference.at(0) = 'F'; + EXPECT_NE(m_value["no_copy"].GetString(), s1); EXPECT_EQ(m_value["copy"].GetType(), Type::StringType); - EXPECT_EQ(m_value["copy"].GetString(), stringToCopy); - EXPECT_NE(m_value["copy"].GetString().data(), stringToCopy.data()); + EXPECT_EQ(m_value["copy"].GetString(), s2); + stringToCopy.at(0) = 'F'; + EXPECT_EQ(m_value["copy"].GetString(), s2); PerformValueChecks(); } From 809ee2dce96fb3464a7a5d5a020469843dcdedc0 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 10 Dec 2021 16:18:38 -0800 Subject: [PATCH 009/272] Fix "force string copy" logic Signed-off-by: Nicholas Van Sickle --- .../AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp index 17f9bfea54..bc8ac9167c 100644 --- a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp @@ -361,7 +361,7 @@ namespace AZ::Dom::Json bool RapidJsonReadHandler::String(const char* str, rapidjson::SizeType length, bool copy) { - const Lifetime lifetime = copy ? m_stringLifetime : Lifetime::Temporary; + const Lifetime lifetime = !copy ? m_stringLifetime : Lifetime::Temporary; return CheckResult(m_visitor->String(AZStd::string_view(str, length), lifetime)); } @@ -377,7 +377,7 @@ namespace AZ::Dom::Json { m_visitor->Key(AZ::Name(key)); } - const Lifetime lifetime = copy ? m_stringLifetime : Lifetime::Temporary; + const Lifetime lifetime = !copy ? m_stringLifetime : Lifetime::Temporary; return CheckResult(m_visitor->RawKey(key, lifetime)); } From 1f2635d24bdaa200e256312df2df364b9cd26c2c Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 10 Dec 2021 16:35:26 -0800 Subject: [PATCH 010/272] Switch to the high pref heap allocator, roll back pool interface changes Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 13 ++++++------- .../AzCore/AzCore/Memory/PoolAllocator.h | 18 +++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 4dd3bde197..9399e10d15 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -36,22 +37,20 @@ namespace AZ::Dom OpaqueType = 8, }; - class ValueAllocator final : public ThreadPoolBase + class ValueAllocator final : public SimpleSchemaAllocator { public: - AZ_CLASS_ALLOCATOR(ValueAllocator, SystemAllocator, 0); AZ_TYPE_INFO(ValueAllocator, "{5BC8B389-72C7-459E-B502-12E74D61869F}"); + using Base = SimpleSchemaAllocator; + ValueAllocator() - : ThreadPoolBase("DomValueAllocator", "Allocator for AZ::Dom::Value") + : Base("DomValueAllocator", "Allocator for AZ::Dom::Value") { + DisableOverriding(); } }; - // class ValueAllocator : public Internal::PoolAllocatorHelper + template class PoolAllocatorHelper - : public SimpleSchemaAllocator + : public SimpleSchemaAllocator { public: - using Base = SimpleSchemaAllocator; + using Base = SimpleSchemaAllocator; using pointer_type = typename Base::pointer_type; using size_type = typename Base::size_type; using difference_type = typename Base::difference_type; @@ -140,13 +140,13 @@ namespace AZ * use PoolAllocatorThreadSafe or do the sync yourself. */ class PoolAllocator - : public Internal::PoolAllocatorHelper + : public Internal::PoolAllocatorHelper { public: AZ_CLASS_ALLOCATOR(PoolAllocator, SystemAllocator, 0); AZ_TYPE_INFO(PoolAllocator, "{D3DC61AF-0949-4BFA-87E0-62FA03A4C025}"); - using Base = Internal::PoolAllocatorHelper; + using Base = Internal::PoolAllocatorHelper; PoolAllocator(const char* name = "PoolAllocator", const char* desc = "Generic pool allocator for small objects") : Base(name, desc) @@ -154,21 +154,21 @@ namespace AZ } }; - template - using ThreadPoolBase = Internal::PoolAllocatorHelper, ProfileAllocations >; + template + using ThreadPoolBase = Internal::PoolAllocatorHelper >; /*! * Thread safe pool allocator. If you want to create your own thread pool heap, * inherit from ThreadPoolBase, as we need unique static variable for allocator type. */ class ThreadPoolAllocator final - : public ThreadPoolBase + : public ThreadPoolBase { public: AZ_CLASS_ALLOCATOR(ThreadPoolAllocator, SystemAllocator, 0); AZ_TYPE_INFO(ThreadPoolAllocator, "{05B4857F-CD06-4942-99FD-CA6A7BAE855A}"); - using Base = ThreadPoolBase; + using Base = ThreadPoolBase; ThreadPoolAllocator() : Base("PoolAllocatorThreadSafe", "Generic thread safe pool allocator for small objects") From 5da5ff90670c5260019989de8881d5e67b96ca4c Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 10 Dec 2021 17:13:23 -0800 Subject: [PATCH 011/272] Removed file size limit on .shadervariantlist files. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp | 4 ++-- Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 5eaa0d9ddb..8dc67bb3d1 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -241,7 +241,7 @@ namespace AZ { // Need to get the name of the shader file from the template so that we can preprocess the shader data and setup // source file dependencies. - if (!RPI::JsonUtils::LoadObjectFromFile(variantListFullPath, shaderVariantList)) + if (!RPI::JsonUtils::LoadObjectFromFile(variantListFullPath, shaderVariantList, AZStd::numeric_limits::max())) { AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse Shader Variant List Descriptor JSON from [%s]", variantListFullPath.c_str()); return LoadResult{LoadResult::Code::Error}; @@ -635,7 +635,7 @@ namespace AZ AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), variantListFullPath, true); RPI::ShaderVariantListSourceData shaderVariantListDescriptor; - if (!RPI::JsonUtils::LoadObjectFromFile(variantListFullPath, shaderVariantListDescriptor)) + if (!RPI::JsonUtils::LoadObjectFromFile(variantListFullPath, shaderVariantListDescriptor, AZStd::numeric_limits::max())) { AZ_Assert(false, "Failed to parse Shader Variant List Descriptor JSON [%s]", variantListFullPath.c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h index 4715acd64c..9f4cdcf31b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h @@ -29,7 +29,7 @@ namespace AZ //! Loads serialized object data from a json file at the specified path //! Errors will be reported using AZ trace template - bool LoadObjectFromFile(const AZStd::string& path, ObjectType& objectData); + bool LoadObjectFromFile(const AZStd::string& path, ObjectType& objectData, size_t maxFileSize = DefaultMaxFileSize); //! Saves serialized object data to a json file at the specified path //! Errors will be reported using AZ trace @@ -39,11 +39,11 @@ namespace AZ // Definitions... template - bool LoadObjectFromFile(const AZStd::string& path, ObjectType& objectData) + bool LoadObjectFromFile(const AZStd::string& path, ObjectType& objectData, size_t maxFileSize) { objectData = ObjectType(); - auto loadOutcome = AZ::JsonSerializationUtils::ReadJsonFile(path, DefaultMaxFileSize); + auto loadOutcome = AZ::JsonSerializationUtils::ReadJsonFile(path, maxFileSize); if (!loadOutcome.IsSuccess()) { AZ_Error("AZ::RPI::JsonUtils", false, "%s", loadOutcome.GetError().c_str()); From c53c97cf5f80bda645654cc4613be86a9eccc373 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Sat, 11 Dec 2021 15:54:57 -0800 Subject: [PATCH 012/272] Add another round of benchmarks Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 12 +- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 2 + .../AzCore/AzCore/DOM/DomValueWriter.cpp | 6 + .../AzCore/AzCore/DOM/DomValueWriter.h | 1 + .../AzCore/AzCore/DOM/DomVisitor.cpp | 5 + Code/Framework/AzCore/AzCore/DOM/DomVisitor.h | 2 + .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 86 ++++++++++++-- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 110 +++++++++++++++++- 8 files changed, 210 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index d8650601ba..ed4488267a 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -61,6 +61,11 @@ namespace AZ::Dom return m_children; } + Value::Value(AZStd::shared_ptr string) + : m_value(string) + { + } + Value::Value() { } @@ -895,6 +900,11 @@ namespace AZ::Dom m_value = aznumeric_cast(value); } + void Value::SetString(AZStd::shared_ptr string) + { + m_value = string; + } + AZStd::string_view Value::GetString() const { switch (m_value.index()) @@ -992,7 +1002,7 @@ namespace AZ::Dom } else if constexpr (AZStd::is_same_v>) { - result = visitor.String(*arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); + result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } else if constexpr (AZStd::is_same_v) { diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 9399e10d15..ac6a9d0c51 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -127,6 +127,7 @@ namespace AZ::Dom Value(const Value&); Value(Value&&) noexcept; Value(AZStd::string_view string, bool copy); + Value(AZStd::shared_ptr string); Value(int32_t value); Value(uint32_t value); @@ -281,6 +282,7 @@ namespace AZ::Dom AZStd::string_view GetString() const; size_t GetStringLength() const; void SetString(AZStd::string_view); + void SetString(AZStd::shared_ptr); void CopyFromString(AZStd::string_view); // opaque type API... diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index cf46a77d54..a8cc1f3947 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -68,6 +68,12 @@ namespace AZ::Dom return FinishWrite(); } + Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr value, [[maybe_unused]] Lifetime lifetime) + { + CurrentValue().SetString(value); + return FinishWrite(); + } + Visitor::Result ValueWriter::StartObject() { CurrentValue().SetObject(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index 617184a926..4c1d5a26ee 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -26,6 +26,7 @@ namespace AZ::Dom Result Double(double value) override; Result String(AZStd::string_view value, Lifetime lifetime) override; + Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) override; Result StartObject() override; Result EndObject(AZ::u64 attributeCount) override; Result Key(AZ::Name key) override; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp index ad314da385..af64c4cea8 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp @@ -105,6 +105,11 @@ namespace AZ::Dom return VisitorSuccess(); } + Visitor::Result Visitor::RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) + { + return String(*value, lifetime); + } + Visitor::Result Visitor::OpaqueValue([[maybe_unused]] const OpaqueType& value, [[maybe_unused]] Lifetime lifetime) { if (!SupportsOpaqueValues()) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h index bbe78131c3..3439a566e2 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace AZ::Dom { @@ -170,6 +171,7 @@ namespace AZ::Dom //! Operates on a string value. As strings are a reference type. //! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy. virtual Result String(AZStd::string_view value, Lifetime lifetime); + virtual Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime); //! Operates on an opaque value. As opaque values are a reference type, storage semantics are provided to //! indicate where the value may be stored persistently or requires a copy. //! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index 3e6143e805..98e62f4aa6 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -50,7 +50,7 @@ namespace Benchmark UnitTest::AllocatorsBenchmarkFixture::TearDown(st); } - AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) + rapidjson::Document GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength) { rapidjson::Document document; document.SetObject(); @@ -108,6 +108,13 @@ namespace Benchmark document.SetObject(); document.AddMember("entries", createObject(), document.GetAllocator()); + return document; + } + + AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) + { + rapidjson::Document document = GenerateDomJsonBenchmarkDocument(entryCount, stringTemplateLength); + AZStd::string serializedJson; auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson); AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON"); @@ -124,7 +131,7 @@ namespace Benchmark ->Args({ 100, 500 }) \ ->Unit(benchmark::kMillisecond); - BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocumentInPlace)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace)(benchmark::State& state) { AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); @@ -146,9 +153,9 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDocumentInPlace) + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace) - BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDomValueInPlace)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace)(benchmark::State& state) { AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); @@ -170,9 +177,9 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDomValueInPlace) + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace) - BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocument)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjson)(benchmark::State& state) { AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); @@ -190,9 +197,29 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDocument) + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjson) - BENCHMARK_DEFINE_F(DomJsonBenchmark, JsonUtilsDeserializeToDocument)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValue)(benchmark::State& state) + { + AZ::Dom::JsonBackend backend; + AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); + + for (auto _ : state) + { + auto result = AZ::Dom::Utils::WriteToValue( + [&](AZ::Dom::Visitor& visitor) + { + return AZ::Dom::Utils::ReadFromString(backend, serializedPayload, AZ::Dom::Lifetime::Temporary, visitor); + }); + + benchmark::DoNotOptimize(result.GetValue()); + } + + state.SetBytesProcessed(serializedPayload.size() * state.iterations()); + } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValue) + + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonDeserializeToRapidjson)(benchmark::State& state) { AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); @@ -206,9 +233,9 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, JsonUtilsDeserializeToDocument) + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeserializeToRapidjson) - BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonPayloadGeneration)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonMakeComplexObject)(benchmark::State& state) { for (auto _ : state) { @@ -217,7 +244,44 @@ namespace Benchmark state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonPayloadGeneration) + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonMakeComplexObject) + + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonLookupMemberByString)(benchmark::State& state) + { + rapidjson::Document document(rapidjson::kObjectType); + AZStd::vector keys; + for (int64_t i = 0; i < state.range(0); ++i) + { + AZStd::string key(AZStd::string::format("key%" PRId64, i)); + keys.push_back(key); + document.AddMember(rapidjson::Value(key.data(), static_cast(key.size()), document.GetAllocator()), rapidjson::Value(i), document.GetAllocator()); + } + + for (auto _ : state) + { + for (const AZStd::string& key : keys) + { + benchmark::DoNotOptimize(document.FindMember(key.data())); + } + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); + } + BENCHMARK_REGISTER_F(DomJsonBenchmark, RapidjsonLookupMemberByString)->Arg(100)->Arg(1000)->Arg(10000)->Unit(benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonDeepCopy)(benchmark::State& state) + { + rapidjson::Document original = GenerateDomJsonBenchmarkDocument(state.range(0), state.range(1)); + + for (auto _ : state) + { + rapidjson::Document copy; + original.Accept(copy); + } + + state.SetItemsProcessed(state.iterations()); + } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeepCopy) #undef BENCHMARK_REGISTER_JSON } // namespace Benchmark diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index d11ef7f69e..e3a0db594c 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace AZ::Dom::Benchmark { @@ -99,7 +100,7 @@ namespace AZ::Dom::Benchmark } }; - BENCHMARK_DEFINE_F(DomValueBenchmark, ValuePayloadGeneration)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueMakeComplexObject)(benchmark::State& state) { for (auto _ : state) { @@ -108,10 +109,115 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, ValuePayloadGeneration) + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueMakeComplexObject) ->Args({ 10, 5 }) ->Args({ 10, 500 }) ->Args({ 100, 5 }) ->Args({ 100, 500 }) ->Unit(benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueShallowCopy)(benchmark::State& state) + { + Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + + for (auto _ : state) + { + Value copy = original; + benchmark::DoNotOptimize(copy); + } + + state.SetItemsProcessed(state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueShallowCopy) + ->Args({ 10, 5 }) + ->Args({ 10, 500 }) + ->Args({ 100, 5 }) + ->Args({ 100, 500 }) + ->Unit(benchmark::kNanosecond); + + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueShallowCopyAndMutate)(benchmark::State& state) + { + Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + + for (auto _ : state) + { + Value copy = original; + copy["entries"]["Key0"].PushBack(42); + benchmark::DoNotOptimize(copy); + } + + state.SetItemsProcessed(state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueShallowCopyAndMutate) + ->Args({ 10, 5 }) + ->Args({ 10, 500 }) + ->Args({ 100, 5 }) + ->Args({ 100, 500 }) + ->Unit(benchmark::kNanosecond); + + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueDeepCopy)(benchmark::State& state) + { + Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); + + for (auto _ : state) + { + Value copy = original.DeepCopy(); + benchmark::DoNotOptimize(copy); + } + + state.SetItemsProcessed(state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueDeepCopy) + ->Args({ 10, 5 }) + ->Args({ 10, 500 }) + ->Args({ 100, 5 }) + ->Args({ 100, 500 }) + ->Unit(benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByName)(benchmark::State& state) + { + Value value(Type::ObjectType); + AZStd::vector keys; + for (int64_t i = 0; i < state.range(0); ++i) + { + AZ::Name key(AZStd::string::format("key%" PRId64, i)); + keys.push_back(key); + value[key] = i; + } + + for (auto _ : state) + { + for (const AZ::Name& key : keys) + { + benchmark::DoNotOptimize(value[key]); + } + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, LookupMemberByName)->Arg(100)->Arg(1000)->Arg(10000)->Unit(benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByString)(benchmark::State& state) + { + Value value(Type::ObjectType); + AZStd::vector keys; + for (int64_t i = 0; i < state.range(0); ++i) + { + AZStd::string key(AZStd::string::format("key%" PRId64, i)); + keys.push_back(key); + value[key] = i; + } + + for (auto _ : state) + { + for (const AZStd::string& key : keys) + { + benchmark::DoNotOptimize(value[key]); + } + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, LookupMemberByString)->Arg(100)->Arg(1000)->Arg(10000)->Unit(benchmark::kMillisecond); + } // namespace AZ::Dom::Benchmark From cc120c772cab1ba8a601ca063a85d7e9838b00c2 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Sun, 12 Dec 2021 12:58:52 -0800 Subject: [PATCH 013/272] Add RapidjsonCopyAndMutate to compare w/ shallow copy Signed-off-by: Nicholas Van Sickle --- .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 20 ++++++++++++++++++- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index 98e62f4aa6..477802dc37 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -276,13 +276,31 @@ namespace Benchmark for (auto _ : state) { rapidjson::Document copy; - original.Accept(copy); + copy.CopyFrom(original, copy.GetAllocator(), true); + benchmark::DoNotOptimize(copy); } state.SetItemsProcessed(state.iterations()); } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeepCopy) + BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonCopyAndMutate)(benchmark::State& state) + { + rapidjson::Document original = GenerateDomJsonBenchmarkDocument(state.range(0), state.range(1)); + + for (auto _ : state) + { + rapidjson::Document copy; + copy.CopyFrom(original, copy.GetAllocator(), true); + copy["entries"]["Key0"].PushBack(42, copy.GetAllocator()); + benchmark::DoNotOptimize(copy); + } + + state.SetItemsProcessed(state.iterations()); + } + BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonCopyAndMutate) + #undef BENCHMARK_REGISTER_JSON } // namespace Benchmark diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index e3a0db594c..3e02eaff2e 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -135,7 +135,7 @@ namespace AZ::Dom::Benchmark ->Args({ 100, 500 }) ->Unit(benchmark::kNanosecond); - BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueShallowCopyAndMutate)(benchmark::State& state) + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueCopyAndMutate)(benchmark::State& state) { Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); @@ -148,7 +148,7 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueShallowCopyAndMutate) + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueCopyAndMutate) ->Args({ 10, 5 }) ->Args({ 10, 500 }) ->Args({ 100, 5 }) From d9ac3c21208442916f3345c01e73306a722beb82 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Sun, 12 Dec 2021 13:56:10 -0800 Subject: [PATCH 014/272] Tidy up Type enum Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 82 +++++++++---------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 18 ++-- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 12 +-- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 12 +-- .../AzCore/Tests/DOM/DomValueTests.cpp | 38 ++++----- 5 files changed, 81 insertions(+), 81 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index ed4488267a..59e21a7d8b 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -141,31 +141,31 @@ namespace AZ::Dom { switch (type) { - case Type::NullType: + case Type::Null: // Null is the default initialized value break; - case Type::FalseType: + case Type::False: m_value = false; break; - case Type::TrueType: + case Type::True: m_value = true; break; - case Type::ObjectType: + case Type::Object: SetObject(); break; - case Type::ArrayType: + case Type::Array: SetArray(); break; - case Type::StringType: + case Type::String: SetString(""); break; - case Type::NumberType: + case Type::Number: m_value = 0.0; break; - case Type::NodeType: + case Type::Node: SetNode(""); break; - case Type::OpaqueType: + case Type::Opaque: AZ_Assert(false, "AZ::Dom::Value may not be constructed with an empty opaque type"); break; } @@ -225,43 +225,43 @@ namespace AZ::Dom switch (m_value.index()) { case 0: // AZStd::monostate - return Type::NullType; + return Type::Null; case 1: // int64_t case 2: // uint64_t case 3: // double - return Type::NumberType; + return Type::Number; case 4: // bool - return AZStd::get(m_value) ? Type::TrueType : Type::FalseType; + return AZStd::get(m_value) ? Type::True : Type::False; case 5: // AZStd::string_view case 6: // AZStd::shared_ptr case 7: // ShortStringType - return Type::StringType; + return Type::String; case 8: // ObjectPtr - return Type::ObjectType; + return Type::Object; case 9: // ArrayPtr - return Type::ArrayType; + return Type::Array; case 10: // NodePtr - return Type::NodeType; + return Type::Node; case 11: // AZStd::any* - return Type::OpaqueType; + return Type::Opaque; } AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); - return Type::NullType; + return Type::Null; } bool Value::IsNull() const { - return GetType() == Type::NullType; + return GetType() == Type::Null; } bool Value::IsFalse() const { - return GetType() == Type::FalseType; + return GetType() == Type::False; } bool Value::IsTrue() const { - return GetType() == Type::TrueType; + return GetType() == Type::True; } bool Value::IsBool() const @@ -271,27 +271,27 @@ namespace AZ::Dom bool Value::IsNode() const { - return GetType() == Type::NodeType; + return GetType() == Type::Node; } bool Value::IsObject() const { - return GetType() == Type::ObjectType; + return GetType() == Type::Object; } bool Value::IsArray() const { - return GetType() == Type::ArrayType; + return GetType() == Type::Array; } bool Value::IsOpaqueValue() const { - return GetType() == Type::OpaqueType; + return GetType() == Type::Opaque; } bool Value::IsNumber() const { - return GetType() == Type::NumberType; + return GetType() == Type::Number; } bool Value::IsInt() const @@ -311,7 +311,7 @@ namespace AZ::Dom bool Value::IsString() const { - return GetType() == Type::StringType; + return GetType() == Type::String; } Value& Value::SetObject() @@ -322,13 +322,13 @@ namespace AZ::Dom const Node& Value::GetNodeInternal() const { - AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); + AZ_Assert(GetType() == Type::Node, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); return *AZStd::get(m_value); } Node& Value::GetNodeInternal() { - AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); + AZ_Assert(GetType() == Type::Node, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); return *CheckCopyOnWrite(AZStd::get(m_value)); } @@ -336,9 +336,9 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ObjectType || type == Type::NodeType, + type == Type::Object || type == Type::Node, "AZ::Dom::Value: attempted to retrieve an object from a value that isn't an object or a node"); - if (type == Type::ObjectType) + if (type == Type::Object) { return AZStd::get(m_value)->m_values; } @@ -352,9 +352,9 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ObjectType || type == Type::NodeType, + type == Type::Object || type == Type::Node, "AZ::Dom::Value: attempted to retrieve an object from a value that isn't an object or a node"); - if (type == Type::ObjectType) + if (type == Type::Object) { return CheckCopyOnWrite(AZStd::get(m_value))->m_values; } @@ -368,9 +368,9 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ArrayType || type == Type::NodeType, + type == Type::Array || type == Type::Node, "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or a node"); - if (type == Type::ArrayType) + if (type == Type::Array) { return AZStd::get(m_value)->m_values; } @@ -384,9 +384,9 @@ namespace AZ::Dom { const Type type = GetType(); AZ_Assert( - type == Type::ArrayType || type == Type::NodeType, + type == Type::Array || type == Type::Node, "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or node"); - if (type == Type::ArrayType) + if (type == Type::Array) { return CheckCopyOnWrite(AZStd::get(m_value))->m_values; } @@ -751,13 +751,13 @@ namespace AZ::Dom void Value::SetNodeValue(Value value) { - AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: Attempted to set value for non-node type"); + AZ_Assert(GetType() == Type::Node, "AZ::Dom::Value: Attempted to set value for non-node type"); Array::ContainerType& nodeChildren = GetArrayInternal(); // Set the first non-node child, if one is found for (Value& entry : nodeChildren) { - if (entry.GetType() != Type::NodeType) + if (entry.GetType() != Type::Node) { entry = AZStd::move(value); return; @@ -770,13 +770,13 @@ namespace AZ::Dom Value Value::GetNodeValue() const { - AZ_Assert(GetType() == Type::NodeType, "AZ::Dom::Value: Attempted to get value for non-node type"); + AZ_Assert(GetType() == Type::Node, "AZ::Dom::Value: Attempted to get value for non-node type"); const Array::ContainerType& nodeChildren = GetArrayInternal(); // Get the first non-node child, if one is found for (const Value& entry : nodeChildren) { - if (entry.GetType() != Type::NodeType) + if (entry.GetType() != Type::Node) { return entry; } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index ac6a9d0c51..274f6b1934 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -26,15 +26,15 @@ namespace AZ::Dom enum class Type { - NullType = 0, - FalseType = 1, - TrueType = 2, - ObjectType = 3, - ArrayType = 4, - StringType = 5, - NumberType = 6, - NodeType = 7, - OpaqueType = 8, + Null = 0, + False = 1, + True = 2, + Object = 3, + Array = 4, + String = 5, + Number = 6, + Node = 7, + Opaque = 8, }; class ValueAllocator final : public SimpleSchemaAllocator diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index a8cc1f3947..3e48c097c8 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -87,13 +87,13 @@ namespace AZ::Dom const char* endMethodName; switch (containerType) { - case Type::ObjectType: + case Type::Object: endMethodName = "EndObject"; break; - case Type::ArrayType: + case Type::Array: endMethodName = "EndArray"; break; - case Type::NodeType: + case Type::Node: endMethodName = "EndNode"; break; default: @@ -173,7 +173,7 @@ namespace AZ::Dom Visitor::Result ValueWriter::EndObject(AZ::u64 attributeCount) { - return EndContainer(Type::ObjectType, attributeCount, 0); + return EndContainer(Type::Object, attributeCount, 0); } Visitor::Result ValueWriter::Key(AZ::Name key) @@ -199,7 +199,7 @@ namespace AZ::Dom Visitor::Result ValueWriter::EndArray(AZ::u64 elementCount) { - return EndContainer(Type::ArrayType, 0, elementCount); + return EndContainer(Type::Array, 0, elementCount); } Visitor::Result ValueWriter::StartNode(AZ::Name name) @@ -217,7 +217,7 @@ namespace AZ::Dom Visitor::Result ValueWriter::EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) { - return EndContainer(Type::NodeType, attributeCount, elementCount); + return EndContainer(Type::Node, attributeCount, elementCount); } Visitor::Result ValueWriter::FinishWrite() diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 3e02eaff2e..51d2e5c10c 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -46,7 +46,7 @@ namespace AZ::Dom::Benchmark Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) { - Value root(Type::ObjectType); + Value root(Type::Object); AZStd::string entryTemplate; while (entryTemplate.size() < static_cast(stringTemplateLength)) @@ -63,18 +63,18 @@ namespace AZ::Dom::Benchmark auto createEntry = [&](int n) -> Value { - Value entry(Type::ObjectType); + Value entry(Type::Object); entry.AddMember("string", createString(n)); entry.AddMember("int", n); entry.AddMember("double", static_cast(n) * 0.5); entry.AddMember("bool", n % 2 == 0); - entry.AddMember("null", Value(Type::NullType)); + entry.AddMember("null", Value(Type::Null)); return entry; }; auto createArray = [&]() -> Value { - Value array(Type::ArrayType); + Value array(Type::Array); for (int i = 0; i < entryCount; ++i) { array.PushBack(createEntry(i)); @@ -176,7 +176,7 @@ namespace AZ::Dom::Benchmark BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByName)(benchmark::State& state) { - Value value(Type::ObjectType); + Value value(Type::Object); AZStd::vector keys; for (int64_t i = 0; i < state.range(0); ++i) { @@ -199,7 +199,7 @@ namespace AZ::Dom::Benchmark BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByString)(benchmark::State& state) { - Value value(Type::ObjectType); + Value value(Type::Object); AZStd::vector keys; for (int64_t i = 0; i < state.range(0); ++i) { diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 125f426e02..62f3ad7601 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -79,7 +79,7 @@ namespace AZ::Dom::Tests m_value.SetArray(); for (int j = 0; j < 5; ++j) { - Value nestedArray(Type::ArrayType); + Value nestedArray(Type::Array); for (int i = 0; i < 5; ++i) { nestedArray.PushBack(Value(i)); @@ -127,7 +127,7 @@ namespace AZ::Dom::Tests m_value.SetObject(); for (int j = 0; j < 3; ++j) { - Value nestedObject(Type::ObjectType); + Value nestedObject(Type::Object); for (int i = 0; i < 5; ++i) { nestedObject.AddMember(AZStd::string::format("Key%i", i), Value(i)); @@ -189,7 +189,7 @@ namespace AZ::Dom::Tests for (int i = 0; i < 5; ++i) { - Value childNode(Type::NodeType); + Value childNode(Type::Node); childNode.SetNodeName(childNodeName); childNode.SetNodeValue(i); @@ -218,9 +218,9 @@ namespace AZ::Dom::Tests m_value["int64_min"] = AZStd::numeric_limits::min(); m_value["int64_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["int64_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["int64_min"].GetType(), Type::Number); EXPECT_EQ(m_value["int64_min"].GetInt64(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["int64_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["int64_max"].GetType(), Type::Number); EXPECT_EQ(m_value["int64_max"].GetInt64(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -232,9 +232,9 @@ namespace AZ::Dom::Tests m_value["uint64_min"] = AZStd::numeric_limits::min(); m_value["uint64_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["uint64_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["uint64_min"].GetType(), Type::Number); EXPECT_EQ(m_value["uint64_min"].GetInt64(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["uint64_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["uint64_max"].GetType(), Type::Number); EXPECT_EQ(m_value["uint64_max"].GetInt64(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -246,9 +246,9 @@ namespace AZ::Dom::Tests m_value["double_min"] = AZStd::numeric_limits::min(); m_value["double_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["double_min"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["double_min"].GetType(), Type::Number); EXPECT_EQ(m_value["double_min"].GetDouble(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["double_max"].GetType(), Type::NumberType); + EXPECT_EQ(m_value["double_max"].GetType(), Type::Number); EXPECT_EQ(m_value["double_max"].GetDouble(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -257,9 +257,9 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, Null) { m_value.SetObject(); - m_value["null_value"] = Value(Type::NullType); + m_value["null_value"] = Value(Type::Null); - EXPECT_EQ(m_value["null_value"].GetType(), Type::NullType); + EXPECT_EQ(m_value["null_value"].GetType(), Type::Null); EXPECT_EQ(m_value["null_type"], Value()); PerformValueChecks(); @@ -271,9 +271,9 @@ namespace AZ::Dom::Tests m_value["true_value"] = true; m_value["false_value"] = false; - EXPECT_EQ(m_value["true_value"].GetType(), Type::TrueType); + EXPECT_EQ(m_value["true_value"].GetType(), Type::True); EXPECT_EQ(m_value["true_value"].GetBool(), true); - EXPECT_EQ(m_value["false_value"].GetType(), Type::FalseType); + EXPECT_EQ(m_value["false_value"].GetType(), Type::False); EXPECT_EQ(m_value["false_value"].GetBool(), false); PerformValueChecks(); @@ -290,12 +290,12 @@ namespace AZ::Dom::Tests AZStd::string stringToCopy = s2; m_value["copy"] = Value(stringToCopy, true); - EXPECT_EQ(m_value["no_copy"].GetType(), Type::StringType); + EXPECT_EQ(m_value["no_copy"].GetType(), Type::String); EXPECT_EQ(m_value["no_copy"].GetString(), s1); stringToReference.at(0) = 'F'; EXPECT_NE(m_value["no_copy"].GetString(), s1); - EXPECT_EQ(m_value["copy"].GetType(), Type::StringType); + EXPECT_EQ(m_value["copy"].GetType(), Type::String); EXPECT_EQ(m_value["copy"].GetString(), s2); stringToCopy.at(0) = 'F'; EXPECT_EQ(m_value["copy"].GetString(), s2); @@ -305,10 +305,10 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, CopyOnWrite_Object) { - Value v1(Type::ObjectType); + Value v1(Type::Object); v1["foo"] = 5; - Value nestedObject(Type::ObjectType); + Value nestedObject(Type::Object); v1["obj"] = nestedObject; Value v2 = v1; @@ -333,11 +333,11 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, CopyOnWrite_Array) { - Value v1(Type::ArrayType); + Value v1(Type::Array); v1.PushBack(1); v1.PushBack(2); - Value nestedArray(Type::ArrayType); + Value nestedArray(Type::Array); v1.PushBack(nestedArray); Value v2 = v1; From e080ade885d84fa0bd0852b705dd46670b5e78bf Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Sun, 12 Dec 2021 14:20:16 -0800 Subject: [PATCH 015/272] Switch high perf allocator back on for containers, modest perf boost Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 274f6b1934..4b09068ec4 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -24,6 +24,7 @@ namespace AZ::Dom { using KeyType = AZ::Name; + //! The type of underlying value stored in a value. \see Value enum class Type { Null = 0, @@ -37,6 +38,9 @@ namespace AZ::Dom Opaque = 8, }; + //! The allocator used by Value. + //! Value heap allocates shared_ptrs for its container storage (Array / Object / Node) alongside the vector + //! contents of its container storage. class ValueAllocator final : public SimpleSchemaAllocator { public: @@ -56,7 +60,7 @@ namespace AZ::Dom class Array { public: - using ContainerType = AZStd::vector; + using ContainerType = AZStd::vector>; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 4; @@ -74,7 +78,7 @@ namespace AZ::Dom { public: using EntryType = AZStd::pair; - using ContainerType = AZStd::vector; + using ContainerType = AZStd::vector>; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 8; From 0216d0ae9f75927491feab2effa0e2273374fbc3 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 09:11:06 -0800 Subject: [PATCH 016/272] Clarify shared string semantics Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 16 +++++----- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 30 +++++++------------ .../AzCore/AzCore/DOM/DomValueWriter.cpp | 2 +- .../AzCore/AzCore/DOM/DomValueWriter.h | 2 +- .../AzCore/AzCore/DOM/DomVisitor.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomVisitor.h | 11 +++++-- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 59e21a7d8b..72eb7ebadd 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -61,7 +61,7 @@ namespace AZ::Dom return m_children; } - Value::Value(AZStd::shared_ptr string) + Value::Value(AZStd::shared_ptr string) : m_value(string) { } @@ -233,7 +233,7 @@ namespace AZ::Dom case 4: // bool return AZStd::get(m_value) ? Type::True : Type::False; case 5: // AZStd::string_view - case 6: // AZStd::shared_ptr + case 6: // AZStd::shared_ptr case 7: // ShortStringType return Type::String; case 8: // ObjectPtr @@ -900,7 +900,7 @@ namespace AZ::Dom m_value = aznumeric_cast(value); } - void Value::SetString(AZStd::shared_ptr string) + void Value::SetString(AZStd::shared_ptr string) { m_value = string; } @@ -911,8 +911,8 @@ namespace AZ::Dom { case 5: // AZStd::string_view return AZStd::get(m_value); - case 6: // AZStd::shared_ptr - return *AZStd::get>(m_value); + case 6: // AZStd::shared_ptr + return *AZStd::get>(m_value); case 7: // ShortStringType { const ShortStringType& ShortString = AZStd::get(m_value); @@ -948,7 +948,7 @@ namespace AZ::Dom } else { - m_value = AZStd::allocate_shared(AZStdAlloc(), value); + m_value = AZStd::allocate_shared(AZStdAlloc(), value); } } @@ -1000,7 +1000,7 @@ namespace AZ::Dom { result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } - else if constexpr (AZStd::is_same_v>) + else if constexpr (AZStd::is_same_v>) { result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } @@ -1096,7 +1096,7 @@ namespace AZ::Dom if (IsString() && other.IsString()) { // If we both hold the same ref counted string we don't need to do a full comparison - if (AZStd::holds_alternative>(m_value) && m_value == other.m_value) + if (AZStd::holds_alternative>(m_value) && m_value == other.m_value) { return true; } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 4b09068ec4..1a09b9a3c8 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -39,8 +39,7 @@ namespace AZ::Dom }; //! The allocator used by Value. - //! Value heap allocates shared_ptrs for its container storage (Array / Object / Node) alongside the vector - //! contents of its container storage. + //! Value heap allocates shared_ptrs for its container storage (Array / Object / Node) alongside class ValueAllocator final : public SimpleSchemaAllocator { public: @@ -131,7 +130,7 @@ namespace AZ::Dom Value(const Value&); Value(Value&&) noexcept; Value(AZStd::string_view string, bool copy); - Value(AZStd::shared_ptr string); + Value(AZStd::shared_ptr string); Value(int32_t value); Value(uint32_t value); @@ -242,10 +241,6 @@ namespace AZ::Dom const Array::ContainerType& GetArray() const; // Node API (supports both object + array API, plus a dedicated NodeName)... - // bool CanConvertToNodeFromObject() const; - // Value& ConvertToNodeFromObject(); - // Value& ConvertToObjectFromNode(); - void SetNode(AZ::Name name); void SetNode(AZStd::string_view name); @@ -282,14 +277,14 @@ namespace AZ::Dom float GetFloat() const; void SetFloat(float); - // string API... + // String API... AZStd::string_view GetString() const; size_t GetStringLength() const; void SetString(AZStd::string_view); - void SetString(AZStd::shared_ptr); + void SetString(AZStd::shared_ptr); void CopyFromString(AZStd::string_view); - // opaque type API... + // Opaque type API... AZStd::any& GetOpaqueValue() const; //! This sets this Value to represent a value of an type that the DOM has //! no formal knowledge of. Where possible, it should be preferred to @@ -298,10 +293,10 @@ namespace AZ::Dom //! values. void SetOpaqueValue(AZStd::any&); - // null API... + // Null API... void SetNull(); - // Visitor API + // Visitor API... Visitor::Result Accept(Visitor& visitor, bool copyStrings) const; AZStd::unique_ptr GetWriteHandler(); @@ -330,12 +325,9 @@ namespace AZ::Dom } }; - // If using the the copy on write model, anything stored internally as a shared_ptr will - // detach and copy when doing a mutating operation if use_count() > 1. - - // This internal storage will not have a 1:1 mapping to the public Type, as there may be - // multiple storage options (e.g. strings being stored as non-owning string_view or - // owning shared_ptr) + //! The internal storage type for Value. + //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes + //! for the same type in some instances, such as string storage using ValueType = AZStd::variant< // NullType AZStd::monostate, @@ -347,7 +339,7 @@ namespace AZ::Dom bool, // StringType AZStd::string_view, - AZStd::shared_ptr, + AZStd::shared_ptr, ShortStringType, // ObjectType ObjectPtr, diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 3e48c097c8..ef99809290 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -68,7 +68,7 @@ namespace AZ::Dom return FinishWrite(); } - Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr value, [[maybe_unused]] Lifetime lifetime) + Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr value, [[maybe_unused]] Lifetime lifetime) { CurrentValue().SetString(value); return FinishWrite(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index 4c1d5a26ee..6086ff4fe5 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -26,7 +26,7 @@ namespace AZ::Dom Result Double(double value) override; Result String(AZStd::string_view value, Lifetime lifetime) override; - Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) override; + Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) override; Result StartObject() override; Result EndObject(AZ::u64 attributeCount) override; Result Key(AZ::Name key) override; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp index af64c4cea8..5e3d6c2882 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp @@ -105,7 +105,7 @@ namespace AZ::Dom return VisitorSuccess(); } - Visitor::Result Visitor::RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) + Visitor::Result Visitor::RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) { return String(*value, lifetime); } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h index 3439a566e2..938df1bb5a 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h @@ -168,10 +168,15 @@ namespace AZ::Dom virtual Result Uint64(AZ::u64 value); //! Operates on a double precision, 64 bit floating point value. virtual Result Double(double value); - //! Operates on a string value. As strings are a reference type. - //! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy. + //! Operates on a string value. As strings are a reference type, + //! storage semantics are provided to indicate where the value may be stored persistently or requires a copy. + //! \param lifetime Specifies the lifetime of this string - if the string has a temporary lifetime, it cannot + //! safely be stored as a reference. virtual Result String(AZStd::string_view value, Lifetime lifetime); - virtual Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime); + //! Operates on a ref-counted string value. S + //! \param lifetime Specifies the lifetime of this string. If the string has a temporary lifetime, it may not + //! be safely stored as a reference, but may still be safely stored as a ref-counted shared_ptr. + virtual Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime); //! Operates on an opaque value. As opaque values are a reference type, storage semantics are provided to //! indicate where the value may be stored persistently or requires a copy. //! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special From 8da04f15d3a7e7c1b02e0d3431fe0bd90dfb481c Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 11:15:02 -0800 Subject: [PATCH 017/272] Add some Value documentation Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 36 +++++++++---- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 50 +++++++++++++------ .../AzCore/Tests/DOM/DomValueTests.cpp | 16 +++--- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 72eb7ebadd..dcecc67460 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -144,12 +144,9 @@ namespace AZ::Dom case Type::Null: // Null is the default initialized value break; - case Type::False: + case Type::Bool: m_value = false; break; - case Type::True: - m_value = true; - break; case Type::Object: SetObject(); break; @@ -159,8 +156,14 @@ namespace AZ::Dom case Type::String: SetString(""); break; - case Type::Number: - m_value = 0.0; + case Type::Int64: + m_value = int64_t{}; + break; + case Type::Uint64: + m_value = uint64_t{}; + break; + case Type::Double: + m_value = double{}; break; case Type::Node: SetNode(""); @@ -227,11 +230,13 @@ namespace AZ::Dom case 0: // AZStd::monostate return Type::Null; case 1: // int64_t + return Type::Int64; case 2: // uint64_t + return Type::Uint64; case 3: // double - return Type::Number; + return Type::Double; case 4: // bool - return AZStd::get(m_value) ? Type::True : Type::False; + return Type::Bool; case 5: // AZStd::string_view case 6: // AZStd::shared_ptr case 7: // ShortStringType @@ -256,12 +261,12 @@ namespace AZ::Dom bool Value::IsFalse() const { - return GetType() == Type::False; + return IsBool() && !AZStd::get(m_value); } bool Value::IsTrue() const { - return GetType() == Type::True; + return IsBool() && AZStd::get(m_value); } bool Value::IsBool() const @@ -291,7 +296,16 @@ namespace AZ::Dom bool Value::IsNumber() const { - return GetType() == Type::Number; + switch (GetType()) + { + case Type::Int64: + [[fallthrough]]; + case Type::Uint64: + [[fallthrough]]; + case Type::Double: + return true; + } + return false; } bool Value::IsInt() const diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 1a09b9a3c8..7ba73a8a4b 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -10,15 +10,15 @@ #include #include +#include #include #include -#include +#include #include #include #include #include #include -#include namespace AZ::Dom { @@ -27,19 +27,20 @@ namespace AZ::Dom //! The type of underlying value stored in a value. \see Value enum class Type { - Null = 0, - False = 1, - True = 2, - Object = 3, - Array = 4, - String = 5, - Number = 6, - Node = 7, - Opaque = 8, + Null, + Bool, + Object, + Array, + String, + Int64, + Uint64, + Double, + Node, + Opaque, }; //! The allocator used by Value. - //! Value heap allocates shared_ptrs for its container storage (Array / Object / Node) alongside + //! Value heap allocates shared_ptrs for its container storage (Array / Object / Node) alongside class ValueAllocator final : public SimpleSchemaAllocator { public: @@ -56,6 +57,7 @@ namespace AZ::Dom class Value; + //! Internal storage for a Value array: an ordered list of Values. class Array { public: @@ -73,6 +75,7 @@ namespace AZ::Dom using ArrayPtr = AZStd::shared_ptr; using ConstArrayPtr = AZStd::shared_ptr; + //! Internal storage for a Value object: an ordered list of Name / Value pairs. class Object { public: @@ -91,6 +94,9 @@ namespace AZ::Dom using ObjectPtr = AZStd::shared_ptr; using ConstObjectPtr = AZStd::shared_ptr; + //! Storage for a Value node: a named Value with both properties and children. + //! Properties are stored as an ordered list of Name / Value pairs. + //! Children are stored as an oredered list of Values. class Node { public: @@ -122,6 +128,21 @@ namespace AZ::Dom using NodePtr = AZStd::shared_ptr; using ConstNodePtr = AZStd::shared_ptr; + //! Value is a typed union of Dom types that can represent the types provdied by AZ::Dom::Visitor. + //! Value can be one of the following types: + //! - Null: a type with no value, this is the default type for Value + //! - Bool: a true or false boolean value + //! - Object: a container with an ordered list of Name/Value pairs, analagous to a JSON object + //! - Array: a container with an ordered list of Values, analagous to a JSON array + //! - String: a UTF-8 string + //! - Int64: a signed, 64-bit integer + //! - Uint64: an unsigned, 64-bit integer + //! - Double: a double precision floating point value + //! - Node: a container with a Name, an ordered list of Name/Values pairs (attributes), and an ordered list of Values (children), + //! analagous to an XML node + //! - Opaque: an arbitrary value stored in an AZStd::any. This is a non-serializable representation of an entry used only for in-memory + //! options. This is intended to be used as an intermediate value over the course of DOM transformation and as a proxy to pass through + //! types of which the DOM has no knowledge to other systems. class Value { public: @@ -327,7 +348,7 @@ namespace AZ::Dom //! The internal storage type for Value. //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes - //! for the same type in some instances, such as string storage + //! for the same type in some instances, such as string storage using ValueType = AZStd::variant< // NullType AZStd::monostate, @@ -351,8 +372,7 @@ namespace AZ::Dom AZStd::any*>; static_assert( - sizeof(ValueType) == sizeof(AZStd::variant), - "ValueType should have no members larger than ShortStringType"); + sizeof(ValueType) == sizeof(AZStd::variant), "ValueType should have no members larger than ShortStringType"); ValueType m_value; }; diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 62f3ad7601..b88ab746b9 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -218,9 +218,9 @@ namespace AZ::Dom::Tests m_value["int64_min"] = AZStd::numeric_limits::min(); m_value["int64_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["int64_min"].GetType(), Type::Number); + EXPECT_EQ(m_value["int64_min"].GetType(), Type::Int64); EXPECT_EQ(m_value["int64_min"].GetInt64(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["int64_max"].GetType(), Type::Number); + EXPECT_EQ(m_value["int64_max"].GetType(), Type::Int64); EXPECT_EQ(m_value["int64_max"].GetInt64(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -232,9 +232,9 @@ namespace AZ::Dom::Tests m_value["uint64_min"] = AZStd::numeric_limits::min(); m_value["uint64_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["uint64_min"].GetType(), Type::Number); + EXPECT_EQ(m_value["uint64_min"].GetType(), Type::Uint64); EXPECT_EQ(m_value["uint64_min"].GetInt64(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["uint64_max"].GetType(), Type::Number); + EXPECT_EQ(m_value["uint64_max"].GetType(), Type::Uint64); EXPECT_EQ(m_value["uint64_max"].GetInt64(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -246,9 +246,9 @@ namespace AZ::Dom::Tests m_value["double_min"] = AZStd::numeric_limits::min(); m_value["double_max"] = AZStd::numeric_limits::max(); - EXPECT_EQ(m_value["double_min"].GetType(), Type::Number); + EXPECT_EQ(m_value["double_min"].GetType(), Type::Double); EXPECT_EQ(m_value["double_min"].GetDouble(), AZStd::numeric_limits::min()); - EXPECT_EQ(m_value["double_max"].GetType(), Type::Number); + EXPECT_EQ(m_value["double_max"].GetType(), Type::Double); EXPECT_EQ(m_value["double_max"].GetDouble(), AZStd::numeric_limits::max()); PerformValueChecks(); @@ -271,9 +271,9 @@ namespace AZ::Dom::Tests m_value["true_value"] = true; m_value["false_value"] = false; - EXPECT_EQ(m_value["true_value"].GetType(), Type::True); + EXPECT_EQ(m_value["true_value"].GetType(), Type::Bool); EXPECT_EQ(m_value["true_value"].GetBool(), true); - EXPECT_EQ(m_value["false_value"].GetType(), Type::False); + EXPECT_EQ(m_value["false_value"].GetType(), Type::Bool); EXPECT_EQ(m_value["false_value"].GetBool(), false); PerformValueChecks(); From d044f51a8913f60666e379fe143affeaa3dc79a6 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 11:21:38 -0800 Subject: [PATCH 018/272] Remove DomDocument for now Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp | 0 Code/Framework/AzCore/AzCore/DOM/DomDocument.h | 0 Code/Framework/AzCore/AzCore/azcore_files.cmake | 2 -- 3 files changed, 2 deletions(-) delete mode 100644 Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp delete mode 100644 Code/Framework/AzCore/AzCore/DOM/DomDocument.h diff --git a/Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp b/Code/Framework/AzCore/AzCore/DOM/DomDocument.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Code/Framework/AzCore/AzCore/DOM/DomDocument.h b/Code/Framework/AzCore/AzCore/DOM/DomDocument.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index e17fb941b8..ef2511bddc 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -127,8 +127,6 @@ set(FILES Debug/TraceReflection.h DOM/DomBackend.cpp DOM/DomBackend.h - DOM/DomDocument.cpp - DOM/DomDocument.h DOM/DomUtils.cpp DOM/DomUtils.h DOM/DomValue.cpp From 202226c2cb616dd62c3353ee3adfed805ae2ab60 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 11:31:23 -0800 Subject: [PATCH 019/272] Document short string usage Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 7ba73a8a4b..5cb67123e5 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -334,6 +334,8 @@ namespace AZ::Dom explicit Value(AZStd::any* opaqueValue); + // Determine the short string buffer size based on the size of our largest internal type (string_view) + // minus the size of the short string size field. static constexpr const size_t ShortStringSize = sizeof(AZStd::string_view) - sizeof(size_t); struct ShortStringType { @@ -348,7 +350,7 @@ namespace AZ::Dom //! The internal storage type for Value. //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes - //! for the same type in some instances, such as string storage + //! for the same type in some instances, such as string storage. using ValueType = AZStd::variant< // NullType AZStd::monostate, From af91cea8ef25280af54c4d37dadcdb073bca50c7 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 11:56:53 -0800 Subject: [PATCH 020/272] Add copy-on-write note Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 5cb67123e5..ecaea3db3d 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -143,6 +143,10 @@ namespace AZ::Dom //! - Opaque: an arbitrary value stored in an AZStd::any. This is a non-serializable representation of an entry used only for in-memory //! options. This is intended to be used as an intermediate value over the course of DOM transformation and as a proxy to pass through //! types of which the DOM has no knowledge to other systems. + //! \note Value is a copy-on-write data structure and may be cheaply returned by value. Heap allocated data larger than the size of the + //! value itself (objects, arrays, and nodes) are copied by new Values only when their contents change, so care should be taken in + //! performance critical code to avoid mutation operations such as operator[] to avoid copies. It is recommended that an immutable Value + //! be explicitly be stored as a `const Value` to avoid accidental detach and copy operations. class Value { public: From 946a77e9144c582f99f024c88f7831191a1150f9 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 12:06:24 -0800 Subject: [PATCH 021/272] Document ValueWriter, add basic OpaqueValue handling Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp | 6 ++++++ Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h | 6 ++++++ Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomVisitor.h | 3 +-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index ef99809290..172f7f2a92 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -220,6 +220,12 @@ namespace AZ::Dom return EndContainer(Type::Node, attributeCount, elementCount); } + Visitor::Result ValueWriter::OpaqueValue(OpaqueType& value) + { + CurrentValue().SetOpaqueValue(value); + return FinishWrite(); + } + Visitor::Result ValueWriter::FinishWrite() { if (m_entryStack.empty()) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index 6086ff4fe5..7430ff910b 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -13,6 +13,8 @@ namespace AZ::Dom { + //! Visitor that writes to a Value. + //! Supports all Visitor operations. class ValueWriter : public Visitor { public: @@ -36,6 +38,7 @@ namespace AZ::Dom Result StartNode(AZ::Name name) override; Result RawStartNode(AZStd::string_view name, Lifetime lifetime) override; Result EndNode(AZ::u64 attributeCount, AZ::u64 elementCount) override; + Result OpaqueValue(OpaqueType& value) override; private: Result FinishWrite(); @@ -60,7 +63,10 @@ namespace AZ::Dom ValueBuffer& GetValueBuffer(); Value& m_result; + // Stores info about the current value being processed AZStd::stack m_entryStack; + // Provides temporary storage for elements and attributes to prevent extra heap allocations + // These buffers persist to be reused even as the entry stack changes AZStd::vector m_valueBuffers; }; } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp index 5e3d6c2882..4e13a2a95c 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp @@ -110,7 +110,7 @@ namespace AZ::Dom return String(*value, lifetime); } - Visitor::Result Visitor::OpaqueValue([[maybe_unused]] const OpaqueType& value, [[maybe_unused]] Lifetime lifetime) + Visitor::Result Visitor::OpaqueValue([[maybe_unused]] OpaqueType& value) { if (!SupportsOpaqueValues()) { diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h index 938df1bb5a..3bf1b3419b 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h @@ -181,8 +181,7 @@ namespace AZ::Dom //! indicate where the value may be stored persistently or requires a copy. //! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special //! cases with specific implementations, not generic usage. - //! Storage semantics are provided to indicate where the value may be stored persistently or requires a copy. - virtual Result OpaqueValue(const OpaqueType& value, Lifetime lifetime); + virtual Result OpaqueValue(OpaqueType& value); //! Operates on a raw value encoded as a UTF-8 string that hasn't had its type deduced. //! Visitors that support raw values (\see VisitorFlags::SupportsRawValues) may parse the raw value and //! forward it to the corresponding value call or calls of their choice. From aa9799a63b0b9c413e5f1431a299d41275648987 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 13 Dec 2021 15:05:17 -0800 Subject: [PATCH 022/272] Use the high perf allocator for DomValueWriter Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index 7430ff910b..488535ace6 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -56,17 +56,17 @@ namespace AZ::Dom struct ValueBuffer { - AZStd::vector m_elements; - AZStd::vector> m_attributes; + Array::ContainerType m_elements; + Object::ContainerType m_attributes; }; ValueBuffer& GetValueBuffer(); Value& m_result; // Stores info about the current value being processed - AZStd::stack m_entryStack; + AZStd::stack>> m_entryStack; // Provides temporary storage for elements and attributes to prevent extra heap allocations // These buffers persist to be reused even as the entry stack changes - AZStd::vector m_valueBuffers; + AZStd::vector> m_valueBuffers; }; } // namespace AZ::Dom From 352b4ab6907eb9bf7890bd4670c34a1781d12409 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 15 Dec 2021 10:23:58 -0800 Subject: [PATCH 023/272] Make DomValue final Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index ecaea3db3d..1b69c73ecc 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -147,7 +147,7 @@ namespace AZ::Dom //! value itself (objects, arrays, and nodes) are copied by new Values only when their contents change, so care should be taken in //! performance critical code to avoid mutation operations such as operator[] to avoid copies. It is recommended that an immutable Value //! be explicitly be stored as a `const Value` to avoid accidental detach and copy operations. - class Value + class Value final { public: // Constructors... From 016eda6cf13fdbaba417b6efc2c63f5e5d3039e3 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 8 Dec 2021 13:57:45 -0800 Subject: [PATCH 024/272] Fixed infinite recursion when adding prefabs While processing prefabs into spawnables new prefabs can be added for later processing. Because the new prefabs were immediately added to the list of prefabs it could happen that the new prefabs would be added to the active processor for processing, which could lead to infinite recursion. Adding prefabs while iterating prefabs now delays the addition until the iteration has completed. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Spawnable/PrefabProcessorContext.cpp | 26 +++++++++++++++++-- .../Prefab/Spawnable/PrefabProcessorContext.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index efef0f53de..ff32ac2ea5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -32,8 +32,24 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils bool PrefabProcessorContext::AddPrefab(AZStd::string prefabName, PrefabDom prefab) { - auto result = m_prefabs.emplace(AZStd::move(prefabName), AZStd::move(prefab)); - return result.second; + if (!m_isIterating) + { + auto result = m_prefabs.emplace(AZStd::move(prefabName), AZStd::move(prefab)); + return result.second; + } + else + { + auto it = m_prefabs.find(prefabName); + if (it == m_prefabs.end()) + { + auto result = m_pendingPrefabAdditions.emplace(AZStd::move(prefabName), AZStd::move(prefab)); + return result.second; + } + else + { + return false; + } + } } void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) @@ -43,7 +59,13 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { callback(it.first, it.second); } + m_isIterating = false; + for (auto& prefab : m_pendingPrefabAdditions) + { + m_prefabs.emplace(AZStd::move(prefab.first), AZStd::move(prefab.second)); + } + m_pendingPrefabAdditions.clear(); } void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index d35a09a574..ade17e2ff0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -134,6 +134,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZ::Data::AssetLoadBehavior ToAssetLoadBehavior(EntityAliasSpawnableLoadBehavior loadBehavior) const; NamedPrefabContainer m_prefabs; + NamedPrefabContainer m_pendingPrefabAdditions; SpawnableEntityAliasStore m_entityAliases; ProcessedObjectStoreContainer m_products; ProductAssetDependencyContainer m_registeredProductAssetDependencies; From 7e38a5f35cbf99e0fd852bfc276b65cce0716a53 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 8 Dec 2021 18:32:18 -0800 Subject: [PATCH 025/272] Fixed entity registration issue when setting up Spawnable Entity Aliases. In some cases entities created for use as a Spawnable Entity Alias would share an entity id with their original. This is no longer working due to a reverse lookup from an entity id to its PrefabDOM. Upon further investigation this turned out to not matter as instances that are created by the PrefabCatchmentProcessor would create new entity ids any way. This cause unexpected behavior at runtime as entity relations may be broken. This will be addressed in a future fix. Testing the above also highlighted a possible double delete in the builder when aliases were registered. This has also been fixed. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Prefab/Spawnable/PrefabProcessorContext.cpp | 5 +++-- .../Prefab/Spawnable/SpawnableUtils.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index ff32ac2ea5..d4fd785118 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -246,9 +246,10 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils it = aliasVisitors.emplace(source->m_spawnable.GetId(), AZStd::move(visitor)).first; } it->second.AddAlias( - AZ::Data::Asset(&target->m_spawnable, loadBehavior), alias.m_tag, sourceIndex, targetIndex, + AZ::Data::Asset(target->m_spawnable.GetId(), azrtti_typeid()), alias.m_tag, + sourceIndex, targetIndex, alias.m_aliasType, alias.m_loadBehavior == EntityAliasSpawnableLoadBehavior::QueueLoad); - + // Register the dependency between the two spawnables. RegisterProductAssetDependency(source->m_spawnable.GetId(), target->m_spawnable.GetId(), loadBehavior); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index 5e552aad3f..b51df104fe 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -86,7 +86,9 @@ namespace AzToolsFramework::Prefab::SpawnableUtils entityData.has_value(), "SpawnbleUtils were unable to locate entity '%.*s' in Instance '%s' for replacing.", AZ_STRING_ARG(alias), source.GetTemplateSourcePath().c_str()); auto placeholder = AZStd::make_unique(entityData->get().GetId(), entityData->get().GetName()); - return instance->ReplaceEntity(AZStd::move(placeholder), alias); + AZStd::unique_ptr result = instance->ReplaceEntity(AZStd::move(placeholder), alias); + result->SetId(AZ::Entity::MakeId()); + return result; } AZStd::unique_ptr ReplaceEntityWithPlaceholder(AZ::EntityId entityId, AzFramework::Spawnable& source) @@ -102,7 +104,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils aznumeric_cast(entityId)); source.GetEntities()[index] = AZStd::make_unique(original->GetId(), original->GetName()); - + original->SetId(AZ::Entity::MakeId()); return original; } @@ -123,10 +125,9 @@ namespace AzToolsFramework::Prefab::SpawnableUtils case PCU::EntityAliasType::Replace: return ResultPair(ReplaceEntityWithPlaceholder(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace); case PCU::EntityAliasType::Additional: - ResultPair(AZStd::make_unique(AZ::Entity::MakeId()), AzFramework::Spawnable::EntityAliasType::Additional); + ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Additional); case PCU::EntityAliasType::Merge: - // Use the same entity id as the original entity so at runtime the entity ids can be verified to match. - ResultPair(AZStd::make_unique(entityId), AzFramework::Spawnable::EntityAliasType::Merge); + ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Merge); default: AZ_Assert( false, "Invalid PrefabProcessorContext::EntityAliasType type (%i) provided.", aznumeric_cast(aliasType)); From cbea11c452559170f03d2bedbfff1cc4d922b7bb Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:48:56 -0800 Subject: [PATCH 026/272] Minor performance optimization to Prefab Instance. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../AzToolsFramework/Prefab/Instance/Instance.cpp | 8 ++++---- .../AzToolsFramework/Prefab/Instance/Instance.h | 4 ++-- .../Prefab/Spawnable/PrefabProcessorContext.cpp | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp index 490a151925..c685735f40 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp @@ -142,14 +142,14 @@ namespace AzToolsFramework return m_templateSourcePath; } - void Instance::SetTemplateSourcePath(AZ::IO::PathView sourcePath) + void Instance::SetTemplateSourcePath(AZ::IO::Path sourcePath) { - m_templateSourcePath = sourcePath; + m_templateSourcePath = AZStd::move(sourcePath); } - void Instance::SetContainerEntityName(AZStd::string_view containerName) + void Instance::SetContainerEntityName(AZStd::string containerName) { - m_containerEntity->SetName(containerName); + m_containerEntity->SetName(AZStd::move(containerName)); } bool Instance::AddEntity(AZ::Entity& entity) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h index 25971093cd..625357f485 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h @@ -80,8 +80,8 @@ namespace AzToolsFramework void SetTemplateId(TemplateId templateId); const AZ::IO::Path& GetTemplateSourcePath() const; - void SetTemplateSourcePath(AZ::IO::PathView sourcePath); - void SetContainerEntityName(AZStd::string_view containerName); + void SetTemplateSourcePath(AZ::IO::Path sourcePath); + void SetContainerEntityName(AZStd::string containerName); bool AddEntity(AZ::Entity& entity); bool AddEntity(AZStd::unique_ptr&& entity); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index d4fd785118..d79b270bb8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -154,6 +154,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { using namespace AzToolsFramework::Prefab; + // Resolve prefab links into spawnable links for the provided spawnable. for (EntityAliasStore& entityAlias : m_entityAliases) { auto sourcePrefab = AZStd::get_if(&entityAlias.m_source); From 76a913882c78c631a8bf649ed0d6c4ba6c08439c Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Fri, 10 Dec 2021 09:03:36 -0800 Subject: [PATCH 027/272] Resolving links in the Prefab Processing Stack now also makes sure that entity ids of aliased entities are appropriately unique or match. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Spawnable/PrefabProcessorContext.cpp | 24 +++++++++++++++++++ .../Prefab/Spawnable/SpawnableUtils.cpp | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index d79b270bb8..5c67c8f3b3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -253,6 +254,29 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils // Register the dependency between the two spawnables. RegisterProductAssetDependency(source->m_spawnable.GetId(), target->m_spawnable.GetId(), loadBehavior); + + // Patch up all entity ids so the alias points to the same entity id if needed. + switch (alias.m_aliasType) + { + case AzFramework::Spawnable::EntityAliasType::Original: + continue; + case AzFramework::Spawnable::EntityAliasType::Disable: + continue; + case AzFramework::Spawnable::EntityAliasType::Replace: + break; // Requires entity id for alias in source and target spawnable matches. + case AzFramework::Spawnable::EntityAliasType::Additional: + continue; + case AzFramework::Spawnable::EntityAliasType::Merge: + break; // Requires entity id for alias in source and target spawnable matches. + default: + continue; + } + + auto entityIdMapper = [source, target](const AZ::EntityId& originalId, bool /*isEntityId*/) -> AZ::EntityId + { + return originalId == target->m_index ? source->m_index : originalId; + }; + AZ::EntityUtils::ReplaceEntityIdsAndEntityRefs(&target->m_spawnable, entityIdMapper); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index b51df104fe..feed44c740 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -85,9 +85,9 @@ namespace AzToolsFramework::Prefab::SpawnableUtils AZ_Assert( entityData.has_value(), "SpawnbleUtils were unable to locate entity '%.*s' in Instance '%s' for replacing.", AZ_STRING_ARG(alias), source.GetTemplateSourcePath().c_str()); - auto placeholder = AZStd::make_unique(entityData->get().GetId(), entityData->get().GetName()); + // A new entity id can be used for the placeholder as `ReplaceEntity` will swap the entity ids. + auto placeholder = AZStd::make_unique(AZ::Entity::MakeId(), entityData->get().GetName()); AZStd::unique_ptr result = instance->ReplaceEntity(AZStd::move(placeholder), alias); - result->SetId(AZ::Entity::MakeId()); return result; } From 9def902e1ceac7fc82b0a9bca91c75647c755d54 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Fri, 10 Dec 2021 17:52:03 -0800 Subject: [PATCH 028/272] Fixes up parents for entities that are moved to another Prefab. This fixes issues with entities that are moved to another Prefab and have a parent that was also moved to the same Prefab. Entities that have their parent moved to another Prefab continue to work as is because a placeholder entity is always left behind. Entities that are moved to another Prefab but have a parent that's still in the original Prefab will currently not work correctly. This will be a addressed in a future commit. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Components/TransformComponent.cpp | 25 +-- .../Prefab/Spawnable/SpawnableUtils.cpp | 169 +++++++----------- .../Prefab/Spawnable/SpawnableUtils.h | 18 +- 3 files changed, 78 insertions(+), 134 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 809f664a10..2f3fc3cb8b 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -585,21 +585,24 @@ namespace AzFramework EBUS_EVENT_PTR(m_notificationBus, AZ::TransformNotificationBus, OnParentChanged, oldParent, parentId); m_parentChangedEvent.Signal(oldParent, parentId); - if (oldParent != parentId) // Don't send removal notification while activating. + if (GetEntity() != nullptr) { - EBUS_EVENT_ID(oldParent, AZ::TransformNotificationBus, OnChildRemoved, GetEntityId()); - auto oldParentTransform = AZ::TransformBus::FindFirstHandler(oldParent); - if (oldParentTransform) + if (oldParent != parentId) // Don't send removal notification while activating. { - oldParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Removed, GetEntityId()); + EBUS_EVENT_ID(oldParent, AZ::TransformNotificationBus, OnChildRemoved, GetEntityId()); + auto oldParentTransform = AZ::TransformBus::FindFirstHandler(oldParent); + if (oldParentTransform) + { + oldParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Removed, GetEntityId()); + } } - } - EBUS_EVENT_ID(parentId, AZ::TransformNotificationBus, OnChildAdded, GetEntityId()); - auto newParentTransform = AZ::TransformBus::FindFirstHandler(parentId); - if (newParentTransform) - { - newParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Added, GetEntityId()); + EBUS_EVENT_ID(parentId, AZ::TransformNotificationBus, OnChildAdded, GetEntityId()); + auto newParentTransform = AZ::TransformBus::FindFirstHandler(parentId); + if (newParentTransform) + { + newParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Added, GetEntityId()); + } } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index feed44c740..e30417324c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -52,14 +53,32 @@ namespace AzToolsFramework::Prefab::SpawnableUtils return result; } + const AZ::Entity* FindEntity(AZ::EntityId entityId, const AzToolsFramework::Prefab::Instance& source) + { + const AZ::Entity* result = nullptr; + source.GetConstEntities( + [&result, entityId](const AZ::Entity& entity) + { + if (entity.GetId() != entityId) + { + return true; + } + else + { + result = &entity; + return false; + } + }); + return result; + } + AZ::Entity* FindEntity(AZ::EntityId entityId, AzFramework::Spawnable& source) { uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entityId, source); return index != InvalidEntityIndex ? source.GetEntities()[index].get() : nullptr; } - template - AZStd::unique_ptr CloneEntity(AZ::EntityId entityId, T& source) + AZStd::unique_ptr CloneEntity(AZ::EntityId entityId, AzToolsFramework::Prefab::Instance& source) { AZ::Entity* target = Internal::FindEntity(entityId, source); AZ_Assert( @@ -74,43 +93,30 @@ namespace AzToolsFramework::Prefab::SpawnableUtils return clone; } - AZStd::unique_ptr ReplaceEntityWithPlaceholder(AZ::EntityId entityId, AzToolsFramework::Prefab::Instance& source) + AZStd::unique_ptr ReplaceEntityWithPlaceholder( + AZ::EntityId entityId, + [[maybe_unused]] AZStd::string_view sourcePrefabName, + AzToolsFramework::Prefab::Instance& source) { auto&& [instance, alias] = source.FindInstanceAndAlias(entityId); AZ_Assert( - instance, "SpawnbleUtils were unable to locate entity alias with id %zu in Instance '%s' for replacing.", - aznumeric_cast(entityId), source.GetTemplateSourcePath().c_str()); + instance, "SpawnbleUtils were unable to locate entity alias with id %zu in Instance '%.*s' for replacing.", + aznumeric_cast(entityId), AZ_STRING_ARG(sourcePrefabName)); EntityOptionalReference entityData = instance->GetEntity(alias); AZ_Assert( - entityData.has_value(), "SpawnbleUtils were unable to locate entity '%.*s' in Instance '%s' for replacing.", - AZ_STRING_ARG(alias), source.GetTemplateSourcePath().c_str()); + entityData.has_value(), "SpawnbleUtils were unable to locate entity '%.*s' in Instance '%.*s' for replacing.", + AZ_STRING_ARG(alias), AZ_STRING_ARG(sourcePrefabName)); // A new entity id can be used for the placeholder as `ReplaceEntity` will swap the entity ids. auto placeholder = AZStd::make_unique(AZ::Entity::MakeId(), entityData->get().GetName()); - AZStd::unique_ptr result = instance->ReplaceEntity(AZStd::move(placeholder), alias); - return result; + return instance->ReplaceEntity(AZStd::move(placeholder), alias); } - AZStd::unique_ptr ReplaceEntityWithPlaceholder(AZ::EntityId entityId, AzFramework::Spawnable& source) - { - uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entityId, source); - AZ_Assert( - index != InvalidEntityIndex, "SpawnbleUtils were unable to locate entity alias with id %zu in Spawnable for replacing.", - aznumeric_cast(entityId)); - - AZStd::unique_ptr original = AZStd::move(source.GetEntities()[index]); - AZ_Assert( - original, "SpawnbleUtils were unable to locate entity with id %zu in Spawnable for replacing.", - aznumeric_cast(entityId)); - - source.GetEntities()[index] = AZStd::make_unique(original->GetId(), original->GetName()); - original->SetId(AZ::Entity::MakeId()); - return original; - } - - template AZStd::pair, AzFramework::Spawnable::EntityAliasType> ApplyAlias( - Source& source, AZ::EntityId entityId, AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType) + AZStd::string_view sourcePrefabName, + AzToolsFramework::Prefab::Instance& source, + AZ::EntityId entityId, + AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType) { namespace PCU = AzToolsFramework::Prefab::PrefabConversionUtils; using ResultPair = AZStd::pair, AzFramework::Spawnable::EntityAliasType>; @@ -123,11 +129,13 @@ namespace AzToolsFramework::Prefab::SpawnableUtils case PCU::EntityAliasType::OptionalReplace: return ResultPair(CloneEntity(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace); case PCU::EntityAliasType::Replace: - return ResultPair(ReplaceEntityWithPlaceholder(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace); + return ResultPair( + ReplaceEntityWithPlaceholder(entityId, sourcePrefabName, source), + AzFramework::Spawnable::EntityAliasType::Replace); case PCU::EntityAliasType::Additional: - ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Additional); + return ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Additional); case PCU::EntityAliasType::Merge: - ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Merge); + return ResultPair(AZStd::make_unique(), AzFramework::Spawnable::EntityAliasType::Merge); default: AZ_Assert( false, "Invalid PrefabProcessorContext::EntityAliasType type (%i) provided.", aznumeric_cast(aliasType)); @@ -183,7 +191,8 @@ namespace AzToolsFramework::Prefab::SpawnableUtils AliasPath alias = source.GetAliasPathRelativeToInstance(entityId); if (!alias.empty()) { - auto&& [replacement, storedAliasType] = Internal::ApplyAlias(source, entityId, aliasType); + auto&& [replacement, storedAliasType] = + Internal::ApplyAlias(sourcePrefabName, source, entityId, aliasType); if (replacement) { AZ::Entity* result = replacement.get(); @@ -213,82 +222,30 @@ namespace AzToolsFramework::Prefab::SpawnableUtils } } - AZ::Entity* CreateEntityAlias( - AZStd::string sourcePrefabName, - AzToolsFramework::Prefab::Instance& source, - AzFramework::Spawnable& target, - AZ::EntityId entityId, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, - uint32_t tag, - AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context) + void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target) { - using namespace AzToolsFramework::Prefab::PrefabConversionUtils; - - AliasPath alias = source.GetAliasPathRelativeToInstance(entityId); - if (!alias.empty()) - { - auto&& [replacement, storedAliasType] = Internal::ApplyAlias(source, entityId, aliasType); - if (replacement) + target.GetEntities( + [&source, &target](AZStd::unique_ptr& entity) { - AZ::Entity* result = replacement.get(); - target.GetEntities().push_back(AZStd::move(replacement)); - - EntityAliasStore store; - store.m_aliasType = storedAliasType; - store.m_source.emplace(AZStd::move(sourcePrefabName), AZStd::move(alias)); - store.m_target.emplace(target, result->GetId()); - store.m_tag = tag; - store.m_loadBehavior = loadBehavior; - context.RegisterSpawnableEntityAlias(AZStd::move(store)); - - return result; - } - else - { - AZ_Assert(false, "A replacement for entity with id %zu could not be created.", static_cast(entityId)); - return nullptr; - } - } - else - { - AZ_Assert(false, "Entity with id %llu was not found in the source prefab.", static_cast(entityId)); - return nullptr; - } - } - - AZ::Entity* CreateEntityAlias( - AzFramework::Spawnable& source, - AzFramework::Spawnable& target, - AZ::EntityId entityId, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, - uint32_t tag, - AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context) - { - using namespace AzToolsFramework::Prefab::PrefabConversionUtils; - - auto&& [replacement, storedAliasType] = Internal::ApplyAlias(source, entityId, aliasType); - if (replacement) - { - AZ::Entity* result = replacement.get(); - target.GetEntities().push_back(AZStd::move(replacement)); - - EntityAliasStore store; - store.m_aliasType = storedAliasType; - store.m_source.emplace(source, entityId); - store.m_target.emplace(target, result->GetId()); - store.m_tag = tag; - store.m_loadBehavior = loadBehavior; - context.RegisterSpawnableEntityAlias(AZStd::move(store)); - - return result; - } - else - { - AZ_Assert(false, "A replacement for entity with id %zu could not be created.", static_cast(entityId)); - return nullptr; - } + AzFramework::TransformComponent* transform = entity->FindComponent(); + if (transform) + { + if (transform->GetParentId().IsValid()) + { + AliasPath originalParentAlias = source.GetAliasPathRelativeToInstance(transform->GetParentId()); + if (!originalParentAlias.empty()) + { + AZ::EntityId targetParentId = target.GetEntityIdFromAliasPath(originalParentAlias); + if (targetParentId.IsValid()) + { + // If this is valid then the parent was moved to the target spawnable so adjust the entity id. + transform->SetParent(targetParentId); + } + } + } + } + return true; + }); } uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h index ea8a49857e..ea33ca09cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h @@ -41,23 +41,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, uint32_t tag, AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context); - AZ::Entity* CreateEntityAlias( - AZStd::string sourcePrefabName, - AzToolsFramework::Prefab::Instance& source, - AzFramework::Spawnable& target, - AZ::EntityId entityId, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, - uint32_t tag, - AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context); - AZ::Entity* CreateEntityAlias( - AzFramework::Spawnable& source, - AzFramework::Spawnable& target, - AZ::EntityId entityId, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, - AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, - uint32_t tag, - AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context); + void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target); uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable); From b8e3b27ea92964c50e131793458ba71aaa30ff66 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Tue, 14 Dec 2021 15:02:04 -0800 Subject: [PATCH 029/272] Added a PrefabDocument for Prefab to simplify working with Prefabs during conversion to spawnables. The new PrefabDocument handles the Prefab and the Instance. This reduces the number of times the Instance has to be reloaded from the Prefab and keeps the entity ids stable between steps. The intention is for all the PrefabDocument to conceptually manipulate the Prefab DOM, although behind the scenes it will manipulate the Instance for now. The Instance should only be directly used in case the PrefabDocument doesn't provide the functionality yet. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../PrefabEditorEntityOwnershipService.cpp | 1 + .../Prefab/Spawnable/EditorInfoRemover.cpp | 45 ++------ .../Prefab/Spawnable/EditorInfoRemover.h | 5 +- .../Spawnable/PrefabCatchmentProcessor.cpp | 63 +++++----- .../Spawnable/PrefabCatchmentProcessor.h | 2 +- .../Prefab/Spawnable/PrefabDocument.cpp | 109 ++++++++++++++++++ .../Prefab/Spawnable/PrefabDocument.h | 47 ++++++++ .../Spawnable/PrefabProcessorContext.cpp | 45 +++----- .../Prefab/Spawnable/PrefabProcessorContext.h | 15 ++- .../aztoolsframework_files.cmake | 2 + .../PrefabBuilder/PrefabBuilderComponent.cpp | 10 +- .../PrefabBuilder/PrefabBuilderComponent.h | 2 +- 12 files changed, 230 insertions(+), 116 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index b91a0aac93..3d962ade67 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -417,6 +417,7 @@ namespace AzToolsFramework bool readyToCreateRootSpawnable = m_playInEditorData.m_assetsCache.IsActivated(); if (!readyToCreateRootSpawnable && !m_playInEditorData.m_assetsCache.Activate(Prefab::PrefabConversionUtils::PlayInEditor)) + { AZ_Error("Prefab", false, "Failed to create a prefab processing stack from key '%.*s'.", AZ_STRING_ARG(Prefab::PrefabConversionUtils::PlayInEditor)); return; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp index dfba1d54ba..3f6d698bbe 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp @@ -37,7 +37,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } prefabProcessorContext.ListPrefabs( - [this, &serializeContext, &prefabProcessorContext]([[maybe_unused]] AZStd::string_view prefabName, PrefabDom& prefab) + [this, &serializeContext, &prefabProcessorContext]([[maybe_unused]] AZStd::string_view prefabName, PrefabDocument& prefab) { auto result = RemoveEditorInfo(prefab, serializeContext, prefabProcessorContext); if (!result) @@ -58,10 +58,9 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } } - void EditorInfoRemover::GetEntitiesFromInstance( - AZStd::unique_ptr& instance, EntityList& hierarchyEntities) + void EditorInfoRemover::GetEntitiesFromInstance(AzToolsFramework::Prefab::Instance& instance, EntityList& hierarchyEntities) { - instance->GetAllEntitiesInHierarchy( + instance.GetAllEntitiesInHierarchy( [&hierarchyEntities](const AZStd::unique_ptr& entity) { hierarchyEntities.emplace_back(entity.get()); @@ -498,7 +497,7 @@ exportComponent, prefabProcessorContext); } EditorInfoRemover::RemoveEditorInfoResult EditorInfoRemover::RemoveEditorInfo( - PrefabDom& prefab, + PrefabDocument& prefab, AZ::SerializeContext* serializeContext, PrefabProcessorContext& prefabProcessorContext) { @@ -510,28 +509,10 @@ exportComponent, prefabProcessorContext); m_componentRequirementsValidator.SetPlatformTags(prefabProcessorContext.GetPlatformTags()); - // convert Prefab DOM into Prefab Instance. - AZStd::unique_ptr instance(aznew Instance()); - if (!Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*instance, prefab, - Prefab::PrefabDomUtils::LoadFlags::AssignRandomEntityId)) - { - PrefabDomValueReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); - - AZStd::string errorMessage("Failed to Load Prefab Instance from given Prefab Dom during Removal of Editor Info."); - if (sourceReference.has_value() && - sourceReference->get().IsString() && - sourceReference->get().GetStringLength() != 0) - { - AZStd::string_view source(sourceReference->get().GetString(), sourceReference->get().GetStringLength()); - errorMessage += AZStd::string::format("Prefab Source: %.*s", AZ_STRING_ARG(source)); - } - - return AZ::Failure(errorMessage); - } - // grab all nested entities from the Instance as source entities. + Instance& sourceInstance = prefab.GetInstance(); EntityList sourceEntities; - GetEntitiesFromInstance(instance, sourceEntities); + GetEntitiesFromInstance(sourceInstance, sourceEntities); EntityList exportEntities; @@ -597,7 +578,7 @@ exportComponent, prefabProcessorContext); exportEntitiesMap.emplace(entity->GetId(), entity); } ); - instance->RemoveNestedEntities( + sourceInstance.RemoveNestedEntities( [&exportEntitiesMap](const AZStd::unique_ptr& entity) { return exportEntitiesMap.find(entity->GetId()) == exportEntitiesMap.end(); @@ -605,7 +586,7 @@ exportComponent, prefabProcessorContext); ); // replace entities of instance with exported ones. - instance->GetAllEntitiesInHierarchy( + sourceInstance.GetAllEntitiesInHierarchy( [&exportEntitiesMap](AZStd::unique_ptr& entity) { auto entityId = entity->GetId(); @@ -614,16 +595,6 @@ exportComponent, prefabProcessorContext); } ); - // save the final result in the target Prefab DOM. - PrefabDom filteredPrefab; - if (!PrefabDomUtils::StoreInstanceInPrefabDom(*instance, filteredPrefab)) - { - return AZ::Failure(AZStd::string::format( - "Saving exported Prefab Instance within a Prefab Dom failed.") - ); - } - prefab.Swap(filteredPrefab); - return AZ::Success(); } } // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h index dc10952733..dbad58d2f5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h @@ -43,7 +43,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils using RemoveEditorInfoResult = AZ::Outcome; RemoveEditorInfoResult RemoveEditorInfo( - PrefabDom& prefab, + PrefabDocument& prefab, AZ::SerializeContext* serializeContext, PrefabProcessorContext& prefabProcessorContext); @@ -51,8 +51,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils protected: using EntityList = AZStd::vector; - static void GetEntitiesFromInstance( - AZStd::unique_ptr& instance, EntityList& hierarchyEntities); + static void GetEntitiesFromInstance(AzToolsFramework::Prefab::Instance& instance, EntityList& hierarchyEntities); static bool ReadComponentAttribute( AZ::Component* component, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 7a54950c47..4658eea49f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -25,7 +25,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { AZ::DataStream::StreamType serializationFormat = m_serializationFormat == SerializationFormats::Binary ? AZ::DataStream::StreamType::ST_BINARY : AZ::DataStream::StreamType::ST_XML; - context.ListPrefabs([&context, serializationFormat](AZStd::string_view prefabName, PrefabDom& prefab) + context.ListPrefabs([&context, serializationFormat](AZStd::string_view prefabName, PrefabDocument& prefab) { ProcessPrefab(context, prefabName, prefab, serializationFormat); }); @@ -45,7 +45,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } } - void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab, + void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDocument& prefab, AZ::DataStream::StreamType serializationFormat) { using namespace AzToolsFramework::Prefab::SpawnableUtils; @@ -64,45 +64,34 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer)); AZ_Assert(spawnable, "Failed to create a new spawnable."); - Instance instance; - if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom( - instance, prefab, object.GetReferencedAssets(), - Prefab::PrefabDomUtils::LoadFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is - // going to be used to create clones of the entities. - { - // Resolve entity aliases that store PrefabDOM information to use the spawnable instead. This is done before the entities are - // moved from the instance as they'd otherwise can't be found. - context.ResolveSpawnableEntityAliases(prefabName, *spawnable, instance); + Instance& instance = prefab.GetInstance(); + // Resolve entity aliases that store PrefabDOM information to use the spawnable instead. This is done before the entities are + // moved from the instance as they'd otherwise can't be found. + context.ResolveSpawnableEntityAliases(prefabName, *spawnable, instance); - AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities(); - instance.DetachAllEntitiesInHierarchy( - [&entities, &context](AZStd::unique_ptr entity) + AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities(); + instance.DetachAllEntitiesInHierarchy( + [&entities, &context](AZStd::unique_ptr entity) + { + if (entity) { - if (entity) + entity->InvalidateDependencies(); + AZ::Entity::DependencySortOutcome evaluation = entity->EvaluateDependenciesGetDetails(); + if (evaluation.IsSuccess()) { - entity->InvalidateDependencies(); - AZ::Entity::DependencySortOutcome evaluation = entity->EvaluateDependenciesGetDetails(); - if (evaluation.IsSuccess()) - { - entities.emplace_back(AZStd::move(entity)); - } - else - { - AZ_Error( - "Prefabs", false, "Entity '%s' %s cannot be activated for the following reason: %s", - entity->GetName().c_str(), entity->GetId().ToString().c_str(), evaluation.GetError().m_message.c_str()); - context.ErrorEncountered(); - } + entities.emplace_back(AZStd::move(entity)); } - }); + else + { + AZ_Error( + "Prefabs", false, "Entity '%s' %s cannot be activated for the following reason: %s", + entity->GetName().c_str(), entity->GetId().ToString().c_str(), evaluation.GetError().m_message.c_str()); + context.ErrorEncountered(); + } + } + }); - SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable); - context.GetProcessedObjects().push_back(AZStd::move(object)); - } - else - { - AZ_Error("Prefabs", false, "Failed to convert prefab '%.*s' to a spawnable.", AZ_STRING_ARG(prefabName)); - context.ErrorEncountered(); - } + SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable); + context.GetProcessedObjects().push_back(AZStd::move(object)); } } // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h index 253321f8e7..a3556d73b7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h @@ -40,7 +40,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils static void Reflect(AZ::ReflectContext* context); protected: - static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab, + static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDocument& prefab, AZ::DataStream::StreamType serializationFormat); SerializationFormats m_serializationFormat{ SerializationFormats::Binary }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp new file mode 100644 index 0000000000..1f55e0df1a --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +namespace AzToolsFramework::Prefab::PrefabConversionUtils +{ + PrefabDocument::PrefabDocument(AZStd::string name) + : m_name(AZStd::move(name)) + , m_instance(AZStd::make_unique()) + { + m_instance->SetTemplateSourcePath(AZ::IO::Path("InMemory") / name); + } + + bool PrefabDocument::SetPrefabDom(const PrefabDom& prefab) + { + if (ConstructInstanceFromPrefabDom(prefab)) + { + constexpr bool copyConstStrings = true; + m_dom.CopyFrom(prefab, m_dom.GetAllocator(), copyConstStrings); + return true; + } + else + { + return false; + } + } + + bool PrefabDocument::SetPrefabDom(PrefabDom&& prefab) + { + if (ConstructInstanceFromPrefabDom(prefab)) + { + m_dom = AZStd::move(prefab); + return true; + } + else + { + return false; + } + } + + const AZStd::string& PrefabDocument::GetName() const + { + return m_name; + } + + const PrefabDom& PrefabDocument::GetDom() const + { + if (m_isDirty) + { + m_isDirty = !PrefabDomUtils::StoreInstanceInPrefabDom(*m_instance, m_dom); + } + return m_dom; + } + + PrefabDom&& PrefabDocument::TakeDom() + { + if (m_isDirty) + { + m_isDirty = !PrefabDomUtils::StoreInstanceInPrefabDom(*m_instance, m_dom); + } + return AZStd::move(m_dom); + } + + AzToolsFramework::Prefab::Instance& PrefabDocument::GetInstance() + { + // Assume that changes will be made to the instance. + m_isDirty = true; + return *m_instance; + } + + const AzToolsFramework::Prefab::Instance& PrefabDocument::GetInstance() const + { + return *m_instance; + } + + bool PrefabDocument::ConstructInstanceFromPrefabDom(const PrefabDom& prefab) + { + using namespace AzToolsFramework::Prefab; + + m_instance->Reset(); + if (PrefabDomUtils::LoadInstanceFromPrefabDom(*m_instance, prefab, PrefabDomUtils::LoadFlags::AssignRandomEntityId)) + { + return true; + } + else + { + AZStd::string errorMessage("Failed to construct Prefab instance from given PrefabDOM"); + + PrefabDomValueConstReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); + if (sourceReference.has_value() && sourceReference->get().IsString() && sourceReference->get().GetStringLength() != 0) + { + errorMessage += " (Source: "; + errorMessage += AZStd::string_view(sourceReference->get().GetString(), sourceReference->get().GetStringLength()); + errorMessage += ')'; + } + + errorMessage += '.'; + AZ_Error("PrefabDocument", false, errorMessage.c_str()); + return false; + } + } +} // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h new file mode 100644 index 0000000000..804082b03b --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace AzToolsFramework::Prefab::PrefabConversionUtils +{ + class PrefabDocument final + { + public: + explicit PrefabDocument(AZStd::string name); + PrefabDocument(const PrefabDocument&) = delete; + PrefabDocument(PrefabDocument&&) = default; + + PrefabDocument& operator=(const PrefabDocument&) = delete; + PrefabDocument& operator=(PrefabDocument&&) = default; + + bool SetPrefabDom(const PrefabDom& prefab); + bool SetPrefabDom(PrefabDom&& prefab); + + const AZStd::string& GetName() const; + const PrefabDom& GetDom() const; + PrefabDom&& TakeDom(); + + // Where possible, prefer functions directly on the PrefabDocument Instead of using the Instance. + AzToolsFramework::Prefab::Instance& GetInstance(); + const AzToolsFramework::Prefab::Instance& GetInstance() const; + + private: + bool ConstructInstanceFromPrefabDom(const PrefabDom& prefab); + + mutable PrefabDom m_dom; + AZStd::unique_ptr m_instance; + AZStd::string m_name; + mutable bool m_isDirty{ false }; + }; +} // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index 5c67c8f3b3..0fd428fa3b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -31,49 +32,39 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils : m_sourceUuid(sourceUuid) {} - bool PrefabProcessorContext::AddPrefab(AZStd::string prefabName, PrefabDom prefab) + bool PrefabProcessorContext::AddPrefab(PrefabDocument&& document) { - if (!m_isIterating) + AZStd::string name = document.GetName(); + if (!m_prefabNames.contains(name)) { - auto result = m_prefabs.emplace(AZStd::move(prefabName), AZStd::move(prefab)); - return result.second; - } - else - { - auto it = m_prefabs.find(prefabName); - if (it == m_prefabs.end()) - { - auto result = m_pendingPrefabAdditions.emplace(AZStd::move(prefabName), AZStd::move(prefab)); - return result.second; - } - else - { - return false; - } + m_prefabNames.emplace(AZStd::move(name)); + PrefabContainer& container = m_isIterating ? m_pendingPrefabAdditions : m_prefabs; + container.push_back(AZStd::move(document)); + return true; } + return false; } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) + void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) { m_isIterating = true; - for (auto& it : m_prefabs) + for (PrefabDocument& document : m_prefabs) { - callback(it.first, it.second); + callback(document.GetName(), document); } m_isIterating = false; - for (auto& prefab : m_pendingPrefabAdditions) - { - m_prefabs.emplace(AZStd::move(prefab.first), AZStd::move(prefab.second)); - } + m_prefabs.insert( + m_prefabs.end(), AZStd::make_move_iterator(m_pendingPrefabAdditions.begin()), + AZStd::make_move_iterator(m_pendingPrefabAdditions.end())); m_pendingPrefabAdditions.clear(); } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const + void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const { - for (const auto& it : m_prefabs) + for (const PrefabDocument& document : m_prefabs) { - callback(it.first, it.second); + callback(document.GetName(), document); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index ade17e2ff0..4c2dc73ed8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace AzToolsFramework::Prefab::PrefabConversionUtils @@ -93,9 +94,9 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils explicit PrefabProcessorContext(const AZ::Uuid& sourceUuid); virtual ~PrefabProcessorContext() = default; - virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab); - virtual void ListPrefabs(const AZStd::function& callback); - virtual void ListPrefabs(const AZStd::function& callback) const; + virtual bool AddPrefab(PrefabDocument&& document); + virtual void ListPrefabs(const AZStd::function& callback); + virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; virtual bool RegisterSpawnableProductAssetDependency( @@ -128,13 +129,15 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual void ErrorEncountered(); protected: - using NamedPrefabContainer = AZStd::unordered_map; + using PrefabNames = AZStd::unordered_set; + using PrefabContainer = AZStd::vector; using SpawnableEntityAliasStore = AZStd::vector; AZ::Data::AssetLoadBehavior ToAssetLoadBehavior(EntityAliasSpawnableLoadBehavior loadBehavior) const; - NamedPrefabContainer m_prefabs; - NamedPrefabContainer m_pendingPrefabAdditions; + PrefabContainer m_prefabs; + PrefabContainer m_pendingPrefabAdditions; + PrefabNames m_prefabNames; SpawnableEntityAliasStore m_entityAliases; ProcessedObjectStoreContainer m_products; ProductAssetDependencyContainer m_registeredProductAssetDependencies; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 2c25cc9222..4c23289805 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -730,6 +730,8 @@ set(FILES Prefab/Spawnable/PrefabConversionPipeline.h Prefab/Spawnable/PrefabConversionPipeline.cpp Prefab/Spawnable/PrefabConverterStackProfileNames.h + Prefab/Spawnable/PrefabDocument.h + Prefab/Spawnable/PrefabDocument.cpp Prefab/Spawnable/ProcesedObjectStore.h Prefab/Spawnable/ProcesedObjectStore.cpp Prefab/Spawnable/PrefabProcessor.h diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index 6107226783..71464501ba 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -237,7 +237,7 @@ namespace AZ::Prefab bool PrefabBuilderComponent::ProcessPrefab( const AZ::PlatformTagSet& platformTags, const char* filePath, AZ::IO::PathView tempDirPath, const AZ::Uuid& sourceFileUuid, - AzToolsFramework::Prefab::PrefabDom& mutableRootDom, AZStd::vector& jobProducts) + AzToolsFramework::Prefab::PrefabDom&& rootDom, AZStd::vector& jobProducts) { AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext context(sourceFileUuid); AZStd::string rootPrefabName; @@ -247,7 +247,9 @@ namespace AZ::Prefab filePath); return false; } - context.AddPrefab(AZStd::move(rootPrefabName), AZStd::move(mutableRootDom)); + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument rootDocument(AZStd::move(rootPrefabName)); + rootDocument.SetPrefabDom(AZStd::move(rootDom)); + context.AddPrefab(AZStd::move(rootDocument)); context.SetPlatformTags(AZStd::move(platformTags)); @@ -319,8 +321,8 @@ namespace AZ::Prefab }); if (ProcessPrefab( - platformTags, request.m_fullPath.c_str(), request.m_tempDirPath.c_str(), request.m_sourceFileUUID, mutableRootDom, - response.m_outputProducts)) + platformTags, request.m_fullPath.c_str(), request.m_tempDirPath.c_str(), request.m_sourceFileUUID, + AZStd::move(mutableRootDom), response.m_outputProducts)) { response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; } diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h index 9ebdd690f5..73ef6b0426 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h @@ -53,7 +53,7 @@ namespace AZ::Prefab const AzToolsFramework::Prefab::PrefabDom& genericDocument); bool ProcessPrefab( const AZ::PlatformTagSet& platformTags, const char* filePath, AZ::IO::PathView tempDirPath, const AZ::Uuid& sourceFileUuid, - AzToolsFramework::Prefab::PrefabDom& mutableRootDom, + AzToolsFramework::Prefab::PrefabDom&& rootDom, AZStd::vector& jobProducts); protected: From 7b5868d19869e1a045a278b7cce0598dc8a3940c Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 15 Dec 2021 10:05:44 -0800 Subject: [PATCH 030/272] Added additional functions to edit prefabs during processing to PrefabDocument. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Prefab/Instance/Instance.cpp | 29 +++++++- .../Prefab/Instance/Instance.h | 7 ++ .../Prefab/Spawnable/EntityAliasTypes.h | 69 +++++++++++++++++++ .../Prefab/Spawnable/PrefabDocument.cpp | 52 +++++++++++--- .../Prefab/Spawnable/PrefabDocument.h | 19 +++++ .../Prefab/Spawnable/PrefabDocument.inl | 16 +++++ .../Prefab/Spawnable/PrefabProcessorContext.h | 51 +------------- .../Prefab/Spawnable/SpawnableUtils.cpp | 27 +------- .../Prefab/Spawnable/SpawnableUtils.h | 10 ++- .../aztoolsframework_files.cmake | 2 + 10 files changed, 193 insertions(+), 89 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.inl diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp index c685735f40..03d62dff0a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp @@ -608,6 +608,31 @@ namespace AzToolsFramework } AZ::EntityId Instance::GetEntityIdFromAliasPath(AliasPathView relativeAliasPath) const + { + return GetInstanceAndEntityIdFromAliasPath(relativeAliasPath).second; + } + + AZStd::pair Instance::GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) + { + Instance* instance = this; + AliasPathView path = relativeAliasPath.ParentPath(); + for (auto it : path) + { + InstanceOptionalReference child = instance->FindNestedInstance(it.Native()); + if (child.has_value()) + { + instance = &(child->get()); + } + else + { + return AZStd::pair(nullptr, AZ::EntityId()); + } + } + + return AZStd::pair(instance, instance->GetEntityId(relativeAliasPath.Filename().Native())); + } + + AZStd::pair Instance::GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const { const Instance* instance = this; AliasPathView path = relativeAliasPath.ParentPath(); @@ -620,11 +645,11 @@ namespace AzToolsFramework } else { - return AZ::EntityId(); + return AZStd::pair(nullptr, AZ::EntityId()); } } - return instance->GetEntityId(relativeAliasPath.Filename().Native()); + return AZStd::pair(instance, instance->GetEntityId(relativeAliasPath.Filename().Native())); } AZStd::vector Instance::GetNestedInstanceAliases(TemplateId templateId) const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h index 625357f485..b63eca309a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h @@ -169,6 +169,13 @@ namespace AzToolsFramework * @return entityId, invalid ID if not found */ AZ::EntityId GetEntityIdFromAliasPath(AliasPathView relativeAliasPath) const; + /** + * Retrieves the instance pointer and entity id from an alias path that's relative to this instance. + * + * @return A pair with the Instance and entity id. The Instance is set to null and entityId is set to invalid if not found. + */ + AZStd::pair GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath); + AZStd::pair GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const; /** diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h new file mode 100644 index 0000000000..9ab1f9bbd1 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace AzToolsFramework::Prefab::PrefabConversionUtils +{ + enum class EntityAliasType : uint8_t + { + Disable, //!< No alias is added. + OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned. + //!< The original entity will be left in the spawnable and a copy is returned. + Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned. The original + //!< entity is returned and a blank entity is left. + Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id. + //!< An empty entity will be returned. + Merge //!< At runtime the components in both entities will be merged. An empty entity will be returned. The added + //!< components may no conflict with the entities already in the root entity. + }; + + enum class EntityAliasSpawnableLoadBehavior : uint8_t + { + NoLoad, //!< Don't load the spawnable referenced in the entity alias. Loading will be up to the caller. + QueueLoad, //!< Queue the spawnable referenced in the entity alias for loading. This will be an async load because asset + //!< handlers aren't allowed to start a blocking load as this can lead to deadlocks. This option will allow + //!< to disable loading the referenced spawnable through the event fired from the spawnables asset handler. + DependentLoad //!< The spawnable referenced in the entity alias is made a dependency of the spawnable that holds the entity + //!< alias. This will cause the spawnable to be automatically loaded along with the owning spawnable. + }; + + struct EntityAliasSpawnableLink + { + EntityAliasSpawnableLink(AzFramework::Spawnable& spawnable, AZ::EntityId index); + + AzFramework::Spawnable& m_spawnable; + AZ::EntityId m_index; + }; + + struct EntityAliasPrefabLink + { + EntityAliasPrefabLink(AZStd::string prefabName, AzToolsFramework::Prefab::AliasPath alias); + + AZStd::string m_prefabName; + AzToolsFramework::Prefab::AliasPath m_alias; + }; + + struct EntityAliasStore + { + using LinkStore = AZStd::variant; + + LinkStore m_source; + LinkStore m_target; + uint32_t m_tag; + AzFramework::Spawnable::EntityAliasType m_aliasType; + EntityAliasSpawnableLoadBehavior m_loadBehavior; + }; +} // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp index 1f55e0df1a..c0eb5257b0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace AzToolsFramework::Prefab::PrefabConversionUtils { @@ -68,6 +69,43 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return AZStd::move(m_dom); } + void PrefabDocument::ListEntitiesWithComponentType( + AZ::TypeId componentType, const AZStd::function& callback) const + { + m_instance->GetAllEntitiesInHierarchyConst( + [this, &componentType, &callback](const AZ::Entity& entity) -> bool + { + if (entity.FindComponent(componentType)) + { + return callback(m_instance->GetAliasPathRelativeToInstance(entity.GetId())); + } + else + { + return true; + } + }); + } + + AZ::Entity* PrefabDocument::CreateEntityAlias( + PrefabDocument& source, + AzToolsFramework::Prefab::AliasPathView entity, + AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, + AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, + uint32_t tag, + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context) + { + auto&& [sourceInstance, entityId] = source.m_instance->GetInstanceAndEntityIdFromAliasPath(entity); + if (sourceInstance != nullptr && entityId.IsValid()) + { + return SpawnableUtils::CreateEntityAlias( + source.m_name, *sourceInstance, m_name, *m_instance, entityId, aliasType, loadBehavior, tag, context); + } + else + { + return nullptr; + } + } + AzToolsFramework::Prefab::Instance& PrefabDocument::GetInstance() { // Assume that changes will be made to the instance. @@ -91,18 +129,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } else { - AZStd::string errorMessage("Failed to construct Prefab instance from given PrefabDOM"); - +#ifdef AZ_ENABLE_TRACING + AZStd::string_view sourceName = m_name; PrefabDomValueConstReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); if (sourceReference.has_value() && sourceReference->get().IsString() && sourceReference->get().GetStringLength() != 0) { - errorMessage += " (Source: "; - errorMessage += AZStd::string_view(sourceReference->get().GetString(), sourceReference->get().GetStringLength()); - errorMessage += ')'; + sourceName = AZStd::string_view(sourceReference->get().GetString(), sourceReference->get().GetStringLength()); } - - errorMessage += '.'; - AZ_Error("PrefabDocument", false, errorMessage.c_str()); + AZ_Error( + "PrefabDocument", false, "Failed to construct Prefab instance from given PrefabDOM '%.*s'.", AZ_STRING_ARG(sourceName)); +#endif return false; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h index 804082b03b..215daf7f71 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h @@ -8,13 +8,18 @@ #pragma once +#include #include #include #include #include +#include +#include namespace AzToolsFramework::Prefab::PrefabConversionUtils { + class PrefabProcessorContext; + class PrefabDocument final { public: @@ -32,6 +37,18 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils const PrefabDom& GetDom() const; PrefabDom&& TakeDom(); + template + void ListEntitiesWithComponentType(const AZStd::function& callback) const; + void ListEntitiesWithComponentType( + AZ::TypeId componentType, const AZStd::function& callback) const; + AZ::Entity* CreateEntityAlias( + PrefabDocument& source, + AzToolsFramework::Prefab::AliasPathView entity, + AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType, + AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, + uint32_t tag, + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context); + // Where possible, prefer functions directly on the PrefabDocument Instead of using the Instance. AzToolsFramework::Prefab::Instance& GetInstance(); const AzToolsFramework::Prefab::Instance& GetInstance() const; @@ -45,3 +62,5 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils mutable bool m_isDirty{ false }; }; } // namespace AzToolsFramework::Prefab::PrefabConversionUtils + +#include diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.inl b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.inl new file mode 100644 index 0000000000..37b1f1c127 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.inl @@ -0,0 +1,16 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +namespace AzToolsFramework::Prefab::PrefabConversionUtils +{ + template + void PrefabDocument::ListEntitiesWithComponentType(const AZStd::function& callback) const + { + ListEntitiesWithComponentType(azrtti_typeid(), callback); + } +} // namespace AzToolsFramework::Prefab::PrefabConversionUtils diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index 4c2dc73ed8..8dde89b9e1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -21,61 +21,12 @@ #include #include #include +#include #include #include namespace AzToolsFramework::Prefab::PrefabConversionUtils { - enum class EntityAliasType : uint8_t - { - Disable, //!< No alias is added. - OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned. - //!< The original entity will be left in the spawnable and a copy is returned. - Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned. The original - //!< entity is returned and a blank entity is left. - Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id. - //!< An empty entity will be returned. - Merge //!< At runtime the components in both entities will be merged. An empty entity will be returned. The added - //!< components may no conflict with the entities already in the root entity. - }; - - enum class EntityAliasSpawnableLoadBehavior : uint8_t - { - NoLoad, //!< Don't load the spawnable referenced in the entity alias. Loading will be up to the caller. - QueueLoad, //!< Queue the spawnable referenced in the entity alias for loading. This will be an async load because asset - //!< handlers aren't allowed to start a blocking load as this can lead to deadlocks. This option will allow - //!< to disable loading the referenced spawnable through the event fired from the spawnables asset handler. - DependentLoad //!< The spawnable referenced in the entity alias is made a dependency of the spawnable that holds the entity - //!< alias. This will cause the spawnable to be automatically loaded along with the owning spawnable. - }; - - struct EntityAliasSpawnableLink - { - EntityAliasSpawnableLink(AzFramework::Spawnable& spawnable, AZ::EntityId index); - - AzFramework::Spawnable& m_spawnable; - AZ::EntityId m_index; - }; - - struct EntityAliasPrefabLink - { - EntityAliasPrefabLink(AZStd::string prefabName, AzToolsFramework::Prefab::AliasPath alias); - - AZStd::string m_prefabName; - AzToolsFramework::Prefab::AliasPath m_alias; - }; - - struct EntityAliasStore - { - using LinkStore = AZStd::variant; - - LinkStore m_source; - LinkStore m_target; - uint32_t m_tag; - AzFramework::Spawnable::EntityAliasType m_aliasType; - EntityAliasSpawnableLoadBehavior m_loadBehavior; - }; - struct AssetDependencyInfo { AZ::Data::AssetId m_assetId; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index e30417324c..4f007f509e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace AzToolsFramework::Prefab::SpawnableUtils { @@ -222,32 +223,6 @@ namespace AzToolsFramework::Prefab::SpawnableUtils } } - void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target) - { - target.GetEntities( - [&source, &target](AZStd::unique_ptr& entity) - { - AzFramework::TransformComponent* transform = entity->FindComponent(); - if (transform) - { - if (transform->GetParentId().IsValid()) - { - AliasPath originalParentAlias = source.GetAliasPathRelativeToInstance(transform->GetParentId()); - if (!originalParentAlias.empty()) - { - AZ::EntityId targetParentId = target.GetEntityIdFromAliasPath(originalParentAlias); - if (targetParentId.IsValid()) - { - // If this is valid then the parent was moved to the target spawnable so adjust the entity id. - transform->SetParent(targetParentId); - } - } - } - } - return true; - }); - } - uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable) { auto begin = spawnable.GetEntities().begin(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h index ea33ca09cc..53d007c0c1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace AZ { @@ -24,6 +24,11 @@ namespace AzToolsFramework::Prefab class Instance; } +namespace AzToolsFramework::Prefab::PrefabConversionUtils +{ + class PrefabProcessorContext; +} + namespace AzToolsFramework::Prefab::SpawnableUtils { static constexpr uint32_t InvalidEntityIndex = AZStd::numeric_limits::max(); @@ -41,8 +46,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior, uint32_t tag, AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context); - void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target); - + uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable); void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 4c23289805..05c07afecd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -723,6 +723,7 @@ set(FILES Prefab/Spawnable/EditorOnlyEntityHandler/UiEditorOnlyEntityHandler.cpp Prefab/Spawnable/EditorOnlyEntityHandler/WorldEditorOnlyEntityHandler.h Prefab/Spawnable/EditorOnlyEntityHandler/WorldEditorOnlyEntityHandler.cpp + Prefab/Spawnable/EntityAliasTypes.h Prefab/Spawnable/InMemorySpawnableAssetContainer.h Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp Prefab/Spawnable/PrefabCatchmentProcessor.h @@ -731,6 +732,7 @@ set(FILES Prefab/Spawnable/PrefabConversionPipeline.cpp Prefab/Spawnable/PrefabConverterStackProfileNames.h Prefab/Spawnable/PrefabDocument.h + Prefab/Spawnable/PrefabDocument.inl Prefab/Spawnable/PrefabDocument.cpp Prefab/Spawnable/ProcesedObjectStore.h Prefab/Spawnable/ProcesedObjectStore.cpp From 43c42f63c642aa47a7aae56a9bb5f765ca55f4c2 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 15 Dec 2021 10:52:23 -0800 Subject: [PATCH 031/272] Cleaned up some unused code in the Prefab processor. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Components/TransformComponent.cpp | 25 ++++++++----------- .../Prefab/Spawnable/EditorInfoRemover.cpp | 4 +-- .../Spawnable/PrefabCatchmentProcessor.cpp | 10 ++++---- .../Spawnable/PrefabCatchmentProcessor.h | 3 +-- .../Spawnable/PrefabProcessorContext.cpp | 8 +++--- .../Prefab/Spawnable/PrefabProcessorContext.h | 4 +-- 6 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 2f3fc3cb8b..809f664a10 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -585,24 +585,21 @@ namespace AzFramework EBUS_EVENT_PTR(m_notificationBus, AZ::TransformNotificationBus, OnParentChanged, oldParent, parentId); m_parentChangedEvent.Signal(oldParent, parentId); - if (GetEntity() != nullptr) + if (oldParent != parentId) // Don't send removal notification while activating. { - if (oldParent != parentId) // Don't send removal notification while activating. + EBUS_EVENT_ID(oldParent, AZ::TransformNotificationBus, OnChildRemoved, GetEntityId()); + auto oldParentTransform = AZ::TransformBus::FindFirstHandler(oldParent); + if (oldParentTransform) { - EBUS_EVENT_ID(oldParent, AZ::TransformNotificationBus, OnChildRemoved, GetEntityId()); - auto oldParentTransform = AZ::TransformBus::FindFirstHandler(oldParent); - if (oldParentTransform) - { - oldParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Removed, GetEntityId()); - } + oldParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Removed, GetEntityId()); } + } - EBUS_EVENT_ID(parentId, AZ::TransformNotificationBus, OnChildAdded, GetEntityId()); - auto newParentTransform = AZ::TransformBus::FindFirstHandler(parentId); - if (newParentTransform) - { - newParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Added, GetEntityId()); - } + EBUS_EVENT_ID(parentId, AZ::TransformNotificationBus, OnChildAdded, GetEntityId()); + auto newParentTransform = AZ::TransformBus::FindFirstHandler(parentId); + if (newParentTransform) + { + newParentTransform->NotifyChildChangedEvent(AZ::ChildChangeType::Added, GetEntityId()); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp index 3f6d698bbe..9488b68ee8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.cpp @@ -37,13 +37,13 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } prefabProcessorContext.ListPrefabs( - [this, &serializeContext, &prefabProcessorContext]([[maybe_unused]] AZStd::string_view prefabName, PrefabDocument& prefab) + [this, &serializeContext, &prefabProcessorContext](PrefabDocument& prefab) { auto result = RemoveEditorInfo(prefab, serializeContext, prefabProcessorContext); if (!result) { AZ_Error( - "Prefab", false, "Converting to runtime Prefab '%.*s' failed, Error: %s .", AZ_STRING_ARG(prefabName), + "Prefab", false, "Converting to runtime Prefab '%s' failed, Error: %s .", prefab.GetName().c_str(), result.GetError().c_str()); return; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 4658eea49f..40cd52cac8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -25,9 +25,9 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { AZ::DataStream::StreamType serializationFormat = m_serializationFormat == SerializationFormats::Binary ? AZ::DataStream::StreamType::ST_BINARY : AZ::DataStream::StreamType::ST_XML; - context.ListPrefabs([&context, serializationFormat](AZStd::string_view prefabName, PrefabDocument& prefab) + context.ListPrefabs([&context, serializationFormat](PrefabDocument& prefab) { - ProcessPrefab(context, prefabName, prefab, serializationFormat); + ProcessPrefab(context, prefab, serializationFormat); }); } @@ -45,12 +45,12 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } } - void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDocument& prefab, + void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, PrefabDocument& prefab, AZ::DataStream::StreamType serializationFormat) { using namespace AzToolsFramework::Prefab::SpawnableUtils; - AZStd::string uniqueName = prefabName; + AZStd::string uniqueName = prefab.GetName(); uniqueName += AzFramework::Spawnable::DotFileExtension; auto serializer = [serializationFormat](AZStd::vector& output, const ProcessedObjectStore& object) -> bool @@ -67,7 +67,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils Instance& instance = prefab.GetInstance(); // Resolve entity aliases that store PrefabDOM information to use the spawnable instead. This is done before the entities are // moved from the instance as they'd otherwise can't be found. - context.ResolveSpawnableEntityAliases(prefabName, *spawnable, instance); + context.ResolveSpawnableEntityAliases(prefab.GetName(), *spawnable, instance); AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities(); instance.DetachAllEntitiesInHierarchy( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h index a3556d73b7..39a94c86b8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h @@ -40,8 +40,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils static void Reflect(AZ::ReflectContext* context); protected: - static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDocument& prefab, - AZ::DataStream::StreamType serializationFormat); + static void ProcessPrefab(PrefabProcessorContext& context, PrefabDocument& prefab, AZ::DataStream::StreamType serializationFormat); SerializationFormats m_serializationFormat{ SerializationFormats::Binary }; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index 0fd428fa3b..2e8da9f9a1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -45,12 +45,12 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return false; } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) + void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) { m_isIterating = true; for (PrefabDocument& document : m_prefabs) { - callback(document.GetName(), document); + callback(document); } m_isIterating = false; @@ -60,11 +60,11 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils m_pendingPrefabAdditions.clear(); } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const + void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const { for (const PrefabDocument& document : m_prefabs) { - callback(document.GetName(), document); + callback(document); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index 8dde89b9e1..d07761271b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -46,8 +46,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual ~PrefabProcessorContext() = default; virtual bool AddPrefab(PrefabDocument&& document); - virtual void ListPrefabs(const AZStd::function& callback); - virtual void ListPrefabs(const AZStd::function& callback) const; + virtual void ListPrefabs(const AZStd::function& callback); + virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; virtual bool RegisterSpawnableProductAssetDependency( From a964120b7ad8edcd1c47181d13f06237e241989e Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:32:28 -0800 Subject: [PATCH 032/272] Updated the NetworkPrefabProcessor with the latest Prefab builder changes. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Pipeline/NetworkPrefabProcessor.cpp | 75 +++++++------------ .../Source/Pipeline/NetworkPrefabProcessor.h | 19 +++-- 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index 2a6baed411..a797523bc0 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -20,11 +20,10 @@ namespace Multiplayer { - using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessor; - using AzToolsFramework::Prefab::PrefabConversionUtils::ProcessedObjectStore; - - void NetworkPrefabProcessor::Process(PrefabProcessorContext& context) + void NetworkPrefabProcessor::Process(AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context) { + using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument; + IMultiplayerTools* mpTools = AZ::Interface::Get(); if (mpTools) { @@ -33,11 +32,17 @@ namespace Multiplayer AZ::DataStream::StreamType serializationFormat = GetAzSerializationFormat(); - context.ListPrefabs([&context, serializationFormat](AZStd::string_view prefabName, PrefabDom& prefab) { - ProcessPrefab(context, prefabName, prefab, serializationFormat); - }); + bool networkPrefabsAdded = false; + context.ListPrefabs( + [&networkPrefabsAdded, &context, serializationFormat](PrefabDocument& prefab) + { + if (ProcessPrefab(context, prefab, serializationFormat)) + { + networkPrefabsAdded = true; + } + }); - if (mpTools && !context.GetProcessedObjects().empty()) + if (mpTools && networkPrefabsAdded) { mpTools->SetDidProcessNetworkPrefabs(true); } @@ -59,28 +64,6 @@ namespace Multiplayer } } - static AZStd::unique_ptr LoadInstanceFromPrefab(const PrefabDom& prefab) - { - using namespace AzToolsFramework::Prefab; - - // convert Prefab DOM into Prefab Instance. - AZStd::unique_ptr sourceInstance(aznew Instance()); - if (!PrefabDomUtils::LoadInstanceFromPrefabDom(*sourceInstance, prefab, PrefabDomUtils::LoadFlags::AssignRandomEntityId)) - { - PrefabDomValueConstReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName); - - AZStd::string errorMessage("NetworkPrefabProcessor: Failed to Load Prefab Instance from given Prefab Dom."); - if (sourceReference.has_value() && sourceReference->get().IsString() && sourceReference->get().GetStringLength() != 0) - { - AZStd::string_view source(sourceReference->get().GetString(), sourceReference->get().GetStringLength()); - errorMessage += AZStd::string::format("Prefab Source: %.*s", AZ_STRING_ARG(source)); - } - AZ_Error("NetworkPrefabProcessor", false, errorMessage.c_str()); - return nullptr; - } - return sourceInstance; - } - static void GatherNetEntities( AzToolsFramework::Prefab::Instance* instance, AZStd::unordered_map& entityToInstanceMap, @@ -103,18 +86,15 @@ namespace Multiplayer }); } - void NetworkPrefabProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab, AZ::DataStream::StreamType serializationFormat) + bool NetworkPrefabProcessor::ProcessPrefab( + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context, + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument& prefab, + AZ::DataStream::StreamType serializationFormat) { + using AzToolsFramework::Prefab::PrefabConversionUtils::ProcessedObjectStore; using namespace AzToolsFramework::Prefab; - // convert Prefab DOM into Prefab Instance. - AZStd::unique_ptr sourceInstance = LoadInstanceFromPrefab(prefab); - if (!sourceInstance) - { - return; - } - - AZStd::string uniqueName = prefabName; + AZStd::string uniqueName = prefab.GetName(); uniqueName += ".network.spawnable"; auto serializer = [serializationFormat](AZStd::vector& output, const ProcessedObjectStore& object) -> bool { @@ -127,15 +107,16 @@ namespace Multiplayer ProcessedObjectStore::Create(uniqueName, context.GetSourceUuid(), AZStd::move(serializer)); auto& netSpawnableEntities = networkSpawnable->GetEntities(); + Instance& sourceInstance = prefab.GetInstance(); // Grab all net entities with their corresponding Instances to handle nested prefabs correctly AZStd::unordered_map netEntityToInstanceMap; AZStd::vector prefabNetEntities; - GatherNetEntities(sourceInstance.get(), netEntityToInstanceMap, prefabNetEntities); + GatherNetEntities(&sourceInstance, netEntityToInstanceMap, prefabNetEntities); if (prefabNetEntities.empty()) { // No networked entities in the prefab, no need to do anything in this processor. - return; + return false; } // Sort the entities prior to processing. The entities will end up in the net spawnable in this order. @@ -182,7 +163,7 @@ namespace Multiplayer // Add net spawnable asset holder to the prefab root { - EntityOptionalReference containerEntityRef = sourceInstance->GetContainerEntity(); + EntityOptionalReference containerEntityRef = sourceInstance.GetContainerEntity(); if (containerEntityRef.has_value()) { auto* networkSpawnableHolderComponent = containerEntityRef.value().get().CreateComponent(); @@ -193,18 +174,12 @@ namespace Multiplayer AZ::Entity* networkSpawnableHolderEntity = aznew AZ::Entity(uniqueName); auto* networkSpawnableHolderComponent = networkSpawnableHolderEntity->CreateComponent(); networkSpawnableHolderComponent->SetNetworkSpawnableAsset(networkSpawnableAsset); - sourceInstance->AddEntity(*networkSpawnableHolderEntity); + sourceInstance.AddEntity(*networkSpawnableHolderEntity); } } - // save the final result in the target Prefab DOM. - if (!PrefabDomUtils::StoreInstanceInPrefabDom(*sourceInstance, prefab)) - { - AZ_Error("NetworkPrefabProcessor", false, "Saving exported Prefab Instance within a Prefab Dom failed."); - return; - } - context.GetProcessedObjects().push_back(AZStd::move(object)); + return true; } AZ::DataStream::StreamType NetworkPrefabProcessor::GetAzSerializationFormat() const diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.h b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.h index 0fd3529db7..ef8912467d 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.h +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.h @@ -14,23 +14,23 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { class PrefabProcessorContext; + class PrefabDocument; } namespace Multiplayer { - using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessor; - using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext; - using AzToolsFramework::Prefab::PrefabDom; - - class NetworkPrefabProcessor : public PrefabProcessor + class NetworkPrefabProcessor : public AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessor { public: AZ_CLASS_ALLOCATOR(NetworkPrefabProcessor, AZ::SystemAllocator, 0); - AZ_RTTI(Multiplayer::NetworkPrefabProcessor, "{AF6C36DA-CBB9-4DF4-AE2D-7BC6CCE65176}", PrefabProcessor); + AZ_RTTI( + Multiplayer::NetworkPrefabProcessor, + "{AF6C36DA-CBB9-4DF4-AE2D-7BC6CCE65176}", + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessor); ~NetworkPrefabProcessor() override = default; - void Process(PrefabProcessorContext& context) override; + void Process(AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context) override; static void Reflect(AZ::ReflectContext* context); @@ -44,7 +44,10 @@ namespace Multiplayer AZ::DataStream::StreamType GetAzSerializationFormat() const; protected: - static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab, AZ::DataStream::StreamType serializationFormat); + static bool ProcessPrefab( + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context, + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument& prefab, + AZ::DataStream::StreamType serializationFormat); SerializationFormats m_serializationFormat = SerializationFormats::Binary; }; From 02137e2219944987fc3879bbd931b5c4045a91c8 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 15 Dec 2021 16:11:51 -0800 Subject: [PATCH 033/272] Fixed existing tests for Prefab processing. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Prefab/SpawnableRemoveEditorInfoTestFixture.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/SpawnableRemoveEditorInfoTestFixture.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/SpawnableRemoveEditorInfoTestFixture.cpp index b8ce3c7c42..0d75227e38 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/SpawnableRemoveEditorInfoTestFixture.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/SpawnableRemoveEditorInfoTestFixture.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -201,15 +202,14 @@ namespace UnitTest { ConvertSourceEntitiesToPrefab(); + AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument prefab("Test"); + prefab.SetPrefabDom(m_prefabDom); const bool actualResult = - m_editorInfoRemover.RemoveEditorInfo(m_prefabDom, m_serializeContext, m_prefabProcessorContext).IsSuccess(); + m_editorInfoRemover.RemoveEditorInfo(prefab, m_serializeContext, m_prefabProcessorContext).IsSuccess(); EXPECT_EQ(expectedResult, actualResult); - AZStd::unique_ptr convertedInstance(aznew Instance()); - ASSERT_TRUE(AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*convertedInstance, m_prefabDom)); - - convertedInstance->DetachAllEntitiesInHierarchy( + prefab.GetInstance().DetachAllEntitiesInHierarchy( [this](AZStd::unique_ptr entity) { m_runtimeEntities.emplace_back(entity.release()); From 1efbb7216f4bef0e3fd904c7289ee67938bb31b9 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 16 Dec 2021 10:51:11 -0800 Subject: [PATCH 034/272] Addressed issues found in/by the Spawnables benchmarks and unit tests. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Spawnable/SpawnableEntitiesInterface.h | 3 +++ .../Spawnable/SpawnableEntitiesManager.cpp | 25 +++++-------------- .../SpawnableEntitiesManagerTests.cpp | 4 +-- .../Spawnable/SpawnAllEntitiesBenchmarks.cpp | 9 ++++--- .../Code/Source/PrefabInstanceSpawner.cpp | 2 +- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h index dc9c7b4538..66197ae8fc 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,8 @@ namespace AzFramework public: friend class SpawnableEntitiesDefinition; + AZ_CLASS_ALLOCATOR(AzFramework::EntitySpawnTicket, AZ::SystemAllocator, 0); + using Id = uint32_t; EntitySpawnTicket() = default; diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp index 37570caec7..3406057fca 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp @@ -499,12 +499,8 @@ namespace AzFramework for (auto it = newEntitiesBegin; it != newEntitiesEnd; ++it) { AZ::Entity* clone = (*it); - // The entity component framework doesn't handle entities without TransformComponent safely. - if (!clone->GetComponents().empty()) - { - clone->SetSpawnTicketId(request.m_ticketId); - GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it); - } + clone->SetSpawnTicketId(request.m_ticketId); + GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone); } // Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context. @@ -636,12 +632,8 @@ namespace AzFramework for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it) { AZ::Entity* clone = (*it); - // The entity component framework doesn't handle entities without TransformComponent safely. - if (!clone->GetComponents().empty()) - { - clone->SetSpawnTicketId(request.m_ticketId); - GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it); - } + clone->SetSpawnTicketId(request.m_ticketId); + GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it); } if (request.m_completionCallback) @@ -668,7 +660,7 @@ namespace AzFramework { if (entity != nullptr) { - // Setting it to 0 is needed to avoid the infite loop between GameEntityContext and SpawnableEntitiesManager. + // Setting it to 0 is needed to avoid the infinite loop between GameEntityContext and SpawnableEntitiesManager. entity->SetSpawnTicketId(0); GameEntityContextRequestBus::Broadcast( &GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId()); @@ -702,7 +694,7 @@ namespace AzFramework { if (*entityIterator != nullptr && (*entityIterator)->GetId() == request.m_entityId) { - // Setting it to 0 is needed to avoid the infite loop between GameEntityContext and SpawnableEntitiesManager. + // Setting it to 0 is needed to avoid the infinite loop between GameEntityContext and SpawnableEntitiesManager. (*entityIterator)->SetSpawnTicketId(0); GameEntityContextRequestBus::Broadcast( &GameEntityContextRequestBus::Events::DestroyGameEntity, (*entityIterator)->GetId()); @@ -949,11 +941,6 @@ namespace AzFramework GameEntityContextRequestBus::Broadcast( &GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId()); } - else - { - // Entities without components wouldn't have been send to the GameEntityContext. - delete entity; - } } delete request.m_ticket; diff --git a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp index 0dc00f81dd..d39bfed1e2 100644 --- a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp +++ b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp @@ -111,7 +111,7 @@ namespace UnitTest m_spawnable = aznew AzFramework::Spawnable( AZ::Data::AssetId::CreateString("{EB2E8A2B-F253-4A90-BBF4-55F2EED786B8}:0"), AZ::Data::AssetData::AssetStatus::Ready); m_spawnableAsset = new AZ::Data::Asset(m_spawnable, AZ::Data::AssetLoadBehavior::Default); - m_ticket = new AzFramework::EntitySpawnTicket(*m_spawnableAsset); + m_ticket = aznew AzFramework::EntitySpawnTicket(*m_spawnableAsset); auto managerInterface = AzFramework::SpawnableEntitiesInterface::Get(); m_manager = azrtti_cast(managerInterface); @@ -516,7 +516,7 @@ namespace UnitTest // Make sure we start with a fresh ticket each time, or else each iteration through this loop would continue to build up // more and more entities. delete m_ticket; - m_ticket = new AzFramework::EntitySpawnTicket(*m_spawnableAsset); + m_ticket = aznew AzFramework::EntitySpawnTicket(*m_spawnableAsset); constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp index ecbbe10c39..ba0c3a4838 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp @@ -25,7 +25,7 @@ namespace Benchmark for (auto _ : state) { state.PauseTiming(); - m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset); + m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); state.ResumeTiming(); for (uint64_t spwanableCounter = 0; spwanableCounter < spawnAllEntitiesCallCount; spwanableCounter++) @@ -62,7 +62,7 @@ namespace Benchmark for (auto _ : state) { state.PauseTiming(); - m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset); + m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); state.ResumeTiming(); AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*m_spawnTicket); @@ -93,15 +93,16 @@ namespace Benchmark SetUpSpawnableAsset(entityCountInSpawnable); + auto spawner = AzFramework::SpawnableEntitiesInterface::Get(); for (auto _ : state) { state.PauseTiming(); - m_spawnTicket = new AzFramework::EntitySpawnTicket(m_spawnableAsset); + m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); state.ResumeTiming(); for (uint64_t spawnCallCounter = 0; spawnCallCounter < spawnCallCount; spawnCallCounter++) { - AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*m_spawnTicket); + spawner->SpawnAllEntities(*m_spawnTicket); } m_rootSpawnableInterface->ProcessSpawnableQueue(); diff --git a/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp index b386f17cab..c7c0ef5d3d 100644 --- a/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp +++ b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp @@ -342,7 +342,7 @@ namespace Vegetation // Create the EntitySpawnTicket here. This pointer is going to get handed off to the vegetation system as opaque instance data, // where it will be tracked and held onto for the lifetime of the vegetation instance. The vegetation system will pass it back // in to DestroyInstance at the end of the lifetime, so that's the one place where we will delete the ticket pointers. - AzFramework::EntitySpawnTicket* ticket = new AzFramework::EntitySpawnTicket(m_spawnableAsset); + AzFramework::EntitySpawnTicket* ticket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); if (ticket->IsValid()) { // Track the ticket that we've created. From e8366040dfb25515bf2f007377171cb40c55bf60 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 16 Dec 2021 15:30:36 -0800 Subject: [PATCH 035/272] Added unit test to cover the updates to the Spawnable Entities Aliases. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../SpawnableEntitiesManagerTests.cpp | 152 +++++++++++++++--- 1 file changed, 134 insertions(+), 18 deletions(-) diff --git a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp index d39bfed1e2..1a483a7851 100644 --- a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp +++ b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp @@ -77,6 +77,12 @@ namespace UnitTest public: AZ_COMPONENT(TargetSpawnableComponent, "{B4041561-63A7-4E1E-80F1-78C08D497960}"); + TargetSpawnableComponent() = default; + explicit TargetSpawnableComponent(AZ::EntityId parent) + : m_parent(parent) + { + } + void Activate() override {} void Deactivate() override {} @@ -84,9 +90,12 @@ namespace UnitTest { if (auto* serializeContext = azrtti_cast(reflection)) { - serializeContext->Class(); + serializeContext->Class() + ->Field("Parent", &TargetSpawnableComponent::m_parent); } } + + AZ::EntityId m_parent; }; class SpawnableEntitiesManagerTest : public AllocatorsFixture @@ -147,22 +156,43 @@ namespace UnitTest { auto entry = AZStd::make_unique(); entry->AddComponent(aznew SourceSpawnableComponent()); + entry->SetId(AZ::EntityId(40 + i)); entities.push_back(AZStd::move(entry)); } } - AZ::Data::Asset CreateTargetSpawnable(size_t numElements) + AZ::Data::Asset CreateTargetSpawnable(size_t numElements, bool requiresMatchingEntityIds) { auto target = aznew AzFramework::Spawnable( AZ::Data::AssetId(AZ::Uuid("{716CD8C3-0BA8-4F32-B579-0EC7C967796F}")), AZ::Data::AssetData::AssetStatus::Ready); AzFramework::Spawnable::EntityList& entities = target->GetEntities(); entities.reserve(numElements); - for (size_t i = 0; i < numElements; ++i) + if (requiresMatchingEntityIds) { - auto entry = AZStd::make_unique(); - entry->AddComponent(aznew TargetSpawnableComponent()); - entities.push_back(AZStd::move(entry)); + for (size_t i = 0; i < numElements; ++i) + { + auto entry = AZStd::make_unique(); + if (i != 0) + { + entry->AddComponent(aznew TargetSpawnableComponent(AZ::EntityId(40 + i - 1))); + } + else + { + entry->AddComponent(aznew TargetSpawnableComponent()); + } + entry->SetId(AZ::EntityId(40 + i)); + entities.push_back(AZStd::move(entry)); + } + } + else + { + for (size_t i = 0; i < numElements; ++i) + { + auto entry = AZStd::make_unique(); + entry->AddComponent(aznew TargetSpawnableComponent()); + entities.push_back(AZStd::move(entry)); + } } return AZ::Data::Asset(target, AZ::Data::AssetLoadBehavior::NoLoad); @@ -212,6 +242,38 @@ namespace UnitTest return true; } + static bool DoParentEntityIdsMatch(AzFramework::SpawnableConstEntityContainerView entities) + { + if (entities.empty()) + { + return false; + } + + const AZ::Entity* previous = nullptr; + for (const AZ::Entity* entity : entities) + { + if (entity) + { + if (previous) + { + if (TargetSpawnableComponent* link = entity->FindComponent(); link != nullptr) + { + if (link->m_parent != previous->GetId()) + { + return false; + } + } + previous = entity; + } + } + else + { + return false; + } + } + return true; + } + static bool IsEveryOtherEntityAReplacement(AzFramework::SpawnableConstEntityContainerView entities) { bool onAlternative = true; @@ -599,7 +661,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = true; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, @@ -608,11 +671,13 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allReplaced = false; - auto callback = [&spawnedEntitiesCount, &allReplaced]( + bool allEntityIdsPatched = false; + auto callback = [&spawnedEntitiesCount, &allReplaced, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allReplaced = AreAllEntitiesReplaced(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -621,6 +686,7 @@ namespace UnitTest EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_TRUE(allReplaced); + EXPECT_TRUE(allEntityIdsPatched); } TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged) @@ -628,7 +694,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = false; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, @@ -637,11 +704,13 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allAdded = false; - auto callback = [&spawnedEntitiesCount, &allAdded]( + bool allEntityIdsPatched = false; + auto callback = [&spawnedEntitiesCount, &allAdded, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allAdded = IsEveryOtherEntityAReplacement(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -650,6 +719,7 @@ namespace UnitTest EXPECT_EQ(8, spawnedEntitiesCount); EXPECT_TRUE(allAdded); + EXPECT_TRUE(allEntityIdsPatched); } TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged) @@ -657,7 +727,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = true; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, @@ -666,11 +737,13 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allMerged = false; - auto callback = [&spawnedEntitiesCount, &allMerged]( + bool allEntityIdsPatched = false; + auto callback = [&spawnedEntitiesCount, &allMerged, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allMerged = AreAllMerged(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -679,6 +752,7 @@ namespace UnitTest EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_TRUE(allMerged); + EXPECT_TRUE(allEntityIdsPatched); } // @@ -1095,7 +1169,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = true; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, @@ -1106,11 +1181,13 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allReplaced = false; - auto callback = [&spawnedEntitiesCount, &allReplaced]( + bool allEntityIdsPatched = false; + auto callback = [&spawnedEntitiesCount, &allReplaced, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allReplaced = AreAllEntitiesReplaced(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -1119,6 +1196,7 @@ namespace UnitTest EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_TRUE(allReplaced); + EXPECT_TRUE(allEntityIdsPatched); } TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged) @@ -1126,7 +1204,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = false; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, @@ -1137,12 +1216,14 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allAdded = false; + bool allEntityIdsPatched = false; auto callback = - [&spawnedEntitiesCount, &allAdded]( + [&spawnedEntitiesCount, &allAdded, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allAdded = IsEveryOtherEntityAReplacement(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -1151,6 +1232,7 @@ namespace UnitTest EXPECT_EQ(8, spawnedEntitiesCount); EXPECT_TRUE(allAdded); + EXPECT_TRUE(allEntityIdsPatched); } TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged) @@ -1158,7 +1240,8 @@ namespace UnitTest using namespace AzFramework; static constexpr size_t NumEntities = 4; FillSpawnable(NumEntities); - AZ::Data::Asset target = CreateTargetSpawnable(4); + constexpr bool requiresMatchingEntityIds = true; + AZ::Data::Asset target = CreateTargetSpawnable(4, requiresMatchingEntityIds); InsertEntityAliases<4>( { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, @@ -1169,11 +1252,13 @@ namespace UnitTest size_t spawnedEntitiesCount = 0; bool allMerged = false; - auto callback = [&spawnedEntitiesCount, &allMerged]( + bool allEntityIdsPatched = false; + auto callback = [&spawnedEntitiesCount, &allMerged, &allEntityIdsPatched]( AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) { spawnedEntitiesCount += entities.size(); allMerged = AreAllMerged(entities); + allEntityIdsPatched = DoParentEntityIdsMatch(entities); }; AzFramework::SpawnEntitiesOptionalArgs optionalArgs; optionalArgs.m_completionCallback = AZStd::move(callback); @@ -1182,6 +1267,7 @@ namespace UnitTest EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_TRUE(allMerged); + EXPECT_TRUE(allEntityIdsPatched); } // @@ -1302,6 +1388,36 @@ namespace UnitTest // ClaimEntities // + TEST_F(SpawnableEntitiesManagerTest, ClaimEntities_Call_AllEntitiesWereClaimedAndNotDeleted) + { + static constexpr size_t NumEntities = 4; + FillSpawnable(NumEntities); + + AZStd::vector claimedEntities; + auto callback = [&claimedEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableEntityContainerView container) + { + for (AZ::Entity* entity : container) + { + claimedEntities.push_back(entity); + } + }; + + { + AzFramework::EntitySpawnTicket ticket(*m_spawnableAsset); + m_manager->SpawnAllEntities(ticket); + m_manager->ClaimEntities(ticket, AZStd::move(callback)); + m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular); + } + + EXPECT_EQ(NumEntities, claimedEntities.size()); + + // If these calls fail it means that the ticket has still deleted the entities, so they weren't properly claimed. + for (AZ::Entity* entity : claimedEntities) + { + delete entity; + } + } + TEST_F(SpawnableEntitiesManagerTest, ClaimEntities_DeleteTicketBeforeCall_NoCrash) { auto callback = [](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableEntityContainerView) {}; From 34edd4d0c011cb184ffe8ba7a5734708d6540d08 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 16 Dec 2021 18:06:25 -0800 Subject: [PATCH 036/272] Fixed post rebase Spawnable issues. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp index 553ad8ece4..dc5cd299b8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp @@ -112,9 +112,9 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils // Use a random uuid as this is only a temporary source. PrefabConversionUtils::PrefabProcessorContext context(AZ::Uuid::CreateRandom()); - PrefabDom copy; - copy.CopyFrom(templateReference->get().GetPrefabDom(), copy.GetAllocator(), false); - context.AddPrefab(spawnableName, AZStd::move(copy)); + PrefabDocument document(spawnableName); + document.SetPrefabDom(templateReference->get().GetPrefabDom()); + context.AddPrefab(AZStd::move(document)); m_converter.ProcessPrefab(context); if (!context.HasCompletedSuccessfully() || context.GetProcessedObjects().empty()) From 9b5dcf82b5972037daf9f114e79dee6618de88e7 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 16 Dec 2021 20:46:12 -0800 Subject: [PATCH 037/272] updates extend editor_entity_utils.py functionality Signed-off-by: Scott Murray --- .../editor_entity_utils.py | 200 +++++++++++++++--- 1 file changed, 172 insertions(+), 28 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 72530325e0..b9f7576f1c 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -29,6 +29,11 @@ class EditorComponent: which also assigns self.id and self.type_id to the EditorComponent object. """ + def __init__(self, type_id): + self.type_id = type_id + self.id = None + self.property_tree = None + def get_component_name(self) -> str: """ Used to get name of component @@ -50,6 +55,9 @@ class EditorComponent: 7. prop_tree.get_container_item(path, key) :return: Property tree object of a component """ + if self.property_tree is not None: + return self.property_tree + build_prop_tree_outcome = editor.EditorComponentAPIBus( bus.Broadcast, "BuildComponentPropertyTreeEditor", self.id ) @@ -58,7 +66,114 @@ class EditorComponent: ), f"Failure: Could not build property tree of component: '{self.get_component_name()}'" prop_tree = build_prop_tree_outcome.GetValue() Report.info(prop_tree.build_paths_list()) - return prop_tree + self.property_tree = prop_tree + return self.property_tree + + def is_property_container(self, component_property_path: str) -> bool: + """ + + """ + if self.property_tree is None: + self.get_property_tree() + result = self.property_tree.is_container(component_property_path) + if not result: + Report.info(f"{self.get_component_name()}: '{component_property_path}' is not a container") + return result + + def get_container_count(self, component_property_path: str) -> int: + """ + Used to get the count of items in the container. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :return: Count of items in the container as unsigned integer + """ + if self.is_property_container(component_property_path): + container_count_outcome = self.property_tree.get_container_count(component_property_path) + assert ( + container_count_outcome.IsSuccess() + ), f"Failure: get_container_count did not return success for '{component_property_path}'" + return container_count_outcome.GetValue() + + def reset_container(self, component_property_path: str) -> bool: + """ + Used to rest a container to empty + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :return: Boolean success + """ + if self.is_property_container(component_property_path): + reset_outcome = self.property_tree.reset_container(component_property_path) + return reset_outcome.IsSuccess() + else: + return False + + def append_container_item(self, component_property_path: str, value: any) -> bool: + """ + Used to append a container item without providing an index key. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :param value: Value to be set + :return: Boolean success + """ + if self.is_property_container(component_property_path): + append_outcome = self.property_tree.append_container_item(component_property_path, value) + return append_outcome.IsSuccess() + else: + return False + + def add_container_item(self, component_property_path: str, key: any, value: any) -> bool: + """ + Used to add a container item at a specified key. In practice key should be an integer index. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :param key: Zero index integer key, although this could be any unique unused key value + :param value: Value to be set + :return: Boolean success + """ + if self.is_property_container(component_property_path): + add_outcome = self.property_tree.add_container_item(component_property_path, key, value) + return add_outcome.IsSuccess() + else: + return False + + def get_container_item(self, component_property_path: str, key: any) -> any: + """ + Used to retrieve a container item value at the specified key. In practice key should be an integer index. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :param key: Zero index integer key + :return: Value stored at the key specified + """ + if self.is_property_container(component_property_path): + get_outcome = self.property_tree.get_container_item(component_property_path, key) + assert ( + get_outcome.IsSuccess() + ), f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]" + return get_outcome.GetValue() + else: + return None + + def remove_container_item(self, component_property_path: str, key: any) -> bool: + """ + Used to remove a container item value at the specified key. In practice key should be an integer index. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :param key: Zero index integer key + :return: Boolean success + """ + if self.is_property_container(component_property_path): + remove_outcome = self.property_tree.remove_container_item(component_property_path, key) + return remove_outcome.IsSuccess() + else: + return False + + def update_container_item(self, component_property_path: str, key: any, value: any): + """ + Used to update a container item at a specified key. In practice key should be an integer index. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :param key: Zero index integer key + :param value: Value to be set + :return: Boolean success + """ + if self.is_property_container(component_property_path): + update_outcome = self.property_tree.update_container_item(component_property_path, key, value) + return update_outcome.IsSuccess() + else: + return False def get_component_property_value(self, component_property_path: str): """ @@ -101,16 +216,25 @@ class EditorComponent: """ editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) + def enable_component(self): + """ + used to enable the componet using its id value + """ + editor.EditorComponentAPIBus(bus.Broadcast, "EnabledComponents", [self.id]) + @staticmethod - def get_type_ids(component_names: list) -> list: + def get_type_ids(component_names: list, entity_type: str ='Game') -> list: """ Used to get type ids of given components list :param: component_names: List of components to get type ids :return: List of type ids of given components. """ + if entity_type.lower() == 'level': + entity_type = azlmbr.entity.EntityType().Level + else: + entity_type = azlmbr.entity.EntityType().Game type_ids = editor.EditorComponentAPIBus( - bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Game - ) + bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, entity_type) return type_ids @@ -278,8 +402,7 @@ class EditorEntity: components = [] type_ids = EditorComponent.get_type_ids(component_names) for type_id in type_ids: - new_comp = EditorComponent() - new_comp.type_id = type_id + new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorComponentAPIBus( bus.Broadcast, "AddComponentsOfType", self.id, [type_id] ) @@ -291,6 +414,27 @@ class EditorEntity: self.components.append(new_comp) return components + def remove_component(self, component_name: str) -> None: + """ + Used to remove a component from Entity + :param component_name: String of component name to remove + :return: None + """ + self.remove_components([component_name]) + + def remove_components(self, component_names: list): + """ + Used to remove a list of components from Entity + :param component_names: List of component names to remove + :return: None + """ + type_ids = EditorComponent.get_type_ids(component_names) + for type_id in type_ids: + remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id]) + assert ( + remove_outcome.IsSuccess() + ), f"Failure: could not remove component from '{self.get_name()}'" + def get_components_of_type(self, component_names: list) -> List[EditorComponent]: """ Used to get components of type component_name that already exists on Entity @@ -300,8 +444,7 @@ class EditorEntity: component_list = [] type_ids = EditorComponent.get_type_ids(component_names) for type_id in type_ids: - component = EditorComponent() - component.type_id = type_id + component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorComponentAPIBus( bus.Broadcast, "GetComponentOfType", self.id, type_id ) @@ -359,6 +502,21 @@ class EditorEntity: set_status = self.get_start_status() assert set_status == status_to_set, f"Failed to set start status of {desired_start_status} to {self.get_name}" + def is_locked(self) -> bool: + """ + Used to get the locked status of the entity + :return: Boolean True if locked False if not locked + """ + return editor.EditorEntityInfoRequestBus(bus.Event, "IsLocked", self.id) + + def set_lock_state(self, is_locked: bool) -> None: + """ + Sets the lock state on the object to locked or not locked. + :param is_locked: True for locking, False to unlock. + :return: None + """ + editor.EditorEntityAPIBus(bus.Event, "SetLockState", self.id, is_locked) + def delete(self) -> None: """ Used to delete the Entity. @@ -488,18 +646,6 @@ class EditorLevelEntity: EditorLevelComponentAPIBus requests. """ - @staticmethod - def get_type_ids(component_names: list) -> list: - """ - Used to get type ids of given components list for EntityType Level - :param: component_names: List of components to get type ids - :return: List of type ids of given components. - """ - type_ids = editor.EditorComponentAPIBus( - bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Level - ) - return type_ids - @staticmethod def add_component(component_name: str) -> EditorComponent: """ @@ -518,10 +664,9 @@ class EditorLevelEntity: :return: List of newly added components to the level """ components = [] - type_ids = EditorLevelEntity.get_type_ids(component_names) + type_ids = EditorComponent.get_type_ids(component_names, 'level') for type_id in type_ids: - new_comp = EditorComponent() - new_comp.type_id = type_id + new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorLevelComponentAPIBus( bus.Broadcast, "AddComponentsOfType", [type_id] ) @@ -540,10 +685,9 @@ class EditorLevelEntity: :return: List of Level Component objects of given component name """ component_list = [] - type_ids = EditorLevelEntity.get_type_ids(component_names) + type_ids = EditorComponent.get_type_ids(component_names, 'level') for type_id in type_ids: - component = EditorComponent() - component.type_id = type_id + component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorLevelComponentAPIBus( bus.Broadcast, "GetComponentOfType", type_id ) @@ -562,7 +706,7 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: True, if level has specified component. Else, False """ - type_ids = EditorLevelEntity.get_type_ids([component_name]) + type_ids = EditorComponent.get_type_ids([component_name], 'level') return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0]) @staticmethod @@ -572,5 +716,5 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: integer count of occurences of level component attached to level or zero if none are present """ - type_ids = EditorLevelEntity.get_type_ids([component_name]) + type_ids = EditorComponent.get_type_ids([component_name], 'level') return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0]) From 291e172f9e13285f4e5c6a90eea7740a804ab88a Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 16 Dec 2021 21:01:39 -0800 Subject: [PATCH 038/272] fixing some docstrings Signed-off-by: Scott Murray --- .../editor_python_test_tools/editor_entity_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index b9f7576f1c..58d9e30f81 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -71,7 +71,9 @@ class EditorComponent: def is_property_container(self, component_property_path: str) -> bool: """ - + Used to determine if a component property is a container. Containers are similar to a dictionary with int keys. + :param component_property_path: String of component property. (e.g. 'Settings|Visible') + :return: Boolean True if the property is a container False if it is not. """ if self.property_tree is None: self.get_property_tree() @@ -255,7 +257,7 @@ class EditorEntity: """ Entity class is used to create and interact with Editor Entities. Example: To create Editor Entity, Use the code: - test_entity = Entity.create_editor_entity("TestEntity") + test_entity = EditorEntity.create_editor_entity("TestEntity") # This creates a python object with 'test_entity' linked to entity name "TestEntity" in Editor. # To add component, use: test_entity.add_component() From 4245bf7ac97b01a97f43806cb4f68873bbd677ed Mon Sep 17 00:00:00 2001 From: Tobias Alexander Franke Date: Tue, 7 Dec 2021 17:00:52 +0800 Subject: [PATCH 039/272] Notify relative component to acquire wind information when the tag of global wind and local wind in PhysX configuration changes. Signed-off-by: T.J. McGrath-Daly --- Gems/PhysX/Code/Source/WindProvider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/PhysX/Code/Source/WindProvider.cpp b/Gems/PhysX/Code/Source/WindProvider.cpp index 3090cea062..c7d5d0863b 100644 --- a/Gems/PhysX/Code/Source/WindProvider.cpp +++ b/Gems/PhysX/Code/Source/WindProvider.cpp @@ -177,7 +177,7 @@ namespace PhysX AZStd::vector m_entityTransformHandlers; AZStd::vector m_pendingAabbUpdates; ChangeCallback m_changeCallback; - bool m_changed = false; + bool m_changed = true; }; WindProvider::WindProvider() From bbd00adadeaf315a615b1e08259f44763a5272fb Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 20 Dec 2021 16:54:06 -0800 Subject: [PATCH 040/272] Address some AZ::Dom::Value feedback - Use a vector for shared string storage (to avoid the double heap allocation for AZStd::string) - Use a shared heap allocated any for opaque types (instead of an unsafe ref) - Add a string comparison key lookup benchmark to measure the impact of Name Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 49 ++++++++------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 59 +++++++++---------- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 2 +- .../AzCore/AzCore/DOM/DomValueWriter.h | 2 +- .../AzCore/AzCore/DOM/DomVisitor.cpp | 4 +- Code/Framework/AzCore/AzCore/DOM/DomVisitor.h | 5 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 29 +++++++++ 7 files changed, 91 insertions(+), 59 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index dcecc67460..3dafc02c6e 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -19,7 +19,7 @@ namespace AZ::Dom { if (refCountedPointer.use_count() > 1) { - AZStd::shared_ptr newPointer = AZStd::allocate_shared(AZStdAlloc()); + AZStd::shared_ptr newPointer = AZStd::allocate_shared(StdValueAllocator()); *newPointer = *refCountedPointer; refCountedPointer = AZStd::move(newPointer); } @@ -92,12 +92,12 @@ namespace AZ::Dom } } - Value::Value(AZStd::any* value) - : m_value(value) + Value::Value(const AZStd::any& value) + : m_value(AZStd::allocate_shared(StdValueAllocator(), value)) { } - Value Value::FromOpaqueValue(AZStd::any& value) + Value Value::FromOpaqueValue(const AZStd::any& value) { return Value(&value); } @@ -330,7 +330,7 @@ namespace AZ::Dom Value& Value::SetObject() { - m_value = AZStd::allocate_shared(AZStdAlloc()); + m_value = AZStd::allocate_shared(StdValueAllocator()); return *this; } @@ -634,7 +634,7 @@ namespace AZ::Dom Value& Value::SetArray() { - m_value = AZStd::allocate_shared(AZStdAlloc()); + m_value = AZStd::allocate_shared(StdValueAllocator()); return *this; } @@ -740,7 +740,7 @@ namespace AZ::Dom void Value::SetNode(AZ::Name name) { - m_value = AZStd::allocate_shared(AZStdAlloc(), name); + m_value = AZStd::allocate_shared(StdValueAllocator(), name); } void Value::SetNode(AZStd::string_view name) @@ -914,9 +914,9 @@ namespace AZ::Dom m_value = aznumeric_cast(value); } - void Value::SetString(AZStd::shared_ptr string) + void Value::SetString(SharedStringType sharedString) { - m_value = string; + m_value = sharedString; } AZStd::string_view Value::GetString() const @@ -925,12 +925,15 @@ namespace AZ::Dom { case 5: // AZStd::string_view return AZStd::get(m_value); - case 6: // AZStd::shared_ptr - return *AZStd::get>(m_value); + case 6: // AZStd::shared_ptr> + { + auto& buffer = *AZStd::get(m_value); + return { buffer.data(), buffer.size() }; + } case 7: // ShortStringType { - const ShortStringType& ShortString = AZStd::get(m_value); - return { ShortString.m_data.data(), ShortString.m_size }; + const ShortStringType& shortString = AZStd::get(m_value); + return { shortString.data(), shortString.size() }; } } AZ_Assert(false, "AZ::Dom::Value: Called GetString on a non-string type"); @@ -947,8 +950,8 @@ namespace AZ::Dom if (value.size() <= ShortStringSize) { ShortStringType buffer; - buffer.m_size = value.size(); - memcpy(buffer.m_data.data(), value.data(), buffer.m_size); + buffer.resize_no_construct(value.size()); + memcpy(buffer.data(), value.data(), value.size()); m_value = buffer; } m_value = value; @@ -962,18 +965,20 @@ namespace AZ::Dom } else { - m_value = AZStd::allocate_shared(AZStdAlloc(), value); + SharedStringType sharedString = + AZStd::allocate_shared(StdValueAllocator(), value.begin(), value.end()); + m_value = AZStd::move(sharedString); } } - AZStd::any& Value::GetOpaqueValue() const + const AZStd::any& Value::GetOpaqueValue() const { - return *AZStd::get(m_value); + return *AZStd::get>(m_value); } - void Value::SetOpaqueValue(AZStd::any& value) + void Value::SetOpaqueValue(const AZStd::any& value) { - m_value = &value; + m_value = AZStd::allocate_shared(StdValueAllocator(), value); } void Value::SetNull() @@ -1014,7 +1019,7 @@ namespace AZ::Dom { result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } - else if constexpr (AZStd::is_same_v>) + else if constexpr (AZStd::is_same_v) { result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } @@ -1110,7 +1115,7 @@ namespace AZ::Dom if (IsString() && other.IsString()) { // If we both hold the same ref counted string we don't need to do a full comparison - if (AZStd::holds_alternative>(m_value) && m_value == other.m_value) + if (AZStd::holds_alternative(m_value) && m_value == other.m_value) { return true; } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 1b69c73ecc..bc1b790009 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -55,13 +55,15 @@ namespace AZ::Dom } }; + using StdValueAllocator = AZStdAlloc; + class Value; //! Internal storage for a Value array: an ordered list of Values. class Array { public: - using ContainerType = AZStd::vector>; + using ContainerType = AZStd::vector; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 4; @@ -80,7 +82,7 @@ namespace AZ::Dom { public: using EntryType = AZStd::pair; - using ContainerType = AZStd::vector>; + using ContainerType = AZStd::vector; using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 8; @@ -150,6 +152,13 @@ namespace AZ::Dom class Value final { public: + // Determine the short string buffer size based on the size of our largest internal type (string_view) + // minus the size of the short string size field. + static constexpr const size_t ShortStringSize = sizeof(AZStd::string_view) - 2; + using ShortStringType = AZStd::fixed_string; + using SharedStringContainer = AZStd::vector; + using SharedStringType = AZStd::shared_ptr; + // Constructors... Value(); Value(const Value&); @@ -167,7 +176,7 @@ namespace AZ::Dom explicit Value(Type type); - static Value FromOpaqueValue(AZStd::any& value); + static Value FromOpaqueValue(const AZStd::any& value); // Equality / comparison / swap... Value& operator=(const Value&); @@ -306,17 +315,17 @@ namespace AZ::Dom AZStd::string_view GetString() const; size_t GetStringLength() const; void SetString(AZStd::string_view); - void SetString(AZStd::shared_ptr); + void SetString(SharedStringType sharedString); void CopyFromString(AZStd::string_view); // Opaque type API... - AZStd::any& GetOpaqueValue() const; + const AZStd::any& GetOpaqueValue() const; //! This sets this Value to represent a value of an type that the DOM has //! no formal knowledge of. Where possible, it should be preferred to //! serialize an opaque type into a DOM value instead, as serializers //! and other systems will have no means of dealing with fully arbitrary //! values. - void SetOpaqueValue(AZStd::any&); + void SetOpaqueValue(const AZStd::any&); // Null API... void SetNull(); @@ -336,49 +345,37 @@ namespace AZ::Dom const Array::ContainerType& GetArrayInternal() const; Array::ContainerType& GetArrayInternal(); - explicit Value(AZStd::any* opaqueValue); - - // Determine the short string buffer size based on the size of our largest internal type (string_view) - // minus the size of the short string size field. - static constexpr const size_t ShortStringSize = sizeof(AZStd::string_view) - sizeof(size_t); - struct ShortStringType - { - AZStd::array m_data; - size_t m_size; - - bool operator==(const ShortStringType& other) const - { - return m_size == other.m_size ? memcmp(m_data.data(), other.m_data.data(), m_size) == 0 : false; - } - }; + explicit Value(const AZStd::any& opaqueValue); //! The internal storage type for Value. //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes //! for the same type in some instances, such as string storage. using ValueType = AZStd::variant< - // NullType + // Null AZStd::monostate, - // NumberType + // Int64 int64_t, + // Uint64 uint64_t, + // Double double, - // FalseType & TrueType + // Bool bool, // StringType AZStd::string_view, - AZStd::shared_ptr, + SharedStringType, ShortStringType, - // ObjectType + // Object ObjectPtr, - // ArrayType + // Array ArrayPtr, - // NodeType + // Node NodePtr, - // OpaqueType - AZStd::any*>; + // Opaque + AZStd::shared_ptr>; static_assert( - sizeof(ValueType) == sizeof(AZStd::variant), "ValueType should have no members larger than ShortStringType"); + sizeof(ValueType) == sizeof(ShortStringType) + sizeof(size_t), "ValueType should have no members larger than ShortStringType"); ValueType m_value; }; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 172f7f2a92..9b814b1bff 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -68,7 +68,7 @@ namespace AZ::Dom return FinishWrite(); } - Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr value, [[maybe_unused]] Lifetime lifetime) + Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr> value, [[maybe_unused]] Lifetime lifetime) { CurrentValue().SetString(value); return FinishWrite(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h index 488535ace6..4fdea293eb 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h @@ -28,7 +28,7 @@ namespace AZ::Dom Result Double(double value) override; Result String(AZStd::string_view value, Lifetime lifetime) override; - Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) override; + Result RefCountedString(AZStd::shared_ptr> value, Lifetime lifetime) override; Result StartObject() override; Result EndObject(AZ::u64 attributeCount) override; Result Key(AZ::Name key) override; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp index 4e13a2a95c..0da4bcd5d3 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp @@ -105,9 +105,9 @@ namespace AZ::Dom return VisitorSuccess(); } - Visitor::Result Visitor::RefCountedString(AZStd::shared_ptr value, Lifetime lifetime) + Visitor::Result Visitor::RefCountedString(AZStd::shared_ptr> value, Lifetime lifetime) { - return String(*value, lifetime); + return String({ value->data(), value->size() }, lifetime); } Visitor::Result Visitor::OpaqueValue([[maybe_unused]] OpaqueType& value) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h index 3bf1b3419b..f9930f93c6 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h @@ -11,8 +11,9 @@ #include #include #include -#include +#include #include +#include namespace AZ::Dom { @@ -176,7 +177,7 @@ namespace AZ::Dom //! Operates on a ref-counted string value. S //! \param lifetime Specifies the lifetime of this string. If the string has a temporary lifetime, it may not //! be safely stored as a reference, but may still be safely stored as a ref-counted shared_ptr. - virtual Result RefCountedString(AZStd::shared_ptr value, Lifetime lifetime); + virtual Result RefCountedString(AZStd::shared_ptr> value, Lifetime lifetime); //! Operates on an opaque value. As opaque values are a reference type, storage semantics are provided to //! indicate where the value may be stored persistently or requires a copy. //! The base implementation of OpaqueValue rejects the operation, as opaque values are meant for special diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 51d2e5c10c..af5b367d63 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -220,4 +220,33 @@ namespace AZ::Dom::Benchmark } BENCHMARK_REGISTER_F(DomValueBenchmark, LookupMemberByString)->Arg(100)->Arg(1000)->Arg(10000)->Unit(benchmark::kMillisecond); + BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByStringComparison)(benchmark::State& state) + { + Value value(Type::Object); + AZStd::vector keys; + for (int64_t i = 0; i < state.range(0); ++i) + { + AZStd::string key(AZStd::string::format("key%" PRId64, i)); + keys.push_back(key); + value[key] = i; + } + + for (auto _ : state) + { + for (const AZStd::string& key : keys) + { + const Object::ContainerType& object = value.GetObject(); + benchmark::DoNotOptimize(AZStd::find_if( + object.cbegin(), object.cend(), + [&key](const Object::EntryType& entry) + { + return key == entry.first.GetStringView(); + })); + } + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, LookupMemberByStringComparison)->Arg(100)->Arg(1000)->Arg(10000)->Unit(benchmark::kMillisecond); + } // namespace AZ::Dom::Benchmark From 1da99eaea02874f22c1fde8df07e7e730dbd3c6a Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 20 Dec 2021 18:27:00 -0800 Subject: [PATCH 041/272] Add type-safe GetTypeIndex instead of hardcoded index lookups Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 96 ++++++++++++++----- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 54 +++++------ 2 files changed, 97 insertions(+), 53 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 3dafc02c6e..3836568f37 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -26,6 +26,51 @@ namespace AZ::Dom return refCountedPointer; } + namespace Internal + { + template + constexpr size_t GetTypeIndexInternal(size_t index = 0) + { + static_assert(false, "Type not found in ValueType"); + return index; + } + + template + constexpr size_t GetTypeIndexInternal(size_t index = 0) + { + if constexpr (AZStd::is_same_v) + { + return index; + } + else + { + return GetTypeIndexInternal(index + 1); + } + } + + template + struct ExtractTypeArgs + { + }; + + template class TypeToExtract, typename... Args> + struct ExtractTypeArgs> + { + template + static constexpr size_t GetTypeIndex() + { + return GetTypeIndexInternal(); + } + }; + } // namespace Internal + + // Helper function, looks up the index of a type within Value::m_value's storage + template + constexpr size_t GetTypeIndex() + { + return Internal::ExtractTypeArgs::GetTypeIndex(); + } + Node::Node(AZ::Name name) : m_name(name) { @@ -227,27 +272,27 @@ namespace AZ::Dom { switch (m_value.index()) { - case 0: // AZStd::monostate + case GetTypeIndex(): return Type::Null; - case 1: // int64_t + case GetTypeIndex(): return Type::Int64; - case 2: // uint64_t + case GetTypeIndex(): return Type::Uint64; - case 3: // double + case GetTypeIndex(): return Type::Double; - case 4: // bool + case GetTypeIndex(): return Type::Bool; - case 5: // AZStd::string_view - case 6: // AZStd::shared_ptr - case 7: // ShortStringType + case GetTypeIndex(): + case GetTypeIndex(): + case GetTypeIndex(): return Type::String; - case 8: // ObjectPtr + case GetTypeIndex(): return Type::Object; - case 9: // ArrayPtr + case GetTypeIndex(): return Type::Array; - case 10: // NodePtr + case GetTypeIndex(): return Type::Node; - case 11: // AZStd::any* + case GetTypeIndex>(): return Type::Opaque; } AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); @@ -813,11 +858,11 @@ namespace AZ::Dom { switch (m_value.index()) { - case 1: // int64_t + case GetTypeIndex(): return AZStd::get(m_value); - case 2: // uint64_t + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); - case 3: // double + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); } AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); @@ -843,11 +888,11 @@ namespace AZ::Dom { switch (m_value.index()) { - case 1: // int64_t + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); - case 2: // uint64_t + case GetTypeIndex(): return AZStd::get(m_value); - case 3: // double + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); } AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); @@ -888,11 +933,11 @@ namespace AZ::Dom { switch (m_value.index()) { - case 1: // int64_t + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); - case 2: // uint64_t + case GetTypeIndex(): return aznumeric_cast(AZStd::get(m_value)); - case 3: // double + case GetTypeIndex(): return AZStd::get(m_value); } AZ_Assert(false, "AZ::Dom::Value: Called GetInt on a non-numeric type"); @@ -923,14 +968,14 @@ namespace AZ::Dom { switch (m_value.index()) { - case 5: // AZStd::string_view + case GetTypeIndex(): return AZStd::get(m_value); - case 6: // AZStd::shared_ptr> + case GetTypeIndex(): { auto& buffer = *AZStd::get(m_value); return { buffer.data(), buffer.size() }; } - case 7: // ShortStringType + case GetTypeIndex(): { const ShortStringType& shortString = AZStd::get(m_value); return { shortString.data(), shortString.size() }; @@ -965,8 +1010,7 @@ namespace AZ::Dom } else { - SharedStringType sharedString = - AZStd::allocate_shared(StdValueAllocator(), value.begin(), value.end()); + SharedStringType sharedString = AZStd::allocate_shared(StdValueAllocator(), value.begin(), value.end()); m_value = AZStd::move(sharedString); } } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index bc1b790009..86e98030e2 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -159,6 +159,33 @@ namespace AZ::Dom using SharedStringContainer = AZStd::vector; using SharedStringType = AZStd::shared_ptr; + //! The internal storage type for Value. + //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes + //! for the same type in some instances, such as string storage. + using ValueType = AZStd::variant< + // Null + AZStd::monostate, + // Int64 + int64_t, + // Uint64 + uint64_t, + // Double + double, + // Bool + bool, + // StringType + AZStd::string_view, + SharedStringType, + ShortStringType, + // Object + ObjectPtr, + // Array + ArrayPtr, + // Node + NodePtr, + // Opaque + AZStd::shared_ptr>; + // Constructors... Value(); Value(const Value&); @@ -347,33 +374,6 @@ namespace AZ::Dom explicit Value(const AZStd::any& opaqueValue); - //! The internal storage type for Value. - //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes - //! for the same type in some instances, such as string storage. - using ValueType = AZStd::variant< - // Null - AZStd::monostate, - // Int64 - int64_t, - // Uint64 - uint64_t, - // Double - double, - // Bool - bool, - // StringType - AZStd::string_view, - SharedStringType, - ShortStringType, - // Object - ObjectPtr, - // Array - ArrayPtr, - // Node - NodePtr, - // Opaque - AZStd::shared_ptr>; - static_assert( sizeof(ValueType) == sizeof(ShortStringType) + sizeof(size_t), "ValueType should have no members larger than ShortStringType"); From 37330c43a9408ad9ffcd726c14f510c4b5d264f5 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 21 Dec 2021 15:47:42 -0800 Subject: [PATCH 042/272] Address some more Generic Dom Value perf feedback Signed-off-by: Nicholas Van Sickle --- .../Backends/JSON/JsonSerializationUtils.cpp | 4 -- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 57 ++++++++++--------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 4 +- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 26 ++++----- .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 26 ++++++--- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 16 +++++- 6 files changed, 77 insertions(+), 56 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp index bc8ac9167c..3baf78b63d 100644 --- a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp @@ -373,10 +373,6 @@ namespace AZ::Dom::Json bool RapidJsonReadHandler::Key(const char* str, rapidjson::SizeType length, [[maybe_unused]] bool copy) { AZStd::string_view key = AZStd::string_view(str, length); - if (!m_visitor->SupportsRawKeys()) - { - m_visitor->Key(AZ::Name(key)); - } const Lifetime lifetime = !copy ? m_stringLifetime : Lifetime::Temporary; return CheckResult(m_visitor->RawKey(key, lifetime)); } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 3836568f37..407d1e66a2 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -17,13 +17,15 @@ namespace AZ::Dom template AZStd::shared_ptr& CheckCopyOnWrite(AZStd::shared_ptr& refCountedPointer) { - if (refCountedPointer.use_count() > 1) + if (refCountedPointer.use_count() == 1) { - AZStd::shared_ptr newPointer = AZStd::allocate_shared(StdValueAllocator()); - *newPointer = *refCountedPointer; - refCountedPointer = AZStd::move(newPointer); + return refCountedPointer; + } + else + { + refCountedPointer = AZStd::allocate_shared(StdValueAllocator(), *refCountedPointer); + return refCountedPointer; } - return refCountedPointer; } namespace Internal @@ -72,7 +74,7 @@ namespace AZ::Dom } Node::Node(AZ::Name name) - : m_name(name) + : m_name(AZStd::move(name)) { } @@ -83,7 +85,7 @@ namespace AZ::Dom void Node::SetName(AZ::Name name) { - m_name = name; + m_name = AZStd::move(name); } Object::ContainerType& Node::GetProperties() @@ -106,8 +108,8 @@ namespace AZ::Dom return m_children; } - Value::Value(AZStd::shared_ptr string) - : m_value(string) + Value::Value(SharedStringType sharedString) + : m_value(AZStd::move(sharedString)) { } @@ -122,18 +124,19 @@ namespace AZ::Dom Value::Value(Value&& value) noexcept { - operator=(value); + memcpy(this, &value, sizeof(Value)); + memset(&value, 0, sizeof(Value)); } - Value::Value(AZStd::string_view string, bool copy) + Value::Value(AZStd::string_view stringView, bool copy) { if (copy) { - CopyFromString(string); + CopyFromString(stringView); } else { - SetString(string); + SetString(stringView); } } @@ -227,7 +230,9 @@ namespace AZ::Dom Value& Value::operator=(Value&& other) noexcept { - m_value.swap(other.m_value); + SetNull(); + memcpy(this, &other, sizeof(Value)); + memset(&other, 0, sizeof(Value)); return *this; } @@ -265,7 +270,10 @@ namespace AZ::Dom void Value::Swap(Value& other) noexcept { - m_value.swap(other.m_value); + AZStd::aligned_storage_for_t temp; + memcpy(&temp, this, sizeof(Value)); + memcpy(this, &other, sizeof(Value)); + memcpy(&other, &temp, sizeof(Value)); } Type Dom::Value::GetType() const @@ -583,7 +591,7 @@ namespace AZ::Dom } else { - object.emplace_back(name, value); + object.emplace_back(AZStd::move(name), value); } return *this; } @@ -602,7 +610,7 @@ namespace AZ::Dom } else { - object.emplace_back(name, value); + object.emplace_back(AZStd::move(name), value); } return *this; } @@ -636,15 +644,12 @@ namespace AZ::Dom Object::Iterator Value::RemoveMember(Object::Iterator pos) { Object::ContainerType& object = GetObjectInternal(); - Object::Iterator nextIndex = object.end(); - auto lastEntry = object.end() - 1; - if (pos != lastEntry) + if (!object.empty()) { - AZStd::swap(*pos, *lastEntry); - nextIndex = pos; + AZStd::swap(*pos, object.back()); + object.pop_back(); } - object.resize(object.size() - 1); - return nextIndex; + return object.end(); } Object::Iterator Value::EraseMember(Object::ConstIterator pos) @@ -785,7 +790,7 @@ namespace AZ::Dom void Value::SetNode(AZ::Name name) { - m_value = AZStd::allocate_shared(StdValueAllocator(), name); + m_value = AZStd::allocate_shared(StdValueAllocator(), AZStd::move(name)); } void Value::SetNode(AZStd::string_view name) @@ -800,7 +805,7 @@ namespace AZ::Dom void Value::SetNodeName(AZ::Name name) { - GetNodeInternal().SetName(name); + GetNodeInternal().SetName(AZStd::move(name)); } void Value::SetNodeName(AZStd::string_view name) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 86e98030e2..a777640aaf 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -190,8 +190,8 @@ namespace AZ::Dom Value(); Value(const Value&); Value(Value&&) noexcept; - Value(AZStd::string_view string, bool copy); - Value(AZStd::shared_ptr string); + Value(AZStd::string_view stringView, bool copy); + Value(SharedStringType sharedString); Value(int32_t value); Value(uint32_t value); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 9b814b1bff..3259579aaa 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -82,6 +82,16 @@ namespace AZ::Dom return VisitorSuccess(); } + template + void MoveVectorMemory(AZStd::vector& dest, AZStd::vector& source) + { + dest.resize_no_construct(source.size()); + const size_t size = sizeof(T) * source.size(); + memcpy(dest.data(), source.data(), size); + memset(source.data(), 0, size); + source.resize(0); + } + Visitor::Result ValueWriter::EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount) { const char* endMethodName; @@ -138,22 +148,12 @@ namespace AZ::Dom } if (buffer.m_attributes.size() > 0) { - container.MemberReserve(buffer.m_attributes.size()); - for (AZStd::pair& entry : buffer.m_attributes) - { - container.AddMember(AZStd::move(entry.first), AZStd::move(entry.second)); - } - buffer.m_attributes.clear(); + MoveVectorMemory(container.GetMutableObject(), buffer.m_attributes); } if(buffer.m_elements.size() > 0) { - container.Reserve(buffer.m_elements.size()); - for (Value& entry : buffer.m_elements) - { - container.PushBack(AZStd::move(entry)); - } - buffer.m_elements.clear(); + MoveVectorMemory(container.GetMutableArray(), buffer.m_elements); } m_entryStack.pop(); @@ -180,7 +180,7 @@ namespace AZ::Dom { AZ_Assert(!m_entryStack.empty(), "Attempmted to push a key with no object"); AZ_Assert(!m_entryStack.top().m_container.IsArray(), "Attempted to push a key to an array"); - m_entryStack.top().m_key = key; + m_entryStack.top().m_key = AZStd::move(key); return VisitorSuccess(); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index 477802dc37..8eda110e7b 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -120,6 +120,16 @@ namespace Benchmark AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON"); return serializedJson; } + + template + void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state) + { + { + T instance = AZStd::move(value); + state.PauseTiming(); + } + state.ResumeTiming(); + } }; // Helper macro for registering JSON benchmarks @@ -148,7 +158,7 @@ namespace Benchmark return AZ::Dom::Utils::ReadFromStringInPlace(backend, payloadCopy, visitor); }); - benchmark::DoNotOptimize(result.GetValue()); + TakeAndDiscardWithoutTimingDtor(result.TakeValue(), state); } state.SetBytesProcessed(serializedPayload.size() * state.iterations()); @@ -172,7 +182,7 @@ namespace Benchmark return AZ::Dom::Utils::ReadFromStringInPlace(backend, payloadCopy, visitor); }); - benchmark::DoNotOptimize(result.GetValue()); + TakeAndDiscardWithoutTimingDtor(result.TakeValue(), state); } state.SetBytesProcessed(serializedPayload.size() * state.iterations()); @@ -192,7 +202,7 @@ namespace Benchmark return AZ::Dom::Utils::ReadFromString(backend, serializedPayload, AZ::Dom::Lifetime::Temporary, visitor); }); - benchmark::DoNotOptimize(result.GetValue()); + TakeAndDiscardWithoutTimingDtor(result.TakeValue(), state); } state.SetBytesProcessed(serializedPayload.size() * state.iterations()); @@ -212,7 +222,7 @@ namespace Benchmark return AZ::Dom::Utils::ReadFromString(backend, serializedPayload, AZ::Dom::Lifetime::Temporary, visitor); }); - benchmark::DoNotOptimize(result.GetValue()); + TakeAndDiscardWithoutTimingDtor(result.TakeValue(), state); } state.SetBytesProcessed(serializedPayload.size() * state.iterations()); @@ -228,7 +238,7 @@ namespace Benchmark { auto result = AZ::JsonSerializationUtils::ReadJsonString(serializedPayload); - benchmark::DoNotOptimize(result.GetValue()); + TakeAndDiscardWithoutTimingDtor(result.TakeValue(), state); } state.SetBytesProcessed(serializedPayload.size() * state.iterations()); @@ -239,7 +249,7 @@ namespace Benchmark { for (auto _ : state) { - benchmark::DoNotOptimize(GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1))); + TakeAndDiscardWithoutTimingDtor(GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)), state); } state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); @@ -277,7 +287,7 @@ namespace Benchmark { rapidjson::Document copy; copy.CopyFrom(original, copy.GetAllocator(), true); - benchmark::DoNotOptimize(copy); + TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } state.SetItemsProcessed(state.iterations()); @@ -294,7 +304,7 @@ namespace Benchmark rapidjson::Document copy; copy.CopyFrom(original, copy.GetAllocator(), true); copy["entries"]["Key0"].PushBack(42, copy.GetAllocator()); - benchmark::DoNotOptimize(copy); + TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } state.SetItemsProcessed(state.iterations()); diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index af5b367d63..12684c64bc 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -98,13 +98,23 @@ namespace AZ::Dom::Benchmark return root; } + + template + void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state) + { + { + T instance = AZStd::move(value); + state.PauseTiming(); + } + state.ResumeTiming(); + } }; BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueMakeComplexObject)(benchmark::State& state) { for (auto _ : state) { - benchmark::DoNotOptimize(GenerateDomBenchmarkPayload(state.range(0), state.range(1))); + TakeAndDiscardWithoutTimingDtor(GenerateDomBenchmarkPayload(state.range(0), state.range(1)), state); } state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); @@ -143,7 +153,7 @@ namespace AZ::Dom::Benchmark { Value copy = original; copy["entries"]["Key0"].PushBack(42); - benchmark::DoNotOptimize(copy); + TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } state.SetItemsProcessed(state.iterations()); @@ -162,7 +172,7 @@ namespace AZ::Dom::Benchmark for (auto _ : state) { Value copy = original.DeepCopy(); - benchmark::DoNotOptimize(copy); + TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } state.SetItemsProcessed(state.iterations()); From 68c93273d687bda5c57e88d9ab630ca6ee03b6f1 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 21 Dec 2021 16:09:11 -0800 Subject: [PATCH 043/272] Add 8 and 16 bit numeric type API Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 20 +++++++++++++++++++ Code/Framework/AzCore/AzCore/DOM/DomValue.h | 12 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 407d1e66a2..f9f4f726dd 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -150,6 +150,26 @@ namespace AZ::Dom return Value(&value); } + Value::Value(int8_t value) + : m_value(aznumeric_cast(value)) + { + } + + Value::Value(uint8_t value) + : m_value(aznumeric_cast(value)) + { + } + + Value::Value(int16_t value) + : m_value(aznumeric_cast(value)) + { + } + + Value::Value(uint16_t value) + : m_value(aznumeric_cast(value)) + { + } + Value::Value(int32_t value) : m_value(aznumeric_cast(value)) { diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index a777640aaf..7ef794486e 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -193,6 +193,10 @@ namespace AZ::Dom Value(AZStd::string_view stringView, bool copy); Value(SharedStringType sharedString); + Value(int8_t value); + Value(uint8_t value); + Value(int16_t value); + Value(uint16_t value); Value(int32_t value); Value(uint32_t value); Value(int64_t value); @@ -321,12 +325,20 @@ namespace AZ::Dom void SetInt64(int64_t); int32_t GetInt32() const; void SetInt32(int32_t); + int16_t GetInt16() const; + void SetInt16(int16_t); + int8_t GetInt8() const; + void SetInt8(int8_t); // uint API... uint64_t GetUint64() const; void SetUint64(uint64_t); uint32_t GetUint32() const; void SetUint32(uint32_t); + uint16_t GetUint16() const; + void SetUint16(uint16_t); + uint8_t GetUint8() const; + void SetUint8(uint8_t); // bool API... bool GetBool() const; From deb3568aaa15e962b49fb5a0aa6b19960866fa73 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 21 Dec 2021 16:19:32 -0800 Subject: [PATCH 044/272] Fix up a couple opaque value cases Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 4 ++-- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index f9f4f726dd..01d7bcf6e1 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -1042,7 +1042,7 @@ namespace AZ::Dom const AZStd::any& Value::GetOpaqueValue() const { - return *AZStd::get>(m_value); + return *AZStd::get(m_value); } void Value::SetOpaqueValue(const AZStd::any& value) @@ -1165,7 +1165,7 @@ namespace AZ::Dom result = visitor.EndNode(object.size(), arrayContainer.size()); } } - else if constexpr (AZStd::is_same_v) + else if constexpr (AZStd::is_same_v) { result = visitor.OpaqueValue(*arg); } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 7ef794486e..b9c1062ed7 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -158,6 +158,7 @@ namespace AZ::Dom using ShortStringType = AZStd::fixed_string; using SharedStringContainer = AZStd::vector; using SharedStringType = AZStd::shared_ptr; + using OpaqueStorageType = AZStd::shared_ptr; //! The internal storage type for Value. //! These types do not correspond one-to-one with the Value's external Type as there may be multiple storage classes @@ -184,7 +185,7 @@ namespace AZ::Dom // Node NodePtr, // Opaque - AZStd::shared_ptr>; + OpaqueStorageType>; // Constructors... Value(); From fd70a2207e68dc456a91e23e5446f64b5a6971a6 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 21 Dec 2021 16:47:13 -0800 Subject: [PATCH 045/272] Address a few other small pieces of feedback Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 14 +++++--------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 8 ++++---- .../Framework/AzCore/AzCore/DOM/DomValueWriter.cpp | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 01d7bcf6e1..7659afa070 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -113,10 +113,6 @@ namespace AZ::Dom { } - Value::Value() - { - } - Value::Value(const Value& value) : m_value(value.m_value) { @@ -344,7 +340,7 @@ namespace AZ::Dom bool Value::IsBool() const { - return AZStd::holds_alternative(m_value); + return GetType() == Type::Bool; } bool Value::IsNode() const @@ -383,17 +379,17 @@ namespace AZ::Dom bool Value::IsInt() const { - return AZStd::holds_alternative(m_value); + return GetType() == Type::Int64; } bool Value::IsUint() const { - return AZStd::holds_alternative(m_value); + return GetType() == Type::Uint64; } bool Value::IsDouble() const { - return AZStd::holds_alternative(m_value); + return GetType() == Type::Double; } bool Value::IsString() const @@ -666,7 +662,7 @@ namespace AZ::Dom Object::ContainerType& object = GetObjectInternal(); if (!object.empty()) { - AZStd::swap(*pos, object.back()); + *pos = AZStd::move(object.back()); object.pop_back(); } return object.end(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index b9c1062ed7..b73da92d23 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -103,9 +103,9 @@ namespace AZ::Dom { public: Node() = default; - Node(AZ::Name name); - Node(const Node&) = default; - Node(Node&&) = default; + explicit Node(AZ::Name name); + explicit Node(const Node&) = default; + explicit Node(Node&&) = default; Node& operator=(const Node&) = default; Node& operator=(Node&&) = default; @@ -188,7 +188,7 @@ namespace AZ::Dom OpaqueStorageType>; // Constructors... - Value(); + Value() = default; Value(const Value&); Value(Value&&) noexcept; Value(AZStd::string_view stringView, bool copy); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 3259579aaa..f8ca56ea32 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -70,7 +70,7 @@ namespace AZ::Dom Visitor::Result ValueWriter::RefCountedString(AZStd::shared_ptr> value, [[maybe_unused]] Lifetime lifetime) { - CurrentValue().SetString(value); + CurrentValue().SetString(AZStd::move(value)); return FinishWrite(); } From f69b9b817c19b73921d5e4095d309a51b656fe8c Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 22 Dec 2021 11:03:51 -0800 Subject: [PATCH 046/272] Round of clang compile fixes Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 10 ++-------- Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp | 7 +++---- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index 46fa5b9bac..d65497e194 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -22,7 +22,7 @@ namespace AZ::Dom::Utils return backend.ReadFromBufferInPlace(string.data(), string.size(), visitor); } - AZ::Outcome AZ::Dom::Utils::WriteToValue(Backend::WriteCallback writeCallback) + AZ::Outcome WriteToValue(Backend::WriteCallback writeCallback) { Value value; AZStd::unique_ptr writer = value.GetWriteHandler(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 7659afa070..7401a5ac98 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -6,8 +6,6 @@ * */ -#pragma once - #include #include #include @@ -31,11 +29,7 @@ namespace AZ::Dom namespace Internal { template - constexpr size_t GetTypeIndexInternal(size_t index = 0) - { - static_assert(false, "Type not found in ValueType"); - return index; - } + constexpr size_t GetTypeIndexInternal(size_t index = 0); template constexpr size_t GetTypeIndexInternal(size_t index = 0) @@ -143,7 +137,7 @@ namespace AZ::Dom Value Value::FromOpaqueValue(const AZStd::any& value) { - return Value(&value); + return Value(value); } Value::Value(int8_t value) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index f8ca56ea32..b7ed44f8de 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -129,7 +129,7 @@ namespace AZ::Dom AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); } - if (buffer.m_attributes.size() != attributeCount) + if (static_cast(buffer.m_attributes.size()) != attributeCount) { return VisitorFailure( VisitorErrorCode::InternalError, @@ -138,7 +138,7 @@ namespace AZ::Dom buffer.m_attributes.size())); } - if (buffer.m_elements.size() != elementCount) + if (static_cast(buffer.m_elements.size()) != elementCount) { return VisitorFailure( VisitorErrorCode::InternalError, @@ -146,6 +146,7 @@ namespace AZ::Dom "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, buffer.m_elements.size())); } + if (buffer.m_attributes.size() > 0) { MoveVectorMemory(container.GetMutableObject(), buffer.m_attributes); @@ -237,8 +238,6 @@ namespace AZ::Dom m_entryStack.top().m_value.Swap(value); ValueInfo& newEntry = m_entryStack.top(); - constexpr const size_t reserveSize = 8; - if (!newEntry.m_key.IsEmpty()) { GetValueBuffer().m_attributes.emplace_back(AZStd::move(newEntry.m_key), AZStd::move(value)); From 8732fab19284ca5736d30f1406659949bed02710 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 22 Dec 2021 12:35:44 -0800 Subject: [PATCH 047/272] One more compile fix Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index b7ed44f8de..210d1fa123 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -134,7 +134,7 @@ namespace AZ::Dom return VisitorFailure( VisitorErrorCode::InternalError, AZStd::string::format( - "AZ::Dom::ValueWriter: %s expected %llu attributes but received %llu attributes instead", endMethodName, attributeCount, + "AZ::Dom::ValueWriter: %s expected %llu attributes but received %zu attributes instead", endMethodName, attributeCount, buffer.m_attributes.size())); } @@ -143,7 +143,7 @@ namespace AZ::Dom return VisitorFailure( VisitorErrorCode::InternalError, AZStd::string::format( - "AZ::Dom::ValueWriter: %s expected %llu elements but received %llu elements instead", endMethodName, elementCount, + "AZ::Dom::ValueWriter: %s expected %llu elements but received %zu elements instead", endMethodName, elementCount, buffer.m_elements.size())); } From 4f746fddac6a2f82e4172a961ac3a8aa5ddfd113 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Fri, 24 Dec 2021 16:56:39 -0800 Subject: [PATCH 048/272] chore: Rename Graph to EditorGraph Signed-off-by: Michael Pollind --- .../Builder/ScriptCanvasBuilderWorker.cpp | 2 +- .../Code/Builder/ScriptCanvasBuilderWorker.h | 4 +- .../ScriptCanvasBuilderWorkerUtility.cpp | 6 +- .../Assets/ScriptCanvasFileHandling.cpp | 4 +- .../Editor/Assets/ScriptCanvasUndoHelper.cpp | 4 +- .../Editor/Assets/ScriptCanvasUndoHelper.h | 6 +- .../Code/Editor/Components/EditorGraph.cpp | 264 +++++++++--------- .../Code/Editor/Components/EditorUtils.cpp | 2 +- .../Code/Editor/Components/GraphUpgrade.cpp | 4 +- .../ScriptCanvas/Components/EditorGraph.h | 22 +- .../ScriptCanvas/Components/EditorUtils.h | 4 +- .../ScriptCanvas/Components/GraphUpgrade.h | 6 +- .../Code/Editor/ScriptCanvasEditorGem.cpp | 2 +- .../Code/Editor/SystemComponent.cpp | 2 +- .../Editor/Undo/ScriptCanvasGraphCommand.cpp | 8 +- .../Editor/Undo/ScriptCanvasGraphCommand.h | 8 +- .../Code/Editor/View/Windows/MainWindow.cpp | 2 +- .../Windows/Tools/UpgradeTool/Controller.cpp | 2 +- .../Code/Include/ScriptCanvas/Core/Core.cpp | 8 +- .../Code/Include/ScriptCanvas/Core/Core.h | 10 +- 20 files changed, 184 insertions(+), 186 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp index a1a2d1d20f..2f44dfe090 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp @@ -44,7 +44,7 @@ namespace ScriptCanvasBuilder AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, false); AzFramework::StringFunc::Path::Normalize(fullPath); - const ScriptCanvasEditor::Graph* sourceGraph = nullptr; + const ScriptCanvasEditor::EditorGraph* sourceGraph = nullptr; const ScriptCanvas::GraphData* graphData = nullptr; ScriptCanvasEditor::SourceHandle sourceHandle; diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h index 142886f98c..42cc958a07 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h @@ -35,7 +35,7 @@ namespace ScriptCanvas namespace ScriptCanvasEditor { - class Graph; + class EditorGraph; class SourceHandle; } @@ -135,7 +135,7 @@ namespace ScriptCanvasBuilder AZ::Outcome ProcessTranslationJob(ProcessTranslationJobInput& input); - ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity); + ScriptCanvasEditor::EditorGraph* PrepareSourceGraph(AZ::Entity* const buildEntity); AZ::Outcome SaveSubgraphInterface(ProcessTranslationJobInput& input, ScriptCanvas::SubgraphInterfaceData& subgraphInterface); diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp index 64e73de9b9..110f8c5164 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp @@ -153,7 +153,7 @@ namespace ScriptCanvasBuilder return AZ::Failure(AZStd::string("Cannot compile graph data from a nullptr Script Canvas Entity")); } - auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(scriptCanvasEntity); + auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(scriptCanvasEntity); if (!sourceGraph) { return AZ::Failure(AZStd::string("Failed to find Script Canvas Graph Component")); @@ -385,9 +385,9 @@ namespace ScriptCanvasBuilder ; } - ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity) + ScriptCanvasEditor::EditorGraph* PrepareSourceGraph(AZ::Entity* const buildEntity) { - auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(buildEntity); + auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(buildEntity); if (!sourceGraph) { return nullptr; diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasFileHandling.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasFileHandling.cpp index c4579c9042..bea3cdfe21 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasFileHandling.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasFileHandling.cpp @@ -180,7 +180,7 @@ namespace ScriptCanvasEditor AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); AZ_Assert(serializeContext, "LoadEditorAssetTree() ailed to retrieve serialize context!"); - const ScriptCanvasEditor::Graph* graph = handle.Get(); + const ScriptCanvasEditor::EditorGraph* graph = handle.Get(); serializeContext->EnumerateObject(graph, beginElementCB, nullptr, AZ::SerializeContext::ENUM_ACCESS_FOR_READ); EditorAssetTree result; @@ -253,7 +253,7 @@ namespace ScriptCanvasEditor aznumeric_caster(ScriptCanvas::MathNodeUtilities::GetRandomIntegral(1, std::numeric_limits::max())); entity->SetId(AZ::EntityId(entityId)); - auto graph = entity->FindComponent(); + auto graph = entity->FindComponent(); graph->MarkOwnership(*scriptCanvasData); entity->Init(); diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.cpp index a067bf411e..35c2f9a11a 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.cpp @@ -17,7 +17,7 @@ namespace ScriptCanvasEditor { } - UndoHelper::UndoHelper(Graph* graph) + UndoHelper::UndoHelper(EditorGraph* graph) : m_undoState(this) { SetSource(graph); @@ -28,7 +28,7 @@ namespace ScriptCanvasEditor UndoRequestBus::Handler::BusDisconnect(); } - void UndoHelper::SetSource(Graph* graph) + void UndoHelper::SetSource(EditorGraph* graph) { m_graph = graph; UndoRequestBus::Handler::BusConnect(graph->GetScriptCanvasId()); diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.h b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.h index e2d4f008fa..4765468ee7 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.h +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasUndoHelper.h @@ -21,13 +21,13 @@ namespace ScriptCanvasEditor public: UndoHelper(); - UndoHelper(Graph* source); + UndoHelper(EditorGraph* source); ~UndoHelper(); UndoCache* GetSceneUndoCache() override; UndoData CreateUndoData() override; - void SetSource(Graph* source); + void SetSource(EditorGraph* source); void BeginUndoBatch(AZStd::string_view label) override; void EndUndoBatch() override; @@ -58,6 +58,6 @@ namespace ScriptCanvasEditor Status m_status = Status::Idle; SceneUndoState m_undoState; - Graph* m_graph = nullptr; + EditorGraph* m_graph = nullptr; }; } diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index d713bc09a6..2a610cd44f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -100,20 +100,8 @@ namespace EditorGraphCpp } namespace ScriptCanvasEditor { - namespace EditorGraph - { - static const char* GetMimeType() - { - return "application/x-o3de-scriptcanvas"; - } - static const char* GetWrappedNodeGroupingMimeType() - { - return "application/x-03de-scriptcanvas-wrappednodegrouping"; - } - } - - Graph::~Graph() + EditorGraph::~EditorGraph() { for (auto& entry : m_graphCanvasSaveData) { @@ -152,7 +140,7 @@ namespace ScriptCanvasEditor return true; } - void Graph::ConvertToGetVariableNode(Graph* graph, ScriptCanvas::VariableId variableId, const AZ::EntityId& nodeId, AZStd::unordered_map< AZ::EntityId, AZ::EntityId >& setVariableRemapping) + void EditorGraph::ConvertToGetVariableNode(EditorGraph* graph, ScriptCanvas::VariableId variableId, const AZ::EntityId& nodeId, AZStd::unordered_map< AZ::EntityId, AZ::EntityId >& setVariableRemapping) { ScriptCanvas::ScriptCanvasId scriptCanvasId = graph->GetScriptCanvasId(); GraphCanvas::GraphId graphId = graph->GetGraphCanvasGraphId(); @@ -440,7 +428,7 @@ namespace ScriptCanvasEditor } } - void Graph::Reflect(AZ::ReflectContext* context) + void EditorGraph::Reflect(AZ::ReflectContext* context) { GraphStatisticsHelper::Reflect(context); @@ -453,19 +441,19 @@ namespace ScriptCanvasEditor ->Field("Count", &CRCCache::m_cacheCount) ; - serializeContext->Class() + serializeContext->Class() ->Version(EditorGraphCpp::Version::Current, &GraphVersionConverter) - ->Field("m_variableCounter", &Graph::m_variableCounter) - ->Field("m_saveFormatConverted", &Graph::m_saveFormatConverted) - ->Field("GraphCanvasData", &Graph::m_graphCanvasSaveData) - ->Field("CRCCacheMap", &Graph::m_crcCacheMap) - ->Field("StatisticsHelper", &Graph::m_statisticsHelper) - ->Field("GraphCanvasSaveVersion", &Graph::m_graphCanvasSaveVersion) + ->Field("m_variableCounter", &EditorGraph::m_variableCounter) + ->Field("m_saveFormatConverted", &EditorGraph::m_saveFormatConverted) + ->Field("GraphCanvasData", &EditorGraph::m_graphCanvasSaveData) + ->Field("CRCCacheMap", &EditorGraph::m_crcCacheMap) + ->Field("StatisticsHelper", &EditorGraph::m_statisticsHelper) + ->Field("GraphCanvasSaveVersion", &EditorGraph::m_graphCanvasSaveVersion) ; } } - void Graph::Activate() + void EditorGraph::Activate() { const ScriptCanvas::ScriptCanvasId& scriptCanvasId = GetScriptCanvasId(); @@ -483,7 +471,7 @@ namespace ScriptCanvasEditor m_undoHelper.SetSource(this); } - void Graph::Deactivate() + void EditorGraph::Deactivate() { GraphItemCommandNotificationBus::Handler::BusDisconnect(); ScriptCanvas::GraphRequestBus::Handler::BusDisconnect(); @@ -499,7 +487,7 @@ namespace ScriptCanvasEditor m_graphCanvasSceneEntity = nullptr; } - void Graph::OnViewRegistered() + void EditorGraph::OnViewRegistered() { if (!m_saveFormatConverted) { @@ -507,7 +495,7 @@ namespace ScriptCanvasEditor } } - bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport) + bool EditorGraph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport) { auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector& newSlots)->ScriptCanvas::SlotId { @@ -623,7 +611,7 @@ namespace ScriptCanvasEditor return true; } - void Graph::HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId) + void EditorGraph::HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId) { // Special-case for the execution nodeling extensions, which are adding input/output data slots. // We want to automatically promote them to variables so that the user can refer to them more easily @@ -690,7 +678,7 @@ namespace ScriptCanvasEditor } } - AZ::Outcome Graph::ReplaceNodeByConfig + AZ::Outcome EditorGraph::ReplaceNodeByConfig ( ScriptCanvas::Node* oldNode , const ScriptCanvas::NodeConfiguration& nodeConfig , ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport) @@ -809,7 +797,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnEntitiesSerialized(GraphCanvas::GraphSerialization& serializationTarget) + void EditorGraph::OnEntitiesSerialized(GraphCanvas::GraphSerialization& serializationTarget) { const GraphCanvas::GraphData& graphCanvasGraphData = serializationTarget.GetGraphData(); @@ -939,7 +927,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnEntitiesDeserialized(const GraphCanvas::GraphSerialization& serializationSource) + void EditorGraph::OnEntitiesDeserialized(const GraphCanvas::GraphSerialization& serializationSource) { const auto& userDataMap = serializationSource.GetUserDataMapRef(); @@ -1026,7 +1014,7 @@ namespace ScriptCanvasEditor } } - void Graph::DisconnectConnection(const GraphCanvas::ConnectionId& connectionId) + void EditorGraph::DisconnectConnection(const GraphCanvas::ConnectionId& connectionId) { AZStd::any* connectionUserData = nullptr; GraphCanvas::ConnectionRequestBus::EventResult(connectionUserData, connectionId, &GraphCanvas::ConnectionRequests::GetUserData); @@ -1044,11 +1032,11 @@ namespace ScriptCanvasEditor } } - ScriptCanvas::DataPtr Graph::Create() + ScriptCanvas::DataPtr EditorGraph::Create() { if (AZ::Entity* entity = aznew AZ::Entity("Script Canvas Graph")) { - auto graph = entity->CreateComponent(); + auto graph = entity->CreateComponent(); entity->CreateComponent(graph->GetScriptCanvasId()); if (ScriptCanvas::DataPtr data = aznew ScriptCanvas::ScriptCanvasData()) @@ -1064,17 +1052,17 @@ namespace ScriptCanvasEditor return nullptr; } - void Graph::MarkOwnership(ScriptCanvas::ScriptCanvasData& owner) + void EditorGraph::MarkOwnership(ScriptCanvas::ScriptCanvasData& owner) { m_owner = &owner; } - ScriptCanvas::DataPtr Graph::GetOwnership() const + ScriptCanvas::DataPtr EditorGraph::GetOwnership() const { - return const_cast(this)->m_owner; + return const_cast(this)->m_owner; } - bool Graph::CreateConnection(const GraphCanvas::ConnectionId& connectionId, const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) + bool EditorGraph::CreateConnection(const GraphCanvas::ConnectionId& connectionId, const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) { if (!sourcePoint.IsValid() || !targetPoint.IsValid()) { @@ -1103,7 +1091,7 @@ namespace ScriptCanvasEditor return scConnected; } - bool Graph::IsValidConnection(const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) const + bool EditorGraph::IsValidConnection(const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint) const { ScriptCanvas::Endpoint scSourceEndpoint = ConvertToScriptCanvasEndpoint(sourcePoint); ScriptCanvas::Endpoint scTargetEndpoint = ConvertToScriptCanvasEndpoint(targetPoint); @@ -1111,23 +1099,23 @@ namespace ScriptCanvasEditor return CanCreateConnectionBetween(scSourceEndpoint, scTargetEndpoint).IsSuccess(); } - AZStd::string Graph::GetDataTypeString(const AZ::Uuid&) + AZStd::string EditorGraph::GetDataTypeString(const AZ::Uuid&) { // This is used by the default tooltip setting in GraphCanvas, returning an empty string // in order for tooltips to be fully controlled by ScriptCanvas return {}; } - void Graph::OnRemoveUnusedNodes() + void EditorGraph::OnRemoveUnusedNodes() { } - void Graph::OnRemoveUnusedElements() + void EditorGraph::OnRemoveUnusedElements() { RemoveUnusedVariables(); } - bool Graph::AllowReset(const GraphCanvas::Endpoint& endpoint) const + bool EditorGraph::AllowReset(const GraphCanvas::Endpoint& endpoint) const { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); @@ -1159,7 +1147,7 @@ namespace ScriptCanvasEditor return false; } - GraphCanvas::NodePropertyDisplay* Graph::CreateDataSlotPropertyDisplay(const AZ::Uuid& dataType, const GraphCanvas::NodeId& nodeId, const GraphCanvas::SlotId& slotId) const + GraphCanvas::NodePropertyDisplay* EditorGraph::CreateDataSlotPropertyDisplay(const AZ::Uuid& dataType, const GraphCanvas::NodeId& nodeId, const GraphCanvas::SlotId& slotId) const { (void)dataType; @@ -1174,7 +1162,7 @@ namespace ScriptCanvasEditor return CreateDisplayPropertyForSlot(scriptCanvasNodeId, scriptCanvasSlotId); } - GraphCanvas::NodePropertyDisplay* Graph::CreatePropertySlotPropertyDisplay(const AZ::Crc32& propertyId, const GraphCanvas::NodeId& nodeId, const GraphCanvas::NodeId& slotId) const + GraphCanvas::NodePropertyDisplay* EditorGraph::CreatePropertySlotPropertyDisplay(const AZ::Crc32& propertyId, const GraphCanvas::NodeId& nodeId, const GraphCanvas::NodeId& slotId) const { (void)slotId; @@ -1234,7 +1222,7 @@ namespace ScriptCanvasEditor return nullptr; } - AZ::EntityId Graph::ConvertToScriptCanvasNodeId(const GraphCanvas::NodeId& nodeId) const + AZ::EntityId EditorGraph::ConvertToScriptCanvasNodeId(const GraphCanvas::NodeId& nodeId) const { AZStd::any* userData = nullptr; @@ -1243,7 +1231,7 @@ namespace ScriptCanvasEditor return (userData && userData->is()) ? *AZStd::any_cast(userData) : AZ::EntityId(); } - GraphCanvas::NodePropertyDisplay* Graph::CreateDisplayPropertyForSlot(const AZ::EntityId& scriptCanvasNodeId, const ScriptCanvas::SlotId& scriptCanvasSlotId) const + GraphCanvas::NodePropertyDisplay* EditorGraph::CreateDisplayPropertyForSlot(const AZ::EntityId& scriptCanvasNodeId, const ScriptCanvas::SlotId& scriptCanvasSlotId) const { ScriptCanvas::Slot* slot = nullptr; ScriptCanvas::NodeRequestBus::EventResult(slot, scriptCanvasNodeId, &ScriptCanvas::NodeRequests::GetSlot, scriptCanvasSlotId); @@ -1354,13 +1342,13 @@ namespace ScriptCanvasEditor return nullptr; } - void Graph::SignalDirty() + void EditorGraph::SignalDirty() { SourceHandle handle(m_owner, {}, {}); GeneralRequestBus::Broadcast(&GeneralRequests::SignalSceneDirty, handle); } - void Graph::HighlightNodesByType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier) + void EditorGraph::HighlightNodesByType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier) { for (const auto& nodePair : GetNodeMapping()) { @@ -1371,7 +1359,7 @@ namespace ScriptCanvasEditor } } - void Graph::HighlightEBusNodes(const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId) + void EditorGraph::HighlightEBusNodes(const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId) { ScriptCanvas::NodeTypeIdentifier ebusIdentifier = ScriptCanvas::NodeUtils::ConstructEBusIdentifier(busId); @@ -1394,7 +1382,7 @@ namespace ScriptCanvasEditor } } - void Graph::HighlightScriptEventNodes(const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId) + void EditorGraph::HighlightScriptEventNodes(const ScriptCanvas::EBusBusId& busId, const ScriptCanvas::EBusEventId& eventId) { ScriptCanvas::NodeTypeIdentifier sendScriptEventIdentifier = ScriptCanvas::NodeUtils::ConstructSendScriptEventIdentifier(busId, eventId); ScriptCanvas::NodeTypeIdentifier receiveScriptEventIdentifier = ScriptCanvas::NodeUtils::ConstructScriptEventIdentifier(busId); @@ -1422,7 +1410,7 @@ namespace ScriptCanvasEditor } } - void Graph::HighlightScriptCanvasEntity(const AZ::EntityId& scriptCanvasId) + void EditorGraph::HighlightScriptCanvasEntity(const AZ::EntityId& scriptCanvasId) { GraphCanvas::SceneMemberGlowOutlineConfiguration glowConfiguration; @@ -1446,7 +1434,7 @@ namespace ScriptCanvasEditor } } - AZ::EntityId Graph::FindGraphCanvasSlotId(const AZ::EntityId& graphCanvasNodeId, const ScriptCanvas::SlotId& slotId) + AZ::EntityId EditorGraph::FindGraphCanvasSlotId(const AZ::EntityId& graphCanvasNodeId, const ScriptCanvas::SlotId& slotId) { AZ::EntityId graphCanvasSlotId; SlotMappingRequestBus::EventResult(graphCanvasSlotId, graphCanvasNodeId, &SlotMappingRequests::MapToGraphCanvasId, slotId); @@ -1467,7 +1455,7 @@ namespace ScriptCanvasEditor return graphCanvasSlotId; } - bool Graph::ConfigureConnectionUserData(const ScriptCanvas::Endpoint& sourceEndpoint, const ScriptCanvas::Endpoint& targetEndpoint, GraphCanvas::ConnectionId connectionId) + bool EditorGraph::ConfigureConnectionUserData(const ScriptCanvas::Endpoint& sourceEndpoint, const ScriptCanvas::Endpoint& targetEndpoint, GraphCanvas::ConnectionId connectionId) { bool isConfigured = true; @@ -1493,7 +1481,7 @@ namespace ScriptCanvasEditor return isConfigured; } - void Graph::HandleQueuedUpdates() + void EditorGraph::HandleQueuedUpdates() { bool signalDirty = false; @@ -1573,7 +1561,7 @@ namespace ScriptCanvasEditor } } - bool Graph::IsNodeVersionConverting(const AZ::EntityId& graphCanvasNodeId) const + bool EditorGraph::IsNodeVersionConverting(const AZ::EntityId& graphCanvasNodeId) const { bool isConverting = false; @@ -1598,7 +1586,7 @@ namespace ScriptCanvasEditor return isConverting; } - void Graph::OnPreNodeDeleted(const AZ::EntityId& nodeId) + void EditorGraph::OnPreNodeDeleted(const AZ::EntityId& nodeId) { // If we are cdeleteing a HandlerEventNode we don't need to do anything since they are purely visual. // And the underlying ScriptCanvas nodes will persist and maintain all of their state. @@ -1630,7 +1618,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnPreConnectionDeleted(const AZ::EntityId& connectionId) + void EditorGraph::OnPreConnectionDeleted(const AZ::EntityId& connectionId) { AZStd::any* userData = nullptr; GraphCanvas::ConnectionRequestBus::EventResult(userData, connectionId, &GraphCanvas::ConnectionRequests::GetUserData); @@ -1671,22 +1659,22 @@ namespace ScriptCanvasEditor DisconnectConnection(connectionId); } - void Graph::OnUnknownPaste([[maybe_unused]] const QPointF& scenePos) + void EditorGraph::OnUnknownPaste([[maybe_unused]] const QPointF& scenePos) { GraphVariablesTableView::HandleVariablePaste(GetScriptCanvasId()); } - void Graph::OnSelectionChanged() + void EditorGraph::OnSelectionChanged() { ClearHighlights(); } - AZ::u32 Graph::GetNewVariableCounter() + AZ::u32 EditorGraph::GetNewVariableCounter() { return ++m_variableCounter; } - void Graph::ReleaseVariableCounter(AZ::u32 variableCounter) + void EditorGraph::ReleaseVariableCounter(AZ::u32 variableCounter) { if (m_variableCounter == variableCounter) { @@ -1694,32 +1682,32 @@ namespace ScriptCanvasEditor } } - void Graph::RequestUndoPoint() + void EditorGraph::RequestUndoPoint() { GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, GetScriptCanvasId()); } - void Graph::RequestPushPreventUndoStateUpdate() + void EditorGraph::RequestPushPreventUndoStateUpdate() { GeneralRequestBus::Broadcast(&GeneralRequests::PushPreventUndoStateUpdate); } - void Graph::RequestPopPreventUndoStateUpdate() + void EditorGraph::RequestPopPreventUndoStateUpdate() { GeneralRequestBus::Broadcast(&GeneralRequests::PopPreventUndoStateUpdate); } - void Graph::TriggerUndo() + void EditorGraph::TriggerUndo() { GeneralRequestBus::Broadcast(&GeneralRequests::TriggerUndo); } - void Graph::TriggerRedo() + void EditorGraph::TriggerRedo() { GeneralRequestBus::Broadcast(&GeneralRequests::TriggerRedo); } - void Graph::EnableNodes(const AZStd::unordered_set< GraphCanvas::NodeId >& nodeIds) + void EditorGraph::EnableNodes(const AZStd::unordered_set< GraphCanvas::NodeId >& nodeIds) { bool enabledNodes = false; for (auto graphCanvasNodeId : nodeIds) @@ -1745,7 +1733,7 @@ namespace ScriptCanvasEditor } } - void Graph::DisableNodes(const AZStd::unordered_set< GraphCanvas::NodeId >& nodeIds) + void EditorGraph::DisableNodes(const AZStd::unordered_set< GraphCanvas::NodeId >& nodeIds) { bool disabledNodes = false; for (auto graphCanvasNodeId : nodeIds) @@ -1766,12 +1754,12 @@ namespace ScriptCanvasEditor } } - void Graph::PostDeletionEvent() + void EditorGraph::PostDeletionEvent() { GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, GetScriptCanvasId()); } - void Graph::PostCreationEvent() + void EditorGraph::PostCreationEvent() { GeneralRequestBus::Broadcast(&GeneralRequests::PushPreventUndoStateUpdate); if (m_wrapperNodeDropTarget.IsValid()) @@ -1979,7 +1967,7 @@ namespace ScriptCanvasEditor GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, GetScriptCanvasId()); } - void Graph::PostRestore(const UndoData&) + void EditorGraph::PostRestore(const UndoData&) { AZStd::vector graphCanvasNodeIds; GraphCanvas::SceneRequestBus::EventResult(graphCanvasNodeIds, GetGraphCanvasGraphId(), &GraphCanvas::SceneRequests::GetNodes); @@ -1995,23 +1983,23 @@ namespace ScriptCanvasEditor GraphCanvas::ViewRequestBus::Event(viewId, &GraphCanvas::ViewRequests::RefreshView); } - void Graph::OnPasteBegin() + void EditorGraph::OnPasteBegin() { GeneralRequestBus::Broadcast(&GeneralRequests::PushPreventUndoStateUpdate); } - void Graph::OnPasteEnd() + void EditorGraph::OnPasteEnd() { GeneralRequestBus::Broadcast(&GeneralRequests::PopPreventUndoStateUpdate); GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, GetScriptCanvasId()); } - void Graph::OnGraphCanvasNodeCreated(const AZ::EntityId& nodeId) + void EditorGraph::OnGraphCanvasNodeCreated(const AZ::EntityId& nodeId) { m_lastGraphCanvasCreationGroup.emplace_back(nodeId); } - void Graph::ResetSlotToDefaultValue(const GraphCanvas::Endpoint& endpoint) + void EditorGraph::ResetSlotToDefaultValue(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); @@ -2023,13 +2011,13 @@ namespace ScriptCanvasEditor } } - void Graph::ResetReference(const GraphCanvas::Endpoint& endpoint) + void EditorGraph::ResetReference(const GraphCanvas::Endpoint& endpoint) { // ResetSlotToDefault deals with resetting the reference internal to the function call on the node. ResetSlotToDefaultValue(endpoint); } - void Graph::ResetProperty(const GraphCanvas::NodeId& nodeId, const AZ::Crc32& propertyId) + void EditorGraph::ResetProperty(const GraphCanvas::NodeId& nodeId, const AZ::Crc32& propertyId) { AZ::EntityId scriptCanvasNodeId = ConvertToScriptCanvasNodeId(nodeId); ScriptCanvas::Node* canvasNode = FindNode(scriptCanvasNodeId); @@ -2040,7 +2028,7 @@ namespace ScriptCanvasEditor } } - void Graph::RemoveSlot(const GraphCanvas::Endpoint& endpoint) + void EditorGraph::RemoveSlot(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); @@ -2067,7 +2055,7 @@ namespace ScriptCanvasEditor } } - bool Graph::IsSlotRemovable(const GraphCanvas::Endpoint& endpoint) const + bool EditorGraph::IsSlotRemovable(const GraphCanvas::Endpoint& endpoint) const { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); @@ -2081,7 +2069,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2094,7 +2082,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2111,7 +2099,7 @@ namespace ScriptCanvasEditor return false; } - GraphCanvas::CanHandleMimeEventOutcome Graph::CanHandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) + GraphCanvas::CanHandleMimeEventOutcome EditorGraph::CanHandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2144,7 +2132,7 @@ namespace ScriptCanvasEditor return AZ::Failure(AZStd::string("Unable to find Node")); } - bool Graph::HandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) + bool EditorGraph::HandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) { bool handledEvent = false; @@ -2170,7 +2158,7 @@ namespace ScriptCanvasEditor return handledEvent; } - bool Graph::CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint) const + bool EditorGraph::CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint) const { ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(endpoint); auto activeSlot = FindSlot(scriptCanvasEndpoint); @@ -2189,7 +2177,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(endpoint); @@ -2296,7 +2284,7 @@ namespace ScriptCanvasEditor return addOutcome.IsSuccess(); } - bool Graph::SynchronizeReferences(const GraphCanvas::Endpoint& referenceSource, const GraphCanvas::Endpoint& referenceTarget) + bool EditorGraph::SynchronizeReferences(const GraphCanvas::Endpoint& referenceSource, const GraphCanvas::Endpoint& referenceTarget) { ScriptCanvas::Endpoint scriptCanvasSourceEndpoint = ConvertToScriptCanvasEndpoint(referenceSource); ScriptCanvas::Endpoint scriptCanvasTargetEndpoint = ConvertToScriptCanvasEndpoint(referenceTarget); @@ -2334,7 +2322,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::ConvertSlotToValue(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::ConvertSlotToValue(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2347,7 +2335,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::CanConvertSlotToValue(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::CanConvertSlotToValue(const GraphCanvas::Endpoint& endpoint) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2361,7 +2349,7 @@ namespace ScriptCanvasEditor return false; } - GraphCanvas::CanHandleMimeEventOutcome Graph::CanHandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) + GraphCanvas::CanHandleMimeEventOutcome EditorGraph::CanHandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) { AZ_UNUSED(endpoint); AZ_UNUSED(mimeData); @@ -2371,7 +2359,7 @@ namespace ScriptCanvasEditor return AZ::Failure(AZStd::string("Unimplemented drag and drop flow")); } - bool Graph::HandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) + bool EditorGraph::HandleValueMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) { AZ_UNUSED(endpoint); AZ_UNUSED(mimeData); @@ -2379,7 +2367,7 @@ namespace ScriptCanvasEditor return false; } - GraphCanvas::SlotId Graph::RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId, GraphModelRequests::ExtensionRequestReason reason) + GraphCanvas::SlotId EditorGraph::RequestExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId, GraphModelRequests::ExtensionRequestReason reason) { GraphCanvas::SlotId graphCanvasSlotId; @@ -2414,7 +2402,7 @@ namespace ScriptCanvasEditor return graphCanvasSlotId; } - void Graph::ExtensionCancelled(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) + void EditorGraph::ExtensionCancelled(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) { AZ::EntityId scNodeId = ConvertToScriptCanvasNodeId(nodeId); @@ -2429,7 +2417,7 @@ namespace ScriptCanvasEditor } } - void Graph::FinalizeExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) + void EditorGraph::FinalizeExtension(const GraphCanvas::NodeId& nodeId, const GraphCanvas::ExtenderId& extenderId) { AZ::EntityId scNodeId = ConvertToScriptCanvasNodeId(nodeId); @@ -2444,7 +2432,7 @@ namespace ScriptCanvasEditor } } - bool Graph::ShouldWrapperAcceptDrop(const AZ::EntityId& wrapperNode, const QMimeData* mimeData) const + bool EditorGraph::ShouldWrapperAcceptDrop(const AZ::EntityId& wrapperNode, const QMimeData* mimeData) const { if (!mimeData->hasFormat(Widget::NodePaletteDockWidget::GetMimeType())) { @@ -2492,7 +2480,7 @@ namespace ScriptCanvasEditor return true; } - void Graph::AddWrapperDropTarget(const AZ::EntityId& wrapperNode) + void EditorGraph::AddWrapperDropTarget(const AZ::EntityId& wrapperNode) { if (!m_wrapperNodeDropTarget.IsValid()) { @@ -2500,7 +2488,7 @@ namespace ScriptCanvasEditor } } - void Graph::RemoveWrapperDropTarget(const AZ::EntityId& wrapperNode) + void EditorGraph::RemoveWrapperDropTarget(const AZ::EntityId& wrapperNode) { if (m_wrapperNodeDropTarget == wrapperNode) { @@ -2508,7 +2496,7 @@ namespace ScriptCanvasEditor } } - GraphCanvas::GraphId Graph::GetGraphCanvasGraphId() const + GraphCanvas::GraphId EditorGraph::GetGraphCanvasGraphId() const { if (m_saveFormatConverted) { @@ -2525,7 +2513,7 @@ namespace ScriptCanvasEditor } } - NodeIdPair Graph::CreateCustomNode(const AZ::Uuid& typeId, const AZ::Vector2& position) + NodeIdPair EditorGraph::CreateCustomNode(const AZ::Uuid& typeId, const AZ::Vector2& position) { CreateCustomNodeMimeEvent mimeEvent(typeId); @@ -2539,7 +2527,7 @@ namespace ScriptCanvasEditor return NodeIdPair(); } - void Graph::AddCrcCache(const AZ::Crc32& crcValue, const AZStd::string& cacheString) + void EditorGraph::AddCrcCache(const AZ::Crc32& crcValue, const AZStd::string& cacheString) { auto mapIter = m_crcCacheMap.find(crcValue); @@ -2553,7 +2541,7 @@ namespace ScriptCanvasEditor } } - void Graph::RemoveCrcCache(const AZ::Crc32& crcValue) + void EditorGraph::RemoveCrcCache(const AZ::Crc32& crcValue) { auto mapIter = m_crcCacheMap.find(crcValue); @@ -2568,7 +2556,7 @@ namespace ScriptCanvasEditor } } - AZStd::string Graph::DecodeCrc(const AZ::Crc32& crcValue) + AZStd::string EditorGraph::DecodeCrc(const AZ::Crc32& crcValue) { auto mapIter = m_crcCacheMap.find(crcValue); @@ -2580,7 +2568,7 @@ namespace ScriptCanvasEditor return ""; } - void Graph::ClearHighlights() + void EditorGraph::ClearHighlights() { for (const GraphCanvas::GraphicsEffectId& effectId : m_highlights) { @@ -2590,7 +2578,7 @@ namespace ScriptCanvasEditor m_highlights.clear(); } - void Graph::HighlightMembersFromTreeItem(const GraphCanvas::GraphCanvasTreeItem* treeItem) + void EditorGraph::HighlightMembersFromTreeItem(const GraphCanvas::GraphCanvasTreeItem* treeItem) { ClearHighlights(); @@ -2608,7 +2596,7 @@ namespace ScriptCanvasEditor } } - void Graph::HighlightVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) + void EditorGraph::HighlightVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) { ClearHighlights(); @@ -2623,7 +2611,7 @@ namespace ScriptCanvasEditor } } - void Graph::HighlightNodes(const AZStd::vector& nodes) + void EditorGraph::HighlightNodes(const AZStd::vector& nodes) { ClearHighlights(); @@ -2633,7 +2621,7 @@ namespace ScriptCanvasEditor } } - void Graph::RemoveUnusedVariables() + void EditorGraph::RemoveUnusedVariables() { RequestPushPreventUndoStateUpdate(); auto variableData = GetVariableData(); @@ -2679,7 +2667,7 @@ namespace ScriptCanvasEditor } } - bool Graph::CanConvertVariableNodeToReference(const GraphCanvas::NodeId& nodeId) + bool EditorGraph::CanConvertVariableNodeToReference(const GraphCanvas::NodeId& nodeId) { AZ::EntityId scriptCanvasNodeId = ConvertToScriptCanvasNodeId(nodeId); @@ -2725,7 +2713,7 @@ namespace ScriptCanvasEditor return false; } - bool Graph::ConvertVariableNodeToReference(const GraphCanvas::NodeId& nodeId) + bool EditorGraph::ConvertVariableNodeToReference(const GraphCanvas::NodeId& nodeId) { AZ::EntityId scriptCanvasNodeId = ConvertToScriptCanvasNodeId(nodeId); @@ -2899,12 +2887,12 @@ namespace ScriptCanvasEditor return true; } - bool Graph::ConvertReferenceToVariableNode([[maybe_unused]] const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::ConvertReferenceToVariableNode([[maybe_unused]] const GraphCanvas::Endpoint& endpoint) { return false; } - bool Graph::OnVersionConversionBegin(ScriptCanvas::Node& scriptCanvasNode) + bool EditorGraph::OnVersionConversionBegin(ScriptCanvas::Node& scriptCanvasNode) { auto insertResult = m_convertingNodes.insert(scriptCanvasNode.GetEntityId()); @@ -2923,7 +2911,7 @@ namespace ScriptCanvasEditor return true; } - void Graph::OnVersionConversionEnd(ScriptCanvas::Node& scriptCanvasNode) + void EditorGraph::OnVersionConversionEnd(ScriptCanvas::Node& scriptCanvasNode) { EditorNodeNotificationBus::Event(scriptCanvasNode.GetEntityId(), &EditorNodeNotifications::OnVersionConversionEnd); @@ -3041,7 +3029,7 @@ namespace ScriptCanvasEditor } } - AZStd::vector Graph::GetNodesOfType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier) + AZStd::vector EditorGraph::GetNodesOfType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier) { AZStd::vector nodeIdPairs; @@ -3120,7 +3108,7 @@ namespace ScriptCanvasEditor return nodeIdPairs; } - AZStd::vector Graph::GetVariableNodes(const ScriptCanvas::VariableId& variableId) + AZStd::vector EditorGraph::GetVariableNodes(const ScriptCanvas::VariableId& variableId) { AZStd::vector variableNodes; @@ -3143,7 +3131,7 @@ namespace ScriptCanvasEditor return variableNodes; } - void Graph::QueueVersionUpdate(const AZ::EntityId& graphCanvasNodeId) + void EditorGraph::QueueVersionUpdate(const AZ::EntityId& graphCanvasNodeId) { bool queueUpdate = m_queuedConvertingNodes.empty(); auto insertResult = m_queuedConvertingNodes.insert(graphCanvasNodeId); @@ -3155,7 +3143,7 @@ namespace ScriptCanvasEditor } } - bool Graph::CanExposeEndpoint(const GraphCanvas::Endpoint& endpoint) + bool EditorGraph::CanExposeEndpoint(const GraphCanvas::Endpoint& endpoint) { bool isEnabled = false; @@ -3213,7 +3201,7 @@ namespace ScriptCanvasEditor return isEnabled && !isNodeling; } - ScriptCanvas::Endpoint Graph::ConvertToScriptCanvasEndpoint(const GraphCanvas::Endpoint& endpoint) const + ScriptCanvas::Endpoint EditorGraph::ConvertToScriptCanvasEndpoint(const GraphCanvas::Endpoint& endpoint) const { AZStd::any* userData = nullptr; @@ -3230,7 +3218,7 @@ namespace ScriptCanvasEditor return scriptCanvasEndpoint; } - GraphCanvas::Endpoint Graph::ConvertToGraphCanvasEndpoint(const ScriptCanvas::Endpoint& endpoint) const + GraphCanvas::Endpoint EditorGraph::ConvertToGraphCanvasEndpoint(const ScriptCanvas::Endpoint& endpoint) const { GraphCanvas::Endpoint graphCanvasEndpoint; @@ -3240,7 +3228,7 @@ namespace ScriptCanvasEditor return graphCanvasEndpoint; } - void Graph::OnSaveDataDirtied(const AZ::EntityId& savedElement) + void EditorGraph::OnSaveDataDirtied(const AZ::EntityId& savedElement) { // The EbusHandlerEvent's are a visual only representation of alternative data, and should not be saved. if (EBusHandlerEventNodeDescriptorRequestBus::FindFirstHandler(savedElement) != nullptr @@ -3292,12 +3280,12 @@ namespace ScriptCanvasEditor } } - bool Graph::NeedsSaveConversion() const + bool EditorGraph::NeedsSaveConversion() const { return !m_saveFormatConverted; } - void Graph::ConvertSaveFormat() + void EditorGraph::ConvertSaveFormat() { if (!m_saveFormatConverted) { @@ -3326,7 +3314,7 @@ namespace ScriptCanvasEditor } } - void Graph::ConstructSaveData() + void EditorGraph::ConstructSaveData() { // Save out the SceneData // @@ -3345,7 +3333,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnToastInteraction() + void EditorGraph::OnToastInteraction() { const AzToolsFramework::ToastId* toastId = AzToolsFramework::ToastNotificationBus::GetCurrentBusId(); @@ -3370,7 +3358,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnToastDismissed() + void EditorGraph::OnToastDismissed() { const AzToolsFramework::ToastId* toastId = AzToolsFramework::ToastNotificationBus::GetCurrentBusId(); @@ -3380,7 +3368,7 @@ namespace ScriptCanvasEditor } } - void Graph::OnUndoRedoEnd() + void EditorGraph::OnUndoRedoEnd() { for (const auto& nodePair : GetNodeMapping()) { @@ -3388,7 +3376,7 @@ namespace ScriptCanvasEditor } } - void Graph::ReportError(const ScriptCanvas::Node& node, const AZStd::string& errorSource, const AZStd::string& errorMessage) + void EditorGraph::ReportError(const ScriptCanvas::Node& node, const AZStd::string& errorSource, const AZStd::string& errorMessage) { AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Error, errorSource.c_str(), errorMessage.c_str()); @@ -3402,13 +3390,13 @@ namespace ScriptCanvasEditor m_toastNodeIds[toastId] = node.GetEntityId(); } - void Graph::UnregisterToast(const AzToolsFramework::ToastId& toastId) + void EditorGraph::UnregisterToast(const AzToolsFramework::ToastId& toastId) { AzToolsFramework::ToastNotificationBus::MultiHandler::BusDisconnect(toastId); m_toastNodeIds.erase(toastId); } - void Graph::DisplayUpdateToast() + void EditorGraph::DisplayUpdateToast() { GraphCanvas::ViewId viewId; GraphCanvas::SceneRequestBus::EventResult(viewId, GetGraphCanvasGraphId(), &GraphCanvas::SceneRequests::GetViewId); @@ -3442,12 +3430,12 @@ namespace ScriptCanvasEditor } } - const GraphStatisticsHelper& Graph::GetNodeUsageStatistics() const + const GraphStatisticsHelper& EditorGraph::GetNodeUsageStatistics() const { return m_statisticsHelper; } - void Graph::CreateGraphCanvasScene() + void EditorGraph::CreateGraphCanvasScene() { if (!m_saveFormatConverted) { @@ -3492,7 +3480,7 @@ namespace ScriptCanvasEditor m_focusHelper.SetActiveGraph(GetGraphCanvasGraphId()); } - bool Graph::UpgradeGraph(SourceHandle& asset, UpgradeRequest request, bool isVerbose) + bool EditorGraph::UpgradeGraph(SourceHandle& asset, UpgradeRequest request, bool isVerbose) { m_upgradeSM.SetAsset(asset); m_upgradeSM.SetVerbose(isVerbose); @@ -3509,7 +3497,7 @@ namespace ScriptCanvasEditor } } - void Graph::ConnectGraphCanvasBuses() + void EditorGraph::ConnectGraphCanvasBuses() { GraphCanvas::GraphId graphCanvasGraphId = GetGraphCanvasGraphId(); @@ -3517,14 +3505,14 @@ namespace ScriptCanvasEditor GraphCanvas::SceneNotificationBus::Handler::BusConnect(graphCanvasGraphId); } - void Graph::DisconnectGraphCanvasBuses() + void EditorGraph::DisconnectGraphCanvasBuses() { GraphCanvas::GraphModelRequestBus::Handler::BusDisconnect(); GraphCanvas::SceneNotificationBus::Handler::BusDisconnect(); } - void Graph::OnSystemTick() + void EditorGraph::OnSystemTick() { if (!m_allowVersionUpdate) { @@ -3539,7 +3527,7 @@ namespace ScriptCanvasEditor } } - void Graph::DisplayGraphCanvasScene() + void EditorGraph::DisplayGraphCanvasScene() { m_variableDataModel.Activate(GetScriptCanvasId()); @@ -3839,17 +3827,17 @@ namespace ScriptCanvasEditor MarkVersion(); } - void Graph::OnGraphCanvasSceneVisible() + void EditorGraph::OnGraphCanvasSceneVisible() { DisplayUpdateToast(); } - AZStd::unordered_map< AZ::EntityId, GraphCanvas::EntitySaveDataContainer* > Graph::GetGraphCanvasSaveData() + AZStd::unordered_map< AZ::EntityId, GraphCanvas::EntitySaveDataContainer* > EditorGraph::GetGraphCanvasSaveData() { return m_graphCanvasSaveData; } - void Graph::UpdateGraphCanvasSaveData(const AZStd::unordered_map< AZ::EntityId, GraphCanvas::EntitySaveDataContainer* >& saveData) + void EditorGraph::UpdateGraphCanvasSaveData(const AZStd::unordered_map< AZ::EntityId, GraphCanvas::EntitySaveDataContainer* >& saveData) { QScopedValueRollback ignoreRequests(m_ignoreSaveRequests, true); @@ -3868,7 +3856,7 @@ namespace ScriptCanvasEditor DisplayGraphCanvasScene(); } - void Graph::ClearGraphCanvasScene() + void EditorGraph::ClearGraphCanvasScene() { GraphCanvas::GraphId graphCanvasGraphId = GetGraphCanvasGraphId(); diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp index 2cd2dda89e..4e512a3678 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp @@ -171,7 +171,7 @@ namespace ScriptCanvasEditor } } - void GraphStatisticsHelper::PopulateStatisticData(const Graph* editorGraph) + void GraphStatisticsHelper::PopulateStatisticData(const EditorGraph* editorGraph) { // Opportunistically use this time to refresh out node count array. m_nodeIdentifierCount.clear(); diff --git a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp index fec813b0c1..d23c371096 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp @@ -25,7 +25,7 @@ namespace ScriptCanvasEditor namespace Helpers { - static AZStd::string ConnectionToText(ScriptCanvasEditor::Graph* graph, ScriptCanvas::Endpoint& from, ScriptCanvas::Endpoint& to) + static AZStd::string ConnectionToText(ScriptCanvasEditor::EditorGraph* graph, ScriptCanvas::Endpoint& from, ScriptCanvas::Endpoint& to) { AZ_Assert(graph, "A valid graph must be provided"); @@ -653,7 +653,7 @@ namespace ScriptCanvasEditor #define RegisterState(stateName) m_states.emplace_back(new stateName(this)); - EditorGraphUpgradeMachine::EditorGraphUpgradeMachine(Graph* graph) + EditorGraphUpgradeMachine::EditorGraphUpgradeMachine(EditorGraph* graph) : m_graph(graph) { RegisterState(Start); diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h index 9157aaeac9..aff47222e1 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h @@ -45,7 +45,7 @@ namespace ScriptCanvas namespace ScriptCanvasEditor { //! EditorGraph is the editor version of the ScriptCanvas::Graph component that is activated when executing the script canvas engine - class Graph + class EditorGraph : public ScriptCanvas::Graph , private NodeCreationNotificationBus::Handler , private SceneCounterRequestBus::Handler @@ -77,7 +77,7 @@ namespace ScriptCanvasEditor typedef AZStd::unordered_map< AZ::EntityId, AZ::EntityId > WrappedNodeGroupingMap; - static void ConvertToGetVariableNode(Graph* graph, ScriptCanvas::VariableId variableId, const AZ::EntityId& nodeId, AZStd::unordered_map& setVariableRemapping); + static void ConvertToGetVariableNode(EditorGraph* graph, ScriptCanvas::VariableId variableId, const AZ::EntityId& nodeId, AZStd::unordered_map& setVariableRemapping); struct CRCCache { @@ -100,13 +100,13 @@ namespace ScriptCanvasEditor }; public: - AZ_COMPONENT(Graph, "{4D755CA9-AB92-462C-B24F-0B3376F19967}", ScriptCanvas::Graph); + AZ_COMPONENT(EditorGraph, "{4D755CA9-AB92-462C-B24F-0B3376F19967}", ScriptCanvas::Graph); static ScriptCanvas::DataPtr Create(); static void Reflect(AZ::ReflectContext* context); - Graph(const ScriptCanvas::ScriptCanvasId& scriptCanvasId = AZ::Entity::MakeId()) + EditorGraph(const ScriptCanvas::ScriptCanvasId& scriptCanvasId = AZ::Entity::MakeId()) : ScriptCanvas::Graph(scriptCanvasId) , m_variableCounter(0) , m_graphCanvasSceneEntity(nullptr) @@ -115,11 +115,21 @@ namespace ScriptCanvasEditor , m_upgradeSM(this) {} - ~Graph() override; + ~EditorGraph() override; void Activate() override; void Deactivate() override; + static const char* GetMimeType() + { + return "application/x-o3de-scriptcanvas"; + } + + static const char* GetWrappedNodeGroupingMimeType() + { + return "application/x-03de-scriptcanvas-wrappednodegrouping"; + } + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { ScriptCanvas::Graph::GetProvidedServices(provided); @@ -326,7 +336,7 @@ namespace ScriptCanvasEditor void UnregisterToast(const AzToolsFramework::ToastId& toastId); - Graph(const Graph&) = delete; + EditorGraph(const EditorGraph&) = delete; void DisplayUpdateToast(); diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h index a4522198b7..d99da61d8d 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h @@ -28,7 +28,7 @@ namespace ScriptCanvasEditor // if CompleteDescription() succeeds, sets the handle to the result, else does nothing bool CompleteDescriptionInPlace(SourceHandle& source); - class Graph; + class EditorGraph; class NodePaletteModel; class NodeIdentifierFactory @@ -48,7 +48,7 @@ namespace ScriptCanvasEditor virtual ~GraphStatisticsHelper() = default; - void PopulateStatisticData(const Graph* editorGraph); + void PopulateStatisticData(const EditorGraph* editorGraph); AZStd::unordered_map< ScriptCanvas::NodeTypeIdentifier, int > m_nodeIdentifierCount; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h index 9fedc2d1f3..78b59e48d1 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h @@ -20,7 +20,7 @@ namespace ScriptCanvas namespace ScriptCanvasEditor { - class Graph; + class EditorGraph; class StateMachine; //! StateTraits provides each state the ability to provide its own compile time ID @@ -158,7 +158,7 @@ namespace ScriptCanvasEditor public: AZ_RTTI(EditorGraphUpgradeMachine, "{C7EABC22-A3DD-4ABE-8303-418EA3CD1246}", StateMachine); - EditorGraphUpgradeMachine(Graph* graph); + EditorGraphUpgradeMachine(EditorGraph* graph); AZStd::unordered_set m_allNodes; AZStd::unordered_set m_outOfDateNodes; @@ -180,7 +180,7 @@ namespace ScriptCanvasEditor bool m_graphNeedsDirtying = false; - Graph* m_graph = nullptr; + EditorGraph* m_graph = nullptr; SourceHandle m_asset; void SetAsset(SourceHandle& assetasset); diff --git a/Gems/ScriptCanvas/Code/Editor/ScriptCanvasEditorGem.cpp b/Gems/ScriptCanvas/Code/Editor/ScriptCanvasEditorGem.cpp index 7c204e8790..1a3bb0e4f9 100644 --- a/Gems/ScriptCanvas/Code/Editor/ScriptCanvasEditorGem.cpp +++ b/Gems/ScriptCanvas/Code/Editor/ScriptCanvasEditorGem.cpp @@ -81,7 +81,7 @@ namespace ScriptCanvas ScriptCanvasEditor::EditorAssetSystemComponent::CreateDescriptor(), ScriptCanvasEditor::EditorScriptCanvasComponent::CreateDescriptor(), ScriptCanvasEditor::EntityMimeDataHandler::CreateDescriptor(), - ScriptCanvasEditor::Graph::CreateDescriptor(), + ScriptCanvasEditor::EditorGraph::CreateDescriptor(), ScriptCanvasEditor::IconComponent::CreateDescriptor(), ScriptCanvasEditor::ReflectComponent::CreateDescriptor(), ScriptCanvasEditor::SystemComponent::CreateDescriptor(), diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp index 9bbdddfedb..a79cf2d6cf 100644 --- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp @@ -183,7 +183,7 @@ namespace ScriptCanvasEditor { if (entity) { - auto graph = entity->CreateComponent(); + auto graph = entity->CreateComponent(); entity->CreateComponent(graph->GetScriptCanvasId()); } } diff --git a/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.cpp b/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.cpp index f497b83b08..eb42daa3d8 100644 --- a/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.cpp @@ -35,7 +35,7 @@ namespace ScriptCanvasEditor { } - void GraphItemCommand::Capture(Graph*, bool) + void GraphItemCommand::Capture(EditorGraph*, bool) { } @@ -104,7 +104,7 @@ namespace ScriptCanvasEditor RestoreItem(m_redoState); } - void GraphItemChangeCommand::Capture(Graph* graph, bool captureUndo) + void GraphItemChangeCommand::Capture(EditorGraph* graph, bool captureUndo) { m_scriptCanvasId = graph->GetScriptCanvasId(); m_graphCanvasGraphId = graph->GetGraphCanvasGraphId(); @@ -203,7 +203,7 @@ namespace ScriptCanvasEditor RestoreItem(m_redoState); } - void GraphItemAddCommand::Capture(Graph* graph, bool) + void GraphItemAddCommand::Capture(EditorGraph* graph, bool) { GraphItemChangeCommand::Capture(graph, false); } @@ -224,7 +224,7 @@ namespace ScriptCanvasEditor RestoreItem(m_redoState); } - void GraphItemRemovalCommand::Capture(Graph* graph, bool) + void GraphItemRemovalCommand::Capture(EditorGraph* graph, bool) { GraphItemChangeCommand::Capture(graph, true); } diff --git a/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.h b/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.h index 9b36a7beb0..38eb1099ac 100644 --- a/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.h +++ b/Gems/ScriptCanvas/Code/Editor/Undo/ScriptCanvasGraphCommand.h @@ -44,7 +44,7 @@ namespace ScriptCanvasEditor void Undo() override; void Redo() override; - virtual void Capture(Graph* graph, bool captureUndo); + virtual void Capture(EditorGraph* graph, bool captureUndo); bool Changed() const override; @@ -74,7 +74,7 @@ namespace ScriptCanvasEditor void Undo() override; void Redo() override; - void Capture(Graph* graph, bool captureUndo) override; + void Capture(EditorGraph* graph, bool captureUndo) override; void RestoreItem(const AZStd::vector& restoreBuffer) override; @@ -101,7 +101,7 @@ namespace ScriptCanvasEditor void Undo() override; void Redo() override; - void Capture(Graph* graph, bool captureUndo) override; + void Capture(EditorGraph* graph, bool captureUndo) override; protected: GraphItemAddCommand(const GraphItemAddCommand&) = delete; @@ -122,7 +122,7 @@ namespace ScriptCanvasEditor void Undo() override; void Redo() override; - void Capture(Graph* graph, bool captureUndo) override; + void Capture(EditorGraph* graph, bool captureUndo) override; protected: GraphItemRemovalCommand(const GraphItemRemovalCommand&) = delete; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index f0bee2171a..f51467971d 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -1541,7 +1541,7 @@ namespace ScriptCanvasEditor { int outTabIndex = -1; - ScriptCanvas::DataPtr graph = Graph::Create(); + ScriptCanvas::DataPtr graph = EditorGraph::Create(); AZ::Uuid assetId = AZ::Uuid::CreateRandom(); ScriptCanvasEditor::SourceHandle handle = ScriptCanvasEditor::SourceHandle(graph, assetId, assetPath); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp index 39cd6f565e..7646ef9dcd 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp @@ -154,7 +154,7 @@ namespace ScriptCanvasEditor { asset.Mod()->UpgradeGraph ( asset - , m_view->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate + , m_view->forceUpgrade->isChecked() ? EditorGraph::UpgradeRequest::Forced : EditorGraph::UpgradeRequest::IfOutOfDate , m_view->verbose->isChecked()); } }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp index 1e00e70075..7f659952e8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp @@ -328,9 +328,9 @@ namespace ScriptCanvas return AZ::EntityUtils::FindFirstDerivedComponent(m_scriptCanvasEntity.get()); } - const ScriptCanvasEditor::Graph* ScriptCanvasData::GetEditorGraph() const + const ScriptCanvasEditor::EditorGraph* ScriptCanvasData::GetEditorGraph() const { - return reinterpret_cast(GetGraph()); + return reinterpret_cast(GetGraph()); } Graph* ScriptCanvasData::ModGraph() @@ -338,8 +338,8 @@ namespace ScriptCanvas return AZ::EntityUtils::FindFirstDerivedComponent(m_scriptCanvasEntity.get()); } - ScriptCanvasEditor::Graph* ScriptCanvasData::ModEditorGraph() + ScriptCanvasEditor::EditorGraph* ScriptCanvasData::ModEditorGraph() { - return reinterpret_cast(ModGraph()); + return reinterpret_cast(ModGraph()); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index c29a648eca..5de5c7adb8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -316,10 +316,10 @@ namespace ScriptCanvas namespace ScriptCanvasEditor { - class Graph; + class EditorGraph; - using GraphPtr = Graph*; - using GraphPtrConst = const Graph*; + using GraphPtr = EditorGraph*; + using GraphPtrConst = const EditorGraph*; class SourceDescription { @@ -411,11 +411,11 @@ namespace ScriptCanvas const Graph* GetGraph() const; - const ScriptCanvasEditor::Graph* GetEditorGraph() const; + const ScriptCanvasEditor::EditorGraph* GetEditorGraph() const; Graph* ModGraph(); - ScriptCanvasEditor::Graph* ModEditorGraph(); + ScriptCanvasEditor::EditorGraph* ModEditorGraph(); AZStd::unique_ptr m_scriptCanvasEntity; private: From 955a6db374f851e31c920b1d2e017fc315565330 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Thu, 30 Dec 2021 15:56:27 -0600 Subject: [PATCH 049/272] Converting Editor automated tests to utilize prefab system Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../hydra_editor_utils.py | 13 +++++-- .../AssetBrowser_SearchFiltering.py | 5 ++- .../AssetBrowser_TreeNavigation.py | 4 +-- .../editor/EditorScripts/AssetPicker_UI_UX.py | 3 +- ...flows_ExistingLevel_EntityComponentCRUD.py | 6 ++-- ...ditorWorkflows_LevelEntityComponentCRUD.py | 30 +++++++--------- .../ComponentCRUD_Add_Delete_Components.py | 6 ++-- .../EditorScripts/Docking_BasicDockedTools.py | 13 ++++--- .../EntityOutliner_EntityOrdering.py | 11 +++--- .../InputBindings_Add_Remove_Input_Events.py | 5 ++- .../EditorScripts/Menus_EditMenuOptions.py | 5 ++- .../EditorScripts/Menus_FileMenuOptions.py | 12 +++---- .../EditorScripts/Menus_ViewMenuOptions.py | 5 ++- .../Gem/PythonTests/editor/TestSuite_Main.py | 20 +++++------ .../editor/TestSuite_Main_Optimized.py | 33 +++++++++-------- .../PythonTests/editor/TestSuite_Periodic.py | 35 +++++++++++-------- .../PythonTests/editor/TestSuite_Sandbox.py | 4 +-- .../editor/TestSuite_Sandbox_Optimized.py | 2 -- 18 files changed, 105 insertions(+), 107 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py index 5e3828ad02..36fc6003f7 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py @@ -5,15 +5,22 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ +from typing import List +from math import isclose +import collections.abc + import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity import azlmbr.legacy.general as general import azlmbr.object -from typing import List -from math import isclose -import collections.abc +from editor_python_test_tools.utils import TestHelper as helper + + +def open_base_level(): + helper.init_idle() + helper.open_level("Prefab", "Base") def find_entity_by_name(entity_name): diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py index 7366faafdc..254224a2f8 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py @@ -59,8 +59,8 @@ def AssetBrowser_SearchFiltering(): import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()): indexes = [parent_index] @@ -80,8 +80,7 @@ def AssetBrowser_SearchFiltering(): return True # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Open Asset Browser (if not opened already) editor_window = pyside_utils.get_editor_main_window() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py index ecc77778cc..52072205b5 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_TreeNavigation.py @@ -53,6 +53,7 @@ def AssetBrowser_TreeNavigation(): import azlmbr.legacy.general as general import editor_python_test_tools.pyside_utils as pyside_utils + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper @@ -69,8 +70,7 @@ def AssetBrowser_TreeNavigation(): file_path = ("AutomatedTesting", "Assets", "ImageGradients", "image_grad_test_gsi.png") # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Open Asset Browser (if not opened already) editor_window = pyside_utils.get_editor_main_window() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py index 59a78c9e5d..047d6edf41 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetPicker_UI_UX.py @@ -215,8 +215,7 @@ def AssetPicker_UI_UX(): QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create entity and add Mesh component entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py index 39cacf9af5..48b7d2b176 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py @@ -56,19 +56,17 @@ def BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(): 06. delete parent entity """ + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report from editor_python_test_tools.editor_entity_utils import EditorEntity import azlmbr.bus as bus import azlmbr.editor as editor import azlmbr.entity as entity - import azlmbr.legacy.general as general import azlmbr.object # 01. load an existing level - test_level = 'Simple' - general.open_level_no_prompt(test_level) - Report.result(Tests.load_level, general.get_current_level_name() == test_level) + hydra.open_base_level() # 02. create parent entity and set name # Delete any exiting entity and Create a new Entity at the root level diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py index 9c5880ab1e..f13b924e30 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py @@ -31,7 +31,7 @@ class Tests: "Component removed from entity successfully", "Failed to remove component from entity" ) - level_saved_and_exported = ( + saved_and_exported = ( "Level saved and exported successfully", "Failed to save/export level" ) @@ -52,8 +52,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD(): - A new entity can be created - Entity hierarchy can be adjusted - Components can be added/removed/updated - - Level can be saved - - Level can be exported + - Level can be saved/exported Note: - This test file must be called from the O3DE Editor command terminal @@ -70,7 +69,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD(): import azlmbr.editor as editor import azlmbr.entity as entity import azlmbr.math as math - import azlmbr.paths + import azlmbr.paths as paths import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report @@ -84,7 +83,7 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD(): return None # 1) Create a new level - level = "tmp_level" + lvl_name = "tmp_level" editor_window = pyside_utils.get_editor_main_window() new_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "New Level") pyside_utils.trigger_action_async(new_level_action) @@ -95,23 +94,24 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD(): Report.info("New Level dialog opened") grp_box = new_level_dlg.findChild(QtWidgets.QGroupBox, "STATIC_GROUP1") level_name = grp_box.findChild(QtWidgets.QLineEdit, "LEVEL") - level_name.setText(level) + level_name.setText(lvl_name) button_box = new_level_dlg.findChild(QtWidgets.QDialogButtonBox, "buttonBox") button_box.button(QtWidgets.QDialogButtonBox.Ok).click() # Verify new level was created successfully level_create_success = await pyside_utils.wait_for_condition(lambda: editor.EditorToolsApplicationRequestBus( - bus.Broadcast, "GetCurrentLevelName") == level, 5.0) + bus.Broadcast, "GetCurrentLevelName") == lvl_name, 5.0) Report.critical_result(Tests.level_created, level_create_success) # 2) Delete existing entities, and create and manipulate new entities via Entity Inspector search_filter = azlmbr.entity.SearchFilter() all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) - entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "OutlinerWidgetUI") + entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "EntityOutlinerWidgetUI") outliner_object_list = entity_outliner_widget.findChild(QtWidgets.QWidget, "m_objectList_Contents") outliner_tree = outliner_object_list.findChild(QtWidgets.QWidget, "m_objectTree") - await pyside_utils.trigger_context_menu_entry(outliner_tree, "Create entity") + outliner_viewport = outliner_tree.findChild(QtWidgets.QWidget, "qt_scrollarea_viewport") + await pyside_utils.trigger_context_menu_entry(outliner_viewport, "Create entity") # Find the new entity parent_entity_id = find_entity_by_name("Entity1") @@ -153,14 +153,10 @@ def BasicEditorWorkflows_LevelEntityComponentCRUD(): save_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "Save") pyside_utils.trigger_action_async(save_level_action) - # 5) Export the level - export_action = pyside_utils.get_action_for_menu_path(editor_window, "Game", "Export to Engine") - pyside_utils.trigger_action_async(export_action) - level_pak_file = os.path.join( - "AutomatedTesting", "Levels", level, "level.pak" - ) - export_success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_pak_file), 5.0) - Report.result(Tests.level_saved_and_exported, export_success) + # 5) Verify the save/export of the level + level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable") + success = await pyside_utils.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0) + Report.result(Tests.saved_and_exported, success) run_test() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py index 779f1ef953..6772450405 100755 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/ComponentCRUD_Add_Delete_Components.py @@ -63,7 +63,7 @@ def ComponentCRUD_Add_Delete_Components(): :return: None """ - from PySide2 import QtWidgets, QtTest, QtCore + from PySide2 import QtWidgets, QtTest from PySide2.QtCore import Qt import azlmbr.legacy.general as general @@ -74,7 +74,6 @@ def ComponentCRUD_Add_Delete_Components(): import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper async def add_component(component_name): pyside_utils.click_button_async(add_comp_btn) @@ -88,8 +87,7 @@ def ComponentCRUD_Add_Delete_Components(): QtTest.QTest.keyClick(tree, Qt.Key_Enter, Qt.NoModifier) # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Create entity entity_position = math.Vector3(125.0, 136.0, 32.0) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py index 6683fc952a..d83db7d90c 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py @@ -62,12 +62,11 @@ def Docking_BasicDockedTools(): import azlmbr.editor as editor import azlmbr.entity as entity + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper # Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # Make sure the Entity Outliner, Entity Inspector and Console tools are open general.open_pane("Entity Outliner (PREVIEW)") @@ -80,7 +79,7 @@ def Docking_BasicDockedTools(): editor.EditorEntityAPIBus(bus.Event, 'SetName', entity_id, entity_original_name) editor_window = pyside_utils.get_editor_main_window() - entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)") + entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") # 1) Open the tools and dock them together in a floating tabbed widget. # We drag/drop it over the viewport since it doesn't allow docking, so this will undock it @@ -89,7 +88,7 @@ def Docking_BasicDockedTools(): # We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved # to the floating window, its parent changes so the wrapped intance we had becomes invalid - entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)") + entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") # Dock the Entity Inspector tabbed with the floating Entity Outliner entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") @@ -106,7 +105,7 @@ def Docking_BasicDockedTools(): # Check to ensure all the tools are parented to the same QStackedWidget def check_all_panes_tabbed(): entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") - entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)") + entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") console = editor_window.findChild(QtWidgets.QDockWidget, "Console") entity_inspector_parent = entity_inspector.parentWidget() entity_outliner_parent = entity_outliner.parentWidget() @@ -122,7 +121,7 @@ def Docking_BasicDockedTools(): # 2.1,2) Select an Entity in the Entity Outliner. entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") - entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner (PREVIEW)") + entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") console = editor_window.findChild(QtWidgets.QDockWidget, "Console") object_tree = entity_outliner.findChild(QtWidgets.QTreeView, "m_objectTree") test_entity_index = pyside_utils.find_child_by_pattern(object_tree, entity_original_name) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py index 5fa8130302..fab7984df9 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EntityOutliner_EntityOrdering.py @@ -30,11 +30,13 @@ def EntityOutliner_EntityOrdering(): 5) Add another new entity, ensure the rest of the order is unchanged """ - import editor_python_test_tools.pyside_utils as pyside_utils + from PySide2 import QtCore + import azlmbr.legacy.general as general + + import editor_python_test_tools.hydra_editor_utils as hydra + import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper - from PySide2 import QtCore, QtWidgets, QtGui, QtTest # Grab the Editor, Entity Outliner, and Outliner Model editor_window = pyside_utils.get_editor_main_window() @@ -110,8 +112,7 @@ def EntityOutliner_EntityOrdering(): expected_order = [] # 1) Open the empty Prefab Base level - helper.init_idle() - helper.open_level("Prefab", "Base") + hydra.open_base_level() # 2) Add 5 entities to the outliner ENTITIES_TO_ADD = 5 diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py index f4769dab4d..07c89ff110 100755 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/InputBindings_Add_Remove_Input_Events.py @@ -69,8 +69,8 @@ def InputBindings_Add_Remove_Input_Events(): import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper def open_asset_editor(): general.open_pane("Asset Editor") @@ -81,8 +81,7 @@ def InputBindings_Add_Remove_Input_Events(): return not general.is_pane_visible("Asset Editor") # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Open Asset Editor Report.result(Tests.asset_editor_opened, open_asset_editor()) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index bd213be293..7d72d76776 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -26,9 +26,9 @@ def Menus_EditMenuOptions_Work(): :return: None """ + import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper edit_menu_options = [ ("Undo",), @@ -57,8 +57,7 @@ def Menus_EditMenuOptions_Work(): ] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Interact with Edit Menu options editor_window = pyside_utils.get_editor_main_window() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index a3e7611b5e..cade2125e2 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -26,29 +26,27 @@ def Menus_FileMenuOptions_Work(): :return: None """ + import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper file_menu_options = [ ("New Level",), - ("Open Level",), + #("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 ("Import",), ("Save",), - ("Save As",), + #("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 ("Save Level Statistics",), ("Edit Project Settings",), - ("Edit Platform Settings",), + #("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604 ("New Project",), ("Open Project",), ("Show Log File",), - ("Resave All Slices",), ("Exit",), ] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Interact with File Menu options editor_window = pyside_utils.get_editor_main_window() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py index deff2855a0..2d92fdb97c 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py @@ -26,9 +26,9 @@ def Menus_ViewMenuOptions_Work(): :return: None """ + import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper view_menu_options = [ ("Center on Selection",), @@ -45,8 +45,7 @@ def Menus_ViewMenuOptions_Work(): ] # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Physics", "Base") + hydra.open_base_level() # 2) Interact with View Menu options editor_window = pyside_utils.get_editor_main_window() diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py index c9e91687e0..949aab140d 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py @@ -33,22 +33,20 @@ class TestAutomation(TestAutomationBase): def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, remove_test_level): from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) @pytest.mark.REQUIRES_gpu def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, remove_test_level): from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, - use_null_renderer=False, enable_prefab_system=False) + use_null_renderer=False) - def test_EntityOutlienr_EntityOrdering(self, request, workspace, editor, launcher_platform): + def test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(self, request, workspace, editor, + launcher_platform): + from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + + def test_EntityOutliner_EntityOrdering(self, request, workspace, editor, launcher_platform): from .EditorScripts import EntityOutliner_EntityOrdering as test_module - self._run_test( - request, - workspace, - editor, - test_module, - batch_mode=False, - autotest_mode=True, - ) + self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py index d87fd8625b..7364cd8bc9 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -12,7 +12,6 @@ import ly_test_tools.environment.file_system as file_system from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) @@ -21,8 +20,12 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests # interact with modal dialogs global_extra_cmdline_args = [] - - enable_prefab_system = False + + class test_AssetPicker_UI_UX(EditorSharedTest): + from .EditorScripts import AssetPicker_UI_UX as test_module + + class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSingleTest): + from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest): # Custom teardown to remove slice asset created during test @@ -45,9 +48,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest): from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module - class test_AssetPicker_UI_UX(EditorSharedTest): - from .EditorScripts import AssetPicker_UI_UX as test_module - @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @@ -57,23 +57,26 @@ class TestAutomationAutoTestMode(EditorTestSuite): # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions global_extra_cmdline_args = ["-autotest_mode"] - enable_prefab_system = False + class test_AssetBrowser_SearchFiltering(EditorSharedTest): + from .EditorScripts import AssetBrowser_SearchFiltering as test_module class test_AssetBrowser_TreeNavigation(EditorSharedTest): from .EditorScripts import AssetBrowser_TreeNavigation as test_module - class test_AssetBrowser_SearchFiltering(EditorSharedTest): - from .EditorScripts import AssetBrowser_SearchFiltering as test_module - class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest): from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module - class test_Menus_ViewMenuOptions_Work(EditorSharedTest): - from .EditorScripts import Menus_ViewMenuOptions as test_module + class test_Docking_BasicDockedTools(EditorSharedTest): + from .EditorScripts import Docking_BasicDockedTools as test_module + + class test_EntityOutliner_EntityOrdering(EditorSharedTest): + from .EditorScripts import EntityOutliner_EntityOrdering as test_module + + class test_Menus_EditMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_EditMenuOptions as test_module - @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208") class test_Menus_FileMenuOptions_Work(EditorSharedTest): from .EditorScripts import Menus_FileMenuOptions as test_module - class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest): - from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module + class test_Menus_ViewMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_ViewMenuOptions as test_module \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py index 1bd1d7f987..f8a054d517 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py @@ -10,6 +10,7 @@ import pytest import sys import ly_test_tools.environment.file_system as file_system +import ly_test_tools.environment.process_utils as process_utils sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') from base import TestAutomationBase @@ -25,36 +26,42 @@ def remove_test_level(request, workspace, project): request.addfinalizer(teardown) +@pytest.fixture +def kill_external_tools(request): + def teardown(): + process_utils.kill_processes_named("o3de.exe") + request.addfinalizer(teardown) + + @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): - def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetBrowser_TreeNavigation as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) - def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform): from .EditorScripts import AssetBrowser_SearchFiltering as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False) + + def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform): + from .EditorScripts import AssetBrowser_TreeNavigation as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform): from .EditorScripts import AssetPicker_UI_UX as test_module - self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False) def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform): from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False) def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform): from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + + def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform, kill_external_tools): + from .EditorScripts import Menus_FileMenuOptions as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform): from .EditorScripts import Menus_ViewMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) - - @pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208") - def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Menus_FileMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py index 8a56a2dbfd..98a6620d9c 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py @@ -20,8 +20,8 @@ class TestAutomation(TestAutomationBase): def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform): from .EditorScripts import Menus_EditMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False) def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform): from .EditorScripts import Docking_BasicDockedTools as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py index ce0d5e43e9..4a472095ae 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py @@ -19,8 +19,6 @@ class TestAutomationAutoTestMode(EditorTestSuite): # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions global_extra_cmdline_args = ["-autotest_mode"] - enable_prefab_system = False - class test_Docking_BasicDockedTools(EditorSharedTest): from .EditorScripts import Docking_BasicDockedTools as test_module From a7d173db3d530dbf0d5f0067e05e4bd8ea422406 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Mon, 3 Jan 2022 16:15:35 -0800 Subject: [PATCH 050/272] changes from review and switching to assert model instead of return bool Signed-off-by: Scott Murray --- .../editor_entity_utils.py | 164 ++++++++++-------- 1 file changed, 93 insertions(+), 71 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 58d9e30f81..0878431054 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -8,7 +8,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT # Built-in Imports from __future__ import annotations from typing import List, Tuple, Union - +from enum import Enum +import warnings # Open 3D Engine Imports import azlmbr @@ -21,15 +22,21 @@ import azlmbr.legacy.general as general from editor_python_test_tools.utils import Report +class Entity_Type(Enum): + GAME = azlmbr.entity.EntityType().Game + LEVEL = azlmbr.entity.EntityType().Level + + class EditorComponent: """ EditorComponent class used to set and get the component property value using path EditorComponent object is returned from either of EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_components_of_type() which also assigns self.id and self.type_id to the EditorComponent object. + self.type_id is the UUID for the component type as provided by an ebus call. """ - def __init__(self, type_id): + def __init__(self, type_id: uuid): self.type_id = type_id self.id = None self.property_tree = None @@ -88,51 +95,59 @@ class EditorComponent: :param component_property_path: String of component property. (e.g. 'Settings|Visible') :return: Count of items in the container as unsigned integer """ - if self.is_property_container(component_property_path): - container_count_outcome = self.property_tree.get_container_count(component_property_path) - assert ( - container_count_outcome.IsSuccess() - ), f"Failure: get_container_count did not return success for '{component_property_path}'" - return container_count_outcome.GetValue() + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + container_count_outcome = self.property_tree.get_container_count(component_property_path) + assert ( + container_count_outcome.IsSuccess() + ), f"Failure: get_container_count did not return success for '{component_property_path}'" + return container_count_outcome.GetValue() - def reset_container(self, component_property_path: str) -> bool: + def reset_container(self, component_property_path: str): """ Used to rest a container to empty :param component_property_path: String of component property. (e.g. 'Settings|Visible') - :return: Boolean success + :return: None """ - if self.is_property_container(component_property_path): - reset_outcome = self.property_tree.reset_container(component_property_path) - return reset_outcome.IsSuccess() - else: - return False + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + reset_outcome = self.property_tree.reset_container(component_property_path) + assert ( + reset_outcome.IsSuccess() + ), f"Failure: could not reset_container on '{component_property_path}'" - def append_container_item(self, component_property_path: str, value: any) -> bool: + def append_container_item(self, component_property_path: str, value: any): """ Used to append a container item without providing an index key. :param component_property_path: String of component property. (e.g. 'Settings|Visible') :param value: Value to be set - :return: Boolean success + :return: None """ - if self.is_property_container(component_property_path): - append_outcome = self.property_tree.append_container_item(component_property_path, value) - return append_outcome.IsSuccess() - else: - return False + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + append_outcome = self.property_tree.append_container_item(component_property_path, value) + assert ( + append_outcome.IsSuccess() + ), f"Failure: could not append_container_item to '{component_property_path}'" - def add_container_item(self, component_property_path: str, key: any, value: any) -> bool: + def add_container_item(self, component_property_path: str, key: any, value: any): """ Used to add a container item at a specified key. In practice key should be an integer index. :param component_property_path: String of component property. (e.g. 'Settings|Visible') :param key: Zero index integer key, although this could be any unique unused key value :param value: Value to be set - :return: Boolean success + :return: None """ - if self.is_property_container(component_property_path): - add_outcome = self.property_tree.add_container_item(component_property_path, key, value) - return add_outcome.IsSuccess() - else: - return False + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + add_outcome = self.property_tree.add_container_item(component_property_path, key, value) + assert ( + add_outcome.IsSuccess() + ), f"Failure: could not add_container_item '{key}' to '{component_property_path}'" def get_container_item(self, component_property_path: str, key: any) -> any: """ @@ -141,27 +156,29 @@ class EditorComponent: :param key: Zero index integer key :return: Value stored at the key specified """ - if self.is_property_container(component_property_path): - get_outcome = self.property_tree.get_container_item(component_property_path, key) - assert ( - get_outcome.IsSuccess() - ), f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]" - return get_outcome.GetValue() - else: - return None + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + get_outcome = self.property_tree.get_container_item(component_property_path, key) + assert ( + get_outcome.IsSuccess() + ), f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]" + return get_outcome.GetValue() - def remove_container_item(self, component_property_path: str, key: any) -> bool: + def remove_container_item(self, component_property_path: str, key: any): """ Used to remove a container item value at the specified key. In practice key should be an integer index. :param component_property_path: String of component property. (e.g. 'Settings|Visible') :param key: Zero index integer key - :return: Boolean success + :return: None """ - if self.is_property_container(component_property_path): - remove_outcome = self.property_tree.remove_container_item(component_property_path, key) - return remove_outcome.IsSuccess() - else: - return False + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + remove_outcome = self.property_tree.remove_container_item(component_property_path, key) + assert ( + remove_outcome.IsSuccess() + ), f"Failure: could not remove_container_item '{key}' from '{component_property_path}'" def update_container_item(self, component_property_path: str, key: any, value: any): """ @@ -169,13 +186,15 @@ class EditorComponent: :param component_property_path: String of component property. (e.g. 'Settings|Visible') :param key: Zero index integer key :param value: Value to be set - :return: Boolean success + :return: None """ - if self.is_property_container(component_property_path): - update_outcome = self.property_tree.update_container_item(component_property_path, key, value) - return update_outcome.IsSuccess() - else: - return False + assert ( + self.is_property_container(component_property_path) + ), f"Failure: '{component_property_path}' is not a property container" + update_outcome = self.property_tree.update_container_item(component_property_path, key, value) + assert ( + update_outcome.IsSuccess() + ), f"Failure: could not update '{key}' in '{component_property_path}'" def get_component_property_value(self, component_property_path: str): """ @@ -211,30 +230,33 @@ class EditorComponent: """ return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", self.id) + def set_enabled(self, new_state: bool): + """ + Used to set the component enabled state + :param new_state: Boolean enabled True, disabled False + :return: None + """ + if new_state: + editor.EditorComponentAPIBus(bus.Broadcast, "EnableComponents", [self.id]) + else: + editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) + def disable_component(self): """ Used to disable the component using its id value. :return: None """ + warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning) editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) - def enable_component(self): - """ - used to enable the componet using its id value - """ - editor.EditorComponentAPIBus(bus.Broadcast, "EnabledComponents", [self.id]) - @staticmethod - def get_type_ids(component_names: list, entity_type: str ='Game') -> list: + def get_type_ids(component_names: list, entity_type: Entity_Type = Entity_Type.GAME) -> list: """ Used to get type ids of given components list - :param: component_names: List of components to get type ids - :return: List of type ids of given components. + :param component_names: List of components to get type ids + :param entity_type: Entity_Type enum value Entity_Type.GAME is the default + :return: List of type ids of given components. Type id is a UUID as provided by the ebus call """ - if entity_type.lower() == 'level': - entity_type = azlmbr.entity.EntityType().Level - else: - entity_type = azlmbr.entity.EntityType().Game type_ids = editor.EditorComponentAPIBus( bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, entity_type) return type_ids @@ -402,7 +424,7 @@ class EditorEntity: :return: List of newly added components to the entity """ components = [] - type_ids = EditorComponent.get_type_ids(component_names) + type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) for type_id in type_ids: new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorComponentAPIBus( @@ -430,7 +452,7 @@ class EditorEntity: :param component_names: List of component names to remove :return: None """ - type_ids = EditorComponent.get_type_ids(component_names) + type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) for type_id in type_ids: remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id]) assert ( @@ -444,7 +466,7 @@ class EditorEntity: :return: List of Entity Component objects of given component name """ component_list = [] - type_ids = EditorComponent.get_type_ids(component_names) + type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) for type_id in type_ids: component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorComponentAPIBus( @@ -464,7 +486,7 @@ class EditorEntity: :param component_name: Name of component to check for :return: True, if entity has specified component. Else, False """ - type_ids = EditorComponent.get_type_ids([component_name]) + type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.GAME) return editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", self.id, type_ids[0]) def get_start_status(self) -> int: @@ -666,7 +688,7 @@ class EditorLevelEntity: :return: List of newly added components to the level """ components = [] - type_ids = EditorComponent.get_type_ids(component_names, 'level') + type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.LEVEL) for type_id in type_ids: new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorLevelComponentAPIBus( @@ -687,7 +709,7 @@ class EditorLevelEntity: :return: List of Level Component objects of given component name """ component_list = [] - type_ids = EditorComponent.get_type_ids(component_names, 'level') + type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.LEVEL) for type_id in type_ids: component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorLevelComponentAPIBus( @@ -708,7 +730,7 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: True, if level has specified component. Else, False """ - type_ids = EditorComponent.get_type_ids([component_name], 'level') + type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.LEVEL) return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0]) @staticmethod @@ -718,5 +740,5 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: integer count of occurences of level component attached to level or zero if none are present """ - type_ids = EditorComponent.get_type_ids([component_name], 'level') + type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.LEVEL) return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0]) From aefe1aa8b9e82f3fccb86cb053d2656d70d35fc2 Mon Sep 17 00:00:00 2001 From: Tobias Alexander Franke Date: Thu, 16 Dec 2021 11:43:24 +0800 Subject: [PATCH 051/272] Fix: Tube spline Signed-off-by: T.J. McGrath-Daly --- Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp index d96fc8c9ce..194204dd93 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp @@ -124,8 +124,14 @@ namespace LmbrCentral void TubeShapeDebugDisplayComponent::GenerateVertices() { + if (!m_spline) + { + AZ_Error("TubeShapeComponent", false, "A TubeShape must have a Spline to work"); + return; + } + const AZ::u32 endSegments = m_spline->IsClosed() ? 0 : m_tubeShapeMeshConfig.m_endSegments; GenerateTubeMesh( - m_spline, m_radiusAttribute, m_radius, m_tubeShapeMeshConfig.m_endSegments, + m_spline, m_radiusAttribute, m_radius, endSegments, m_tubeShapeMeshConfig.m_sides, m_tubeShapeMesh.m_vertexBuffer, m_tubeShapeMesh.m_indexBuffer, m_tubeShapeMesh.m_lineBuffer); } From c7d72bc6b68a93e194466eac80fdb17d78acf22f Mon Sep 17 00:00:00 2001 From: Tobias Alexander Franke Date: Wed, 17 Nov 2021 15:30:46 +0800 Subject: [PATCH 052/272] Ragdoll saving issue Signed-off-by: T.J. McGrath-Daly --- .../Code/Source/Editor/Plugins/Ragdoll/RagdollNodeWidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeWidget.cpp b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeWidget.cpp index 29745beb68..538ad3ba52 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeWidget.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeWidget.cpp @@ -125,6 +125,10 @@ namespace EMotionFX Physics::RagdollNodeConfiguration* ragdollNodeConfig = GetRagdollNodeConfig(); if (ragdollNodeConfig) { + AzPhysics::JointConfiguration* jointLimitConfig = ragdollNodeConfig->m_jointConfig.get(); + jointLimitConfig->SetPropertyVisibility(AzPhysics::JointConfiguration::PropertyVisibility::ParentLocalRotation, jointLimitConfig != nullptr); + jointLimitConfig->SetPropertyVisibility(AzPhysics::JointConfiguration::PropertyVisibility::ChildLocalRotation, jointLimitConfig != nullptr); + m_addColliderButton->show(); m_addRemoveButton->setText("Remove from ragdoll"); From e4880cf9a18617b2504cf64ac73bc6b16996777c Mon Sep 17 00:00:00 2001 From: Tobias Alexander Franke Date: Tue, 21 Dec 2021 19:35:34 +0800 Subject: [PATCH 053/272] Fix: Right hand bones misplaced Signed-off-by: T.J. McGrath-Daly --- .../Code/EMotionFX/Rendering/Common/RenderUtil.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Rendering/Common/RenderUtil.cpp b/Gems/EMotionFX/Code/EMotionFX/Rendering/Common/RenderUtil.cpp index 6fd28ee72f..b1dd26061a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Rendering/Common/RenderUtil.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Rendering/Common/RenderUtil.cpp @@ -952,7 +952,15 @@ namespace MCommon } else { - worldTM = AZ::Transform::CreateFromQuaternion(MCore::AzEulerAnglesToAzQuat(0.0f, 0.0f, MCore::Math::DegreesToRadians(180.0f))); + if (direction.GetX() > 0) + { + worldTM = AZ::Transform::CreateFromQuaternion(MCore::AzEulerAnglesToAzQuat(MCore::Math::DegreesToRadians(180.0f), 0.0f, MCore::Math::DegreesToRadians(180.0f))); + } + else + { + worldTM = AZ::Transform::CreateFromQuaternion(MCore::AzEulerAnglesToAzQuat(0.0f, 0.0f, 0.0f)); + } + } // set the cylinder to the given position From 4426d15d32c76d924e6870c4006cada0704295ef Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 4 Jan 2022 11:25:13 -0600 Subject: [PATCH 054/272] Adding explicit wait to avoid teardown issues with external tools Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../editor/EditorScripts/Menus_FileMenuOptions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index cade2125e2..c319535c05 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -26,6 +26,8 @@ def Menus_FileMenuOptions_Work(): :return: None """ + import azlmbr.legacy.general as general + import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report @@ -64,6 +66,9 @@ def Menus_FileMenuOptions_Work(): ) Report.result(menu_action_triggered, action_triggered) + # Wait a few seconds for Project Settings dialogs to load so teardown can properly close them + general.idle_wait(2.0) + if __name__ == "__main__": From a891993c35091f4eb3f18ff1ac91c944b08d22ef Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Tue, 4 Jan 2022 09:58:30 -0800 Subject: [PATCH 055/272] Remove 'INF' from integer widget and replace it with better formatted integers. Also fix warning message with invalid param Signed-off-by: mrieggeramzn --- .../UI/PropertyEditor/PropertyIntCtrlCommon.h | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h index bb7d03367b..7d3e7191e3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h @@ -93,23 +93,13 @@ namespace AzToolsFramework toolTipString += "\n"; } toolTipString += "["; - if (propertyControl->minimum() <= aznumeric_cast(QtWidgetLimits::Min())) - { - toolTipString += "-" + QObject::tr(PropertyQTConstant_InfinityString); - } - else - { - toolTipString += QString::number(propertyControl->minimum()); - } + + const QString minString = QLocale().toString(propertyControl->minimum()); + const QString maxString = QLocale().toString(propertyControl->maximum()); + + toolTipString += minString; toolTipString += ", "; - if (propertyControl->maximum() >= aznumeric_cast(QtWidgetLimits::Max())) - { - toolTipString += QObject::tr(PropertyQTConstant_InfinityString); - } - else - { - toolTipString += QString::number(propertyControl->maximum()); - } + toolTipString += maxString; toolTipString += "]"; return true; } @@ -128,15 +118,12 @@ namespace AzToolsFramework { toolTipString += "\n"; } - toolTipString += "[" + QString::number(propertyControl->minimum()) + ", "; - if (propertyControl->maximum() >= aznumeric_cast(QtWidgetLimits::Max())) - { - toolTipString += QObject::tr(PropertyQTConstant_InfinityString); - } - else - { - toolTipString += QString::number(propertyControl->maximum()); - } + + const QString minString = QLocale().toString(propertyControl->minimum()); + const QString maxString = QLocale().toString(propertyControl->maximum()); + + toolTipString += "[" + minString + ", "; + toolTipString += maxString; toolTipString += "]"; return true; } @@ -196,7 +183,7 @@ namespace AzToolsFramework } else { - AZ_WarningOnce("AzToolsFramework", false, "Property %s: 'Min' attribute from property '%s' into widget", debugName); + AZ_WarningOnce("AzToolsFramework", false, "Failed to read 'Min' attribute from property '%s' into widget", debugName); } } else if (attrib == AZ::Edit::Attributes::Max) From d343caa3f2d846610b4b1a29adac682d9e567867 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 4 Jan 2022 11:58:17 -0800 Subject: [PATCH 056/272] add optional force_get to get_property_tree Signed-off-by: Scott Murray --- .../editor_python_test_tools/editor_entity_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 0878431054..4dd7ec1446 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -50,7 +50,7 @@ class EditorComponent: assert len(type_names) != 0, "Component object does not have type id" return type_names[0] - def get_property_tree(self): + def get_property_tree(self, force_get: bool = False): """ Used to get the property tree object of component that has following functions associated with it: 1. prop_tree.is_container(path) @@ -60,9 +60,10 @@ class EditorComponent: 5. prop_tree.remove_container_item(path, key) 6. prop_tree.update_container_item(path, key, value) 7. prop_tree.get_container_item(path, key) + :param force_get: Force a fresh property tree to be returned rather than using an existing self.property_tree :return: Property tree object of a component """ - if self.property_tree is not None: + if (not force_get) and (self.property_tree is not None): return self.property_tree build_prop_tree_outcome = editor.EditorComponentAPIBus( @@ -244,6 +245,7 @@ class EditorComponent: def disable_component(self): """ Used to disable the component using its id value. + Deprecation warning! Use set_enable(False) instead as this method is in deprecation :return: None """ warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning) From 30e21bc2d115f9309a3629df0ac71837861d8e8a Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Tue, 4 Jan 2022 14:52:00 -0800 Subject: [PATCH 057/272] Updating formatting Signed-off-by: mrieggeramzn --- .../UI/PropertyEditor/PropertyIntCtrlCommon.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h index 7d3e7191e3..504e3fd0dc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h @@ -92,15 +92,11 @@ namespace AzToolsFramework { toolTipString += "\n"; } - toolTipString += "["; const QString minString = QLocale().toString(propertyControl->minimum()); const QString maxString = QLocale().toString(propertyControl->maximum()); + toolTipString += QString("[%1, %2]").arg(minString).arg(maxString); - toolTipString += minString; - toolTipString += ", "; - toolTipString += maxString; - toolTipString += "]"; return true; } return false; @@ -121,10 +117,8 @@ namespace AzToolsFramework const QString minString = QLocale().toString(propertyControl->minimum()); const QString maxString = QLocale().toString(propertyControl->maximum()); + toolTipString += QString("[%1, %2]").arg(minString).arg(maxString); - toolTipString += "[" + minString + ", "; - toolTipString += maxString; - toolTipString += "]"; return true; } return false; From 41c0fb2b02a285c2682785d8ae22e54a652a1f0a Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 4 Jan 2022 17:41:58 -0800 Subject: [PATCH 058/272] Address some review feedback Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 2 +- Code/Framework/AzCore/AzCore/DOM/DomUtils.h | 2 +- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 248 +++++++++++------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 38 +-- .../AzCore/AzCore/DOM/DomValueWriter.cpp | 4 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 4 +- .../AzCore/Tests/DOM/DomValueTests.cpp | 46 ++-- 7 files changed, 203 insertions(+), 141 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index d65497e194..73c4bd2d76 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -22,7 +22,7 @@ namespace AZ::Dom::Utils return backend.ReadFromBufferInPlace(string.data(), string.size(), visitor); } - AZ::Outcome WriteToValue(Backend::WriteCallback writeCallback) + AZ::Outcome WriteToValue(const Backend::WriteCallback& writeCallback) { Value value; AZStd::unique_ptr writer = value.GetWriteHandler(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h index f03e5b66b8..ebe4273b48 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h @@ -16,5 +16,5 @@ namespace AZ::Dom::Utils Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor); Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor); - AZ::Outcome WriteToValue(Backend::WriteCallback writeCallback); + AZ::Outcome WriteToValue(const Backend::WriteCallback& writeCallback); } // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 7401a5ac98..8c002b7091 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -12,22 +12,22 @@ namespace AZ::Dom { - template - AZStd::shared_ptr& CheckCopyOnWrite(AZStd::shared_ptr& refCountedPointer) - { - if (refCountedPointer.use_count() == 1) - { - return refCountedPointer; - } - else - { - refCountedPointer = AZStd::allocate_shared(StdValueAllocator(), *refCountedPointer); - return refCountedPointer; - } - } - namespace Internal { + template + AZStd::shared_ptr& CheckCopyOnWrite(AZStd::shared_ptr& refCountedPointer) + { + if (refCountedPointer.use_count() == 1) + { + return refCountedPointer; + } + else + { + refCountedPointer = AZStd::allocate_shared(StdValueAllocator(), *refCountedPointer); + return refCountedPointer; + } + } + template constexpr size_t GetTypeIndexInternal(size_t index = 0); @@ -288,107 +288,173 @@ namespace AZ::Dom Type Dom::Value::GetType() const { - switch (m_value.index()) - { - case GetTypeIndex(): - return Type::Null; - case GetTypeIndex(): - return Type::Int64; - case GetTypeIndex(): - return Type::Uint64; - case GetTypeIndex(): - return Type::Double; - case GetTypeIndex(): - return Type::Bool; - case GetTypeIndex(): - case GetTypeIndex(): - case GetTypeIndex(): - return Type::String; - case GetTypeIndex(): - return Type::Object; - case GetTypeIndex(): - return Type::Array; - case GetTypeIndex(): - return Type::Node; - case GetTypeIndex>(): - return Type::Opaque; - } - AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); - return Type::Null; + return AZStd::visit( + [](auto&& value) -> Type + { + using CurrentType = AZStd::decay_t; + if constexpr (AZStd::is_same_v) + { + return Type::Null; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Int64; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Uint64; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Double; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Bool; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Object; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Array; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Node; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Opaque; + } + else + { + static_assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + } + }, + m_value); } bool Value::IsNull() const { - return GetType() == Type::Null; + return AZStd::holds_alternative(m_value); } bool Value::IsFalse() const { - return IsBool() && !AZStd::get(m_value); + const bool* value = AZStd::get_if(&m_value); + return value != nullptr ? !(*value) : false; } bool Value::IsTrue() const { - return IsBool() && AZStd::get(m_value); + const bool* value = AZStd::get_if(&m_value); + return value != nullptr ? *value : false; } bool Value::IsBool() const { - return GetType() == Type::Bool; + return AZStd::holds_alternative(m_value); } bool Value::IsNode() const { - return GetType() == Type::Node; + return AZStd::holds_alternative(m_value); } bool Value::IsObject() const { - return GetType() == Type::Object; + return AZStd::holds_alternative(m_value); } bool Value::IsArray() const { - return GetType() == Type::Array; + return AZStd::holds_alternative(m_value); } bool Value::IsOpaqueValue() const { - return GetType() == Type::Opaque; + return AZStd::holds_alternative(m_value); } bool Value::IsNumber() const { - switch (GetType()) - { - case Type::Int64: - [[fallthrough]]; - case Type::Uint64: - [[fallthrough]]; - case Type::Double: - return true; - } - return false; + return AZStd::visit( + [](auto&& value) -> bool + { + using CurrentType = AZStd::decay_t; + if constexpr (AZStd::is_same_v) + { + return true; + } + else if constexpr (AZStd::is_same_v) + { + return true; + } + else if constexpr (AZStd::is_same_v) + { + return true; + } + else + { + return false; + } + }, + m_value); } bool Value::IsInt() const { - return GetType() == Type::Int64; + return AZStd::holds_alternative(m_value); } bool Value::IsUint() const { - return GetType() == Type::Uint64; + return AZStd::holds_alternative(m_value); } bool Value::IsDouble() const { - return GetType() == Type::Double; + return AZStd::holds_alternative(m_value); } bool Value::IsString() const { - return GetType() == Type::String; + return AZStd::visit( + [](auto&& value) -> bool + { + using CurrentType = AZStd::decay_t; + if constexpr (AZStd::is_same_v) + { + return true; + } + else if constexpr (AZStd::is_same_v) + { + return true; + } + else if constexpr (AZStd::is_same_v) + { + return true; + } + else + { + return false; + } + }, + m_value); } Value& Value::SetObject() @@ -406,7 +472,7 @@ namespace AZ::Dom Node& Value::GetNodeInternal() { AZ_Assert(GetType() == Type::Node, "AZ::Dom::Value: attempted to retrieve a node from a non-node value"); - return *CheckCopyOnWrite(AZStd::get(m_value)); + return *Internal::CheckCopyOnWrite(AZStd::get(m_value)); } const Object::ContainerType& Value::GetObjectInternal() const @@ -433,11 +499,11 @@ namespace AZ::Dom "AZ::Dom::Value: attempted to retrieve an object from a value that isn't an object or a node"); if (type == Type::Object) { - return CheckCopyOnWrite(AZStd::get(m_value))->m_values; + return Internal::CheckCopyOnWrite(AZStd::get(m_value))->m_values; } else { - return CheckCopyOnWrite(AZStd::get(m_value))->GetProperties(); + return Internal::CheckCopyOnWrite(AZStd::get(m_value))->GetProperties(); } } @@ -465,11 +531,11 @@ namespace AZ::Dom "AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or node"); if (type == Type::Array) { - return CheckCopyOnWrite(AZStd::get(m_value))->m_values; + return Internal::CheckCopyOnWrite(AZStd::get(m_value))->m_values; } else { - return CheckCopyOnWrite(AZStd::get(m_value))->GetChildren(); + return Internal::CheckCopyOnWrite(AZStd::get(m_value))->GetChildren(); } } @@ -698,22 +764,22 @@ namespace AZ::Dom return *this; } - size_t Value::Size() const + size_t Value::ArraySize() const { return GetArrayInternal().size(); } - size_t Value::Capacity() const + size_t Value::ArrayCapacity() const { return GetArrayInternal().capacity(); } - bool Value::Empty() const + bool Value::IsArrayEmpty() const { return GetArrayInternal().empty(); } - void Value::Clear() + void Value::ClearArray() { GetArrayInternal().clear(); } @@ -728,43 +794,43 @@ namespace AZ::Dom return GetArrayInternal()[index]; } - Value& Value::MutableAt(size_t index) + Value& Value::MutableArrayAt(size_t index) { return operator[](index); } - const Value& Value::At(size_t index) const + const Value& Value::ArrayAt(size_t index) const { return operator[](index); } - Array::ConstIterator Value::Begin() const + Array::ConstIterator Value::ArrayBegin() const { return GetArrayInternal().begin(); } - Array::ConstIterator Value::End() const + Array::ConstIterator Value::ArrayEnd() const { return GetArrayInternal().end(); } - Array::Iterator Value::Begin() + Array::Iterator Value::ArrayBegin() { return GetArrayInternal().begin(); } - Array::Iterator Value::End() + Array::Iterator Value::ArrayEnd() { return GetArrayInternal().end(); } - Value& Value::Reserve(size_t newCapacity) + Value& Value::ArrayReserve(size_t newCapacity) { GetArrayInternal().reserve(newCapacity); return *this; } - Value& Value::PushBack(Value value) + Value& Value::ArrayPushBack(Value value) { Array::ContainerType& array = GetArrayInternal(); array.reserve((array.size() / Array::ReserveIncrement + 1) * Array::ReserveIncrement); @@ -772,18 +838,18 @@ namespace AZ::Dom return *this; } - Value& Value::PopBack() + Value& Value::ArrayPopBack() { GetArrayInternal().pop_back(); return *this; } - Array::Iterator Value::Erase(Array::ConstIterator pos) + Array::Iterator Value::ArrayErase(Array::ConstIterator pos) { return GetArrayInternal().erase(pos); } - Array::Iterator Value::Erase(Array::ConstIterator first, Array::ConstIterator last) + Array::Iterator Value::ArrayErase(Array::ConstIterator first, Array::ConstIterator last) { return GetArrayInternal().erase(first, last); } @@ -1007,13 +1073,6 @@ namespace AZ::Dom void Value::SetString(AZStd::string_view value) { - if (value.size() <= ShortStringSize) - { - ShortStringType buffer; - buffer.resize_no_construct(value.size()); - memcpy(buffer.data(), value.data(), value.size()); - m_value = buffer; - } m_value = value; } @@ -1021,7 +1080,10 @@ namespace AZ::Dom { if (value.size() <= ShortStringSize) { - SetString(value); + ShortStringType buffer; + buffer.resize_no_construct(value.size()); + memcpy(buffer.data(), value.data(), value.size()); + m_value = buffer; } else { @@ -1035,9 +1097,9 @@ namespace AZ::Dom return *AZStd::get(m_value); } - void Value::SetOpaqueValue(const AZStd::any& value) + void Value::SetOpaqueValue(AZStd::any value) { - m_value = AZStd::allocate_shared(StdValueAllocator(), value); + m_value = AZStd::allocate_shared(StdValueAllocator(), AZStd::move(value)); } void Value::SetNull() diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index b73da92d23..d67947dd0a 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -103,9 +103,9 @@ namespace AZ::Dom { public: Node() = default; + Node(const Node&) = default; + Node(Node&&) = default; explicit Node(AZ::Name name); - explicit Node(const Node&) = default; - explicit Node(Node&&) = default; Node& operator=(const Node&) = default; Node& operator=(Node&&) = default; @@ -174,7 +174,7 @@ namespace AZ::Dom double, // Bool bool, - // StringType + // String AZStd::string_view, SharedStringType, ShortStringType, @@ -280,28 +280,28 @@ namespace AZ::Dom // Array API (also used by Node)... Value& SetArray(); - size_t Size() const; - size_t Capacity() const; - bool Empty() const; - void Clear(); + size_t ArraySize() const; + size_t ArrayCapacity() const; + bool IsArrayEmpty() const; + void ClearArray(); Value& operator[](size_t index); const Value& operator[](size_t index) const; - Value& MutableAt(size_t index); - const Value& At(size_t index) const; + Value& MutableArrayAt(size_t index); + const Value& ArrayAt(size_t index) const; - Array::ConstIterator Begin() const; - Array::ConstIterator End() const; - Array::Iterator Begin(); - Array::Iterator End(); + Array::ConstIterator ArrayBegin() const; + Array::ConstIterator ArrayEnd() const; + Array::Iterator ArrayBegin(); + Array::Iterator ArrayEnd(); - Value& Reserve(size_t newCapacity); - Value& PushBack(Value value); - Value& PopBack(); + Value& ArrayReserve(size_t newCapacity); + Value& ArrayPushBack(Value value); + Value& ArrayPopBack(); - Array::Iterator Erase(Array::ConstIterator pos); - Array::Iterator Erase(Array::ConstIterator first, Array::ConstIterator last); + Array::Iterator ArrayErase(Array::ConstIterator pos); + Array::Iterator ArrayErase(Array::ConstIterator first, Array::ConstIterator last); Array::ContainerType& GetMutableArray(); const Array::ContainerType& GetArray() const; @@ -365,7 +365,7 @@ namespace AZ::Dom //! serialize an opaque type into a DOM value instead, as serializers //! and other systems will have no means of dealing with fully arbitrary //! values. - void SetOpaqueValue(const AZStd::any&); + void SetOpaqueValue(AZStd::any); // Null API... void SetNull(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp index 210d1fa123..433e650d04 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValueWriter.cpp @@ -129,7 +129,7 @@ namespace AZ::Dom AZStd::string::format("AZ::Dom::ValueWriter: %s called from within a different container type", endMethodName)); } - if (static_cast(buffer.m_attributes.size()) != attributeCount) + if (aznumeric_cast(buffer.m_attributes.size()) != attributeCount) { return VisitorFailure( VisitorErrorCode::InternalError, @@ -138,7 +138,7 @@ namespace AZ::Dom buffer.m_attributes.size())); } - if (static_cast(buffer.m_elements.size()) != elementCount) + if (aznumeric_cast(buffer.m_elements.size()) != elementCount) { return VisitorFailure( VisitorErrorCode::InternalError, diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 12684c64bc..74eb78be00 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -77,7 +77,7 @@ namespace AZ::Dom::Benchmark Value array(Type::Array); for (int i = 0; i < entryCount; ++i) { - array.PushBack(createEntry(i)); + array.ArrayPushBack(createEntry(i)); } return array; }; @@ -152,7 +152,7 @@ namespace AZ::Dom::Benchmark for (auto _ : state) { Value copy = original; - copy["entries"]["Key0"].PushBack(42); + copy["entries"]["Key0"].ArrayPushBack(42); TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index b88ab746b9..3cbd532b13 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -55,7 +55,7 @@ namespace AZ::Dom::Tests m_value.SetArray(); EXPECT_TRUE(m_value.IsArray()); - EXPECT_EQ(m_value.Size(), 0); + EXPECT_EQ(m_value.ArraySize(), 0); PerformValueChecks(); } @@ -66,8 +66,8 @@ namespace AZ::Dom::Tests for (int i = 0; i < 5; ++i) { - m_value.PushBack(Value(i)); - EXPECT_EQ(m_value.Size(), i + 1); + m_value.ArrayPushBack(Value(i)); + EXPECT_EQ(m_value.ArraySize(), i + 1); EXPECT_EQ(m_value[i].GetInt32(), i); } @@ -82,15 +82,15 @@ namespace AZ::Dom::Tests Value nestedArray(Type::Array); for (int i = 0; i < 5; ++i) { - nestedArray.PushBack(Value(i)); + nestedArray.ArrayPushBack(Value(i)); } - m_value.PushBack(AZStd::move(nestedArray)); + m_value.ArrayPushBack(AZStd::move(nestedArray)); } - EXPECT_EQ(m_value.Size(), 5); + EXPECT_EQ(m_value.ArraySize(), 5); for (int i = 0; i < 3; ++i) { - EXPECT_EQ(m_value[i].Size(), 5); + EXPECT_EQ(m_value[i].ArraySize(), 5); for (int j = 0; j < 5; ++j) { EXPECT_EQ(m_value[i][j].GetInt32(), j); @@ -154,7 +154,7 @@ namespace AZ::Dom::Tests m_value.SetNode("Test"); EXPECT_EQ(m_value.GetNodeName(), AZ::Name("Test")); EXPECT_EQ(m_value.MemberCount(), 0); - EXPECT_EQ(m_value.Size(), 0); + EXPECT_EQ(m_value.ArraySize(), 0); PerformValueChecks(); } @@ -165,8 +165,8 @@ namespace AZ::Dom::Tests for (int i = 0; i < 10; ++i) { - m_value.PushBack(Value(i)); - EXPECT_EQ(m_value.Size(), i + 1); + m_value.ArrayPushBack(Value(i)); + EXPECT_EQ(m_value.ArraySize(), i + 1); EXPECT_EQ(m_value[i].GetInt32(), i); if (i < 5) @@ -196,10 +196,10 @@ namespace AZ::Dom::Tests childNode.AddMember("foo", i); childNode.AddMember("bar", Value("test", false)); - m_value.PushBack(childNode); + m_value.ArrayPushBack(childNode); } - EXPECT_EQ(m_value.Size(), 5); + EXPECT_EQ(m_value.ArraySize(), 5); for (int i = 0; i < 5; ++i) { const Value& childNode = m_value[i]; @@ -334,30 +334,30 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, CopyOnWrite_Array) { Value v1(Type::Array); - v1.PushBack(1); - v1.PushBack(2); + v1.ArrayPushBack(1); + v1.ArrayPushBack(2); Value nestedArray(Type::Array); - v1.PushBack(nestedArray); + v1.ArrayPushBack(nestedArray); Value v2 = v1; EXPECT_EQ(&v1.GetArray(), &v2.GetArray()); - EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + EXPECT_EQ(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); v2[0] = 0; EXPECT_NE(&v1.GetArray(), &v2.GetArray()); - EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + EXPECT_EQ(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); - v2[2].PushBack(42); + v2[2].ArrayPushBack(42); EXPECT_NE(&v1.GetArray(), &v2.GetArray()); - EXPECT_NE(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + EXPECT_NE(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); v2 = v1; EXPECT_EQ(&v1.GetArray(), &v2.GetArray()); - EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray()); + EXPECT_EQ(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); } TEST_F(DomValueTests, CopyOnWrite_Node) @@ -365,8 +365,8 @@ namespace AZ::Dom::Tests Value v1; v1.SetNode("TopLevel"); - v1.PushBack(1); - v1.PushBack(2); + v1.ArrayPushBack(1); + v1.ArrayPushBack(2); v1["obj"].SetNode("Nested"); Value v2 = v1; @@ -378,7 +378,7 @@ namespace AZ::Dom::Tests EXPECT_NE(&v1.GetNode(), &v2.GetNode()); EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode()); - v2["obj"].PushBack(42); + v2["obj"].ArrayPushBack(42); EXPECT_NE(&v1.GetNode(), &v2.GetNode()); EXPECT_NE(&v1["obj"].GetNode(), &v2["obj"].GetNode()); From 783a04b88092045fe0a78c07e9b16a24188c4cbc Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Wed, 5 Jan 2022 18:00:07 +0000 Subject: [PATCH 059/272] 3495 Preferences panel update: fix richtext elision and allow html links Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- Code/Editor/EditorPreferencesPageAWS.cpp | 2 +- .../Components/Widgets/ElidingLabel.cpp | 60 ++++++++++++++++++- .../UI/PropertyEditor/PropertyRowWidget.cpp | 1 + 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Code/Editor/EditorPreferencesPageAWS.cpp b/Code/Editor/EditorPreferencesPageAWS.cpp index 68a9d6889f..9279dce7bc 100644 --- a/Code/Editor/EditorPreferencesPageAWS.cpp +++ b/Code/Editor/EditorPreferencesPageAWS.cpp @@ -28,7 +28,7 @@ void CEditorPreferencesPage_AWS::Reflect(AZ::SerializeContext& serialize) if (editContext) { editContext->Class("Options", "") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Allow O3DE to send information about your use of AWS Core Gem to AWS", + ->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Allow O3DE to send information about your use of AWS Core Gem to AWS", ""); editContext->Class("AWS Preferences", "AWS Preferences") diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/ElidingLabel.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/ElidingLabel.cpp index 8ef69c4b56..8daa183b80 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/ElidingLabel.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/ElidingLabel.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include namespace AzQtComponents { @@ -35,6 +37,7 @@ namespace AzQtComponents m_text = text; m_metricsLabel->setText(m_text); + m_elidedText.clear(); elide(); updateGeometry(); @@ -65,7 +68,62 @@ namespace AzQtComponents void ElidingLabel::elide() { ensurePolished(); - m_elidedText = fontMetrics().elidedText(m_text, m_elideMode, TextRect().width()); + + if (Qt::mightBeRichText(m_text)) + { + // If RichText tags are elided using fontMetrics.elidedText(), they will break. + // A TextDocument is used to produce elided text that takes this into account. + const QString ellipsis("..."); + const int maxLineWidth = TextRect().width(); + + QTextDocument doc; + doc.setHtml(m_text); + doc.setDefaultFont(font()); + doc.setDocumentMargin(0.0); + + // Turn off wrapping so the document uses a single line. + QTextOption option = doc.defaultTextOption(); + option.setWrapMode(QTextOption::WrapMode::NoWrap); + doc.setDefaultTextOption(option); + doc.adjustSize(); + + if (doc.size().width() <= maxLineWidth) + { + m_elidedText = m_text; + } + else + { + QTextCursor textCursor(&doc); + textCursor.movePosition(QTextCursor::End); + + int ellipsisWidth = 0; + + // At the moment only ElideRight and ElideNone are ever used. This will need expanding if other elision modes are used. + if (m_elideMode == Qt::ElideRight) + { + ellipsisWidth = fontMetrics().horizontalAdvance(ellipsis); + } + + // Move the cursor back until the text fits or the start of the text is reached. + while (doc.size().width() + ellipsisWidth > maxLineWidth && !textCursor.atStart()) + { + textCursor.deletePreviousChar(); + doc.adjustSize(); + } + + if (m_elideMode == Qt::ElideRight) + { + textCursor.insertText(ellipsis); + } + + m_elidedText = doc.toHtml(); + } + } + else + { + m_elidedText = fontMetrics().elidedText(m_text, m_elideMode, TextRect().width()); + } + QLabel::setText(m_elidedText); if (m_elidedText != m_text) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp index bb2d2851ca..e895456151 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp @@ -421,6 +421,7 @@ namespace AzToolsFramework { QString label{ text }; m_nameLabel->setText(label); + m_nameLabel->setOpenExternalLinks(true); m_nameLabel->setVisible(!label.isEmpty()); // setting the stretches to 0 in case of an empty label really hides the label (i.e. even the reserved space) m_mainLayout->setStretch(0, label.isEmpty() ? 0 : LabelColumnStretch); From 8ed3da5b7f9916474e3e1de2188d23093bf68549 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 10:24:53 -0800 Subject: [PATCH 060/272] Adding header file Signed-off-by: mrieggeramzn --- .../AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h index 504e3fd0dc..ed428eeac5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace AzToolsFramework { From 31e51f8c3abd1614550f73cf43c8ab267611d498 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 Jan 2022 10:47:23 -0800 Subject: [PATCH 061/272] Minor updates to the Spawnable Entity Aliases in response to PR feedback. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Tests/Spawnable/SpawnableEntitiesManagerTests.cpp | 8 +++++--- .../Entity/PrefabEditorEntityOwnershipService.cpp | 3 +-- .../Prefab/Spawnable/PrefabProcessorContext.cpp | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp index 1a483a7851..50365ff2ff 100644 --- a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp +++ b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp @@ -101,6 +101,8 @@ namespace UnitTest class SpawnableEntitiesManagerTest : public AllocatorsFixture { public: + constexpr static AZ::u64 EntityIdStartId = 40; + void SetUp() override { AllocatorsFixture::SetUp(); @@ -156,7 +158,7 @@ namespace UnitTest { auto entry = AZStd::make_unique(); entry->AddComponent(aznew SourceSpawnableComponent()); - entry->SetId(AZ::EntityId(40 + i)); + entry->SetId(AZ::EntityId(EntityIdStartId + i)); entities.push_back(AZStd::move(entry)); } } @@ -175,13 +177,13 @@ namespace UnitTest auto entry = AZStd::make_unique(); if (i != 0) { - entry->AddComponent(aznew TargetSpawnableComponent(AZ::EntityId(40 + i - 1))); + entry->AddComponent(aznew TargetSpawnableComponent(AZ::EntityId(EntityIdStartId + i - 1))); } else { entry->AddComponent(aznew TargetSpawnableComponent()); } - entry->SetId(AZ::EntityId(40 + i)); + entry->SetId(AZ::EntityId(EntityIdStartId + i)); entities.push_back(AZStd::move(entry)); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 3d962ade67..418d176daa 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -415,8 +415,7 @@ namespace AzToolsFramework { // Construct the runtime entities and products bool readyToCreateRootSpawnable = m_playInEditorData.m_assetsCache.IsActivated(); - if (!readyToCreateRootSpawnable && - !m_playInEditorData.m_assetsCache.Activate(Prefab::PrefabConversionUtils::PlayInEditor)) + if (!readyToCreateRootSpawnable && !m_playInEditorData.m_assetsCache.Activate(Prefab::PrefabConversionUtils::PlayInEditor)) { AZ_Error("Prefab", false, "Failed to create a prefab processing stack from key '%.*s'.", AZ_STRING_ARG(Prefab::PrefabConversionUtils::PlayInEditor)); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index 2e8da9f9a1..fd8ce43836 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -38,6 +38,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils if (!m_prefabNames.contains(name)) { m_prefabNames.emplace(AZStd::move(name)); + // If currently iterating add to pending queue to avoid invalidating the container that's being iterated over. PrefabContainer& container = m_isIterating ? m_pendingPrefabAdditions : m_prefabs; container.push_back(AZStd::move(document)); return true; @@ -47,6 +48,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) { + // Enable iterating state so the prefab container doesn't get invalided. Enabling this flag will cause new prefabs + // to be stored in a temporary buffer that can be moved into the regular prefab container after iterating. m_isIterating = true; for (PrefabDocument& document : m_prefabs) { From 2296cf228c42158c0c01a6a6ea5d45f9ebe2d257 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 5 Jan 2022 13:00:14 -0600 Subject: [PATCH 062/272] Removing custom teardown for closing O3DE applications, and adding to list of LY_PROCESSES to close with test Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/automatedtesting_shared/base.py | 2 +- .../editor/EditorScripts/Menus_FileMenuOptions.py | 5 ----- .../PythonTests/editor/TestSuite_Main_Optimized.py | 6 +++--- .../Gem/PythonTests/editor/TestSuite_Periodic.py | 11 ++--------- .../ly_test_tools/o3de/editor_test_utils.py | 2 +- 5 files changed, 7 insertions(+), 19 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py index 0441f8a1dc..4db959b23e 100755 --- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py +++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py @@ -182,7 +182,7 @@ class TestAutomationBase: @staticmethod def _kill_ly_processes(include_asset_processor=True): LY_PROCESSES = [ - 'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher' + 'Editor', 'Profiler', 'RemoteConsole', 'AutomatedTesting.ServerLauncher', 'o3de' ] AP_PROCESSES = [ 'AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder', 'CrySCompileServer', diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index c319535c05..cade2125e2 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -26,8 +26,6 @@ def Menus_FileMenuOptions_Work(): :return: None """ - import azlmbr.legacy.general as general - import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report @@ -66,9 +64,6 @@ def Menus_FileMenuOptions_Work(): ) Report.result(menu_action_triggered, action_triggered) - # Wait a few seconds for Project Settings dialogs to load so teardown can properly close them - general.idle_wait(2.0) - if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py index 7364cd8bc9..058c309652 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -24,11 +24,11 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): class test_AssetPicker_UI_UX(EditorSharedTest): from .EditorScripts import AssetPicker_UI_UX as test_module - class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSingleTest): + class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest): from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest): - # Custom teardown to remove slice asset created during test + # Custom teardown to remove level created during test def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) @@ -39,7 +39,7 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): # Disable null renderer use_null_renderer = False - # Custom teardown to remove slice asset created during test + # Custom teardown to remove level created during test def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py index f8a054d517..282276250f 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py @@ -26,13 +26,6 @@ def remove_test_level(request, workspace, project): request.addfinalizer(teardown) -@pytest.fixture -def kill_external_tools(request): - def teardown(): - process_utils.kill_processes_named("o3de.exe") - request.addfinalizer(teardown) - - @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) @@ -40,7 +33,7 @@ class TestAutomation(TestAutomationBase): def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform): from .EditorScripts import AssetBrowser_SearchFiltering as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) + self._run_test(request, workspace, editor, test_module, batch_mode=False, use_null_renderer=False) def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform): from .EditorScripts import AssetBrowser_TreeNavigation as test_module @@ -58,7 +51,7 @@ class TestAutomation(TestAutomationBase): from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) - def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform, kill_external_tools): + def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform): from .EditorScripts import Menus_FileMenuOptions as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py index 9f1e01342c..dd0bede4b8 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py @@ -24,7 +24,7 @@ def kill_all_ly_processes(include_asset_processor: bool = True) -> None: :return: None """ LY_PROCESSES = [ - 'Editor', 'Profiler', 'RemoteConsole', + 'Editor', 'Profiler', 'RemoteConsole', 'o3de' ] AP_PROCESSES = [ 'AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder' From acc6248ec98ef8cd24ea057f679d90ca6be812e5 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 5 Jan 2022 11:31:09 -0800 Subject: [PATCH 063/272] Move deep comparison / copy to utils Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 148 +++++++++++++++++ Code/Framework/AzCore/AzCore/DOM/DomUtils.h | 3 + Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 155 +++--------------- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 13 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 3 +- .../AzCore/Tests/DOM/DomValueTests.cpp | 6 +- 6 files changed, 186 insertions(+), 142 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index 73c4bd2d76..c604373296 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -33,4 +33,152 @@ namespace AZ::Dom::Utils } return AZ::Success(AZStd::move(value)); } + + bool DeepCompareIsEqual(const Value& lhs, const Value& rhs) + { + const Value::ValueType& lhsValue = lhs.GetInternalValue(); + const Value::ValueType& rhsValue = rhs.GetInternalValue(); + + if (lhs.IsString() && rhs.IsString()) + { + // If we both hold the same ref counted string we don't need to do a full comparison + if (AZStd::holds_alternative(lhsValue) && lhsValue == rhsValue) + { + return true; + } + return lhs.GetString() == rhs.GetString(); + } + + return AZStd::visit( + [&](auto&& ourValue) -> bool + { + using Alternative = AZStd::decay_t; + + if constexpr (AZStd::is_same_v) + { + if (!rhs.IsObject()) + { + return false; + } + auto&& theirValue = AZStd::get>(rhsValue); + if (ourValue == theirValue) + { + return true; + } + + const Object::ContainerType& ourValues = ourValue->GetValues(); + const Object::ContainerType& theirValues = theirValue->GetValues(); + + if (ourValues.size() != theirValues.size()) + { + return false; + } + + for (size_t i = 0; i < ourValues.size(); ++i) + { + const Object::EntryType& lhsChild = ourValues[i]; + const Object::EntryType& rhsChild = theirValues[i]; + if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + { + return false; + } + } + + return true; + } + else if constexpr (AZStd::is_same_v) + { + if (!rhs.IsArray()) + { + return false; + } + auto&& theirValue = AZStd::get>(rhsValue); + if (ourValue == theirValue) + { + return true; + } + + const Array::ContainerType& ourValues = ourValue->GetValues(); + const Array::ContainerType& theirValues = theirValue->GetValues(); + + if (ourValues.size() != theirValues.size()) + { + return false; + } + + for (size_t i = 0; i < ourValues.size(); ++i) + { + const Value& lhsChild = ourValues[i]; + const Value& rhsChild = theirValues[i]; + if (!DeepCompareIsEqual(lhsChild, rhsChild)) + { + return false; + } + } + + return true; + } + else if constexpr (AZStd::is_same_v) + { + if (!rhs.IsNode()) + { + return false; + } + auto&& theirValue = AZStd::get>(rhsValue); + if (ourValue == theirValue) + { + return true; + } + + const Node& ourNode = *ourValue; + const Node& theirNode = *theirValue; + + const Object::ContainerType& ourProperties = ourNode.GetProperties(); + const Object::ContainerType& theirProperties = theirNode.GetProperties(); + + if (ourProperties.size() != theirProperties.size()) + { + return false; + } + + for (size_t i = 0; i < ourProperties.size(); ++i) + { + const Object::EntryType& lhsChild = ourProperties[i]; + const Object::EntryType& rhsChild = theirProperties[i]; + if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + { + return false; + } + } + + const Array::ContainerType& ourChildren = ourNode.GetChildren(); + const Array::ContainerType& theirChildren = theirNode.GetChildren(); + + for (size_t i = 0; i < ourChildren.size(); ++i) + { + const Value& lhsChild = ourChildren[i]; + const Value& rhsChild = theirChildren[i]; + if (!DeepCompareIsEqual(lhsChild, rhsChild)) + { + return false; + } + } + + return true; + } + else + { + return lhs == rhs; + } + }, + lhsValue); + } + + Value DeepCopy(const Value& value, bool copyStrings) + { + Value copiedValue; + AZStd::unique_ptr writer = copiedValue.GetWriteHandler(); + value.Accept(*writer, copyStrings); + return copiedValue; + } } // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h index ebe4273b48..5403b93714 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h @@ -17,4 +17,7 @@ namespace AZ::Dom::Utils Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor); AZ::Outcome WriteToValue(const Backend::WriteCallback& writeCallback); + + bool DeepCompareIsEqual(const Value& lhs, const Value& rhs); + Value DeepCopy(const Value& value, bool copyStrings = true); } // namespace AZ::Dom::Utils diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 8c002b7091..af6d86d699 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -67,6 +67,16 @@ namespace AZ::Dom return Internal::ExtractTypeArgs::GetTypeIndex(); } + const Array::ContainerType& Array::GetValues() const + { + return m_values; + } + + const Object::ContainerType& Object::GetValues() const + { + return m_values; + } + Node::Node(AZ::Name name) : m_name(AZStd::move(name)) { @@ -130,8 +140,8 @@ namespace AZ::Dom } } - Value::Value(const AZStd::any& value) - : m_value(AZStd::allocate_shared(StdValueAllocator(), value)) + Value::Value(AZStd::any opaqueValue) + : m_value(AZStd::allocate_shared(StdValueAllocator(), AZStd::move(opaqueValue))) { } @@ -660,7 +670,9 @@ namespace AZ::Dom Value& Value::AddMember(KeyType name, const Value& value) { Object::ContainerType& object = GetObjectInternal(); - object.reserve((object.size() / Object::ReserveIncrement + 1) * Object::ReserveIncrement); + // Reserve in ReserveIncremenet chunks instead of the default vector doubling strategy + // Profiling has found that this is an aggregate performance gain for typical workflows + object.reserve(AZ_SIZE_ALIGN_UP(object.size() + 1, Object::ReserveIncrement)); if (auto memberIt = FindMutableMember(name); memberIt != object.end()) { memberIt->second = value; @@ -833,7 +845,9 @@ namespace AZ::Dom Value& Value::ArrayPushBack(Value value) { Array::ContainerType& array = GetArrayInternal(); - array.reserve((array.size() / Array::ReserveIncrement + 1) * Array::ReserveIncrement); + // Reserve in ReserveIncremenet chunks instead of the default vector doubling strategy + // Profiling has found that this is an aggregate performance gain for typical workflows + array.reserve(AZ_SIZE_ALIGN_UP(array.size() + 1, Array::ReserveIncrement)); array.push_back(AZStd::move(value)); return *this; } @@ -1231,137 +1245,8 @@ namespace AZ::Dom return AZStd::make_unique(*this); } - bool Value::DeepCompareIsEqual(const Value& other) const + const Value::ValueType& Value::GetInternalValue() const { - if (IsString() && other.IsString()) - { - // If we both hold the same ref counted string we don't need to do a full comparison - if (AZStd::holds_alternative(m_value) && m_value == other.m_value) - { - return true; - } - return GetString() == other.GetString(); - } - - if (m_value.index() != other.m_value.index()) - { - return false; - } - - return AZStd::visit( - [&](auto&& ourValue) -> bool - { - using Alternative = AZStd::decay_t; - auto&& theirValue = AZStd::get>(other.m_value); - - if constexpr (AZStd::is_same_v) - { - return true; - } - else if constexpr (AZStd::is_same_v) - { - if (ourValue == theirValue) - { - return true; - } - - if (ourValue->m_values.size() != theirValue->m_values.size()) - { - return false; - } - - for (size_t i = 0; i < ourValue->m_values.size(); ++i) - { - const Object::EntryType& lhs = ourValue->m_values[i]; - const Object::EntryType& rhs = theirValue->m_values[i]; - if (lhs.first != rhs.first || !lhs.second.DeepCompareIsEqual(rhs.second)) - { - return false; - } - } - - return true; - } - else if constexpr (AZStd::is_same_v) - { - if (ourValue == theirValue) - { - return true; - } - - if (ourValue->m_values.size() != theirValue->m_values.size()) - { - return false; - } - - for (size_t i = 0; i < ourValue->m_values.size(); ++i) - { - const Value& lhs = ourValue->m_values[i]; - const Value& rhs = theirValue->m_values[i]; - if (!lhs.DeepCompareIsEqual(rhs)) - { - return false; - } - } - - return true; - } - else if constexpr (AZStd::is_same_v) - { - if (ourValue == theirValue) - { - return true; - } - - const Node& ourNode = *ourValue; - const Node& theirNode = *theirValue; - - const Object::ContainerType& ourProperties = ourNode.GetProperties(); - const Object::ContainerType& theirProperties = theirNode.GetProperties(); - - if (ourProperties.size() != theirProperties.size()) - { - return false; - } - - for (size_t i = 0; i < ourProperties.size(); ++i) - { - const Object::EntryType& lhs = ourProperties[i]; - const Object::EntryType& rhs = theirProperties[i]; - if (lhs.first != rhs.first || !lhs.second.DeepCompareIsEqual(rhs.second)) - { - return false; - } - } - - const Array::ContainerType& ourChildren = ourNode.GetChildren(); - const Array::ContainerType& theirChildren = theirNode.GetChildren(); - - for (size_t i = 0; i < ourChildren.size(); ++i) - { - const Value& lhs = ourChildren[i]; - const Value& rhs = theirChildren[i]; - if (!lhs.DeepCompareIsEqual(rhs)) - { - return false; - } - } - - return true; - } - else - { - return ourValue == theirValue; - } - }, - m_value); - } - - Value Value::DeepCopy(bool copyStrings) const - { - Value newValue; - AZStd::unique_ptr writer = newValue.GetWriteHandler(); - Accept(*writer, copyStrings); - return newValue; + return m_value; } } // namespace AZ::Dom diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index d67947dd0a..a6990fcbce 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -67,6 +67,9 @@ namespace AZ::Dom using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 4; + static_assert((ReserveIncrement & (ReserveIncrement - 1)) == 0, "ReserveIncremenet must be a power of 2"); + + const ContainerType& GetValues() const; private: ContainerType m_values; @@ -86,6 +89,9 @@ namespace AZ::Dom using Iterator = ContainerType::iterator; using ConstIterator = ContainerType::const_iterator; static constexpr const size_t ReserveIncrement = 8; + static_assert((ReserveIncrement & (ReserveIncrement - 1)) == 0, "ReserveIncremenet must be a power of 2"); + + const ContainerType& GetValues() const; private: ContainerType m_values; @@ -374,8 +380,9 @@ namespace AZ::Dom Visitor::Result Accept(Visitor& visitor, bool copyStrings) const; AZStd::unique_ptr GetWriteHandler(); - bool DeepCompareIsEqual(const Value& other) const; - Value DeepCopy(bool copyStrings = true) const; + //! Gets the internal value of this Value. Note that this value's types may not correspond one-to-one with the Type enumeration, + //! as internally the same type might have different storage mechanisms. Where possible, prefer using the typed API. + const ValueType& GetInternalValue() const; private: const Node& GetNodeInternal() const; @@ -385,7 +392,7 @@ namespace AZ::Dom const Array::ContainerType& GetArrayInternal() const; Array::ContainerType& GetArrayInternal(); - explicit Value(const AZStd::any& opaqueValue); + explicit Value(AZStd::any opaqueValue); static_assert( sizeof(ValueType) == sizeof(ShortStringType) + sizeof(size_t), "ValueType should have no members larger than ShortStringType"); diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 74eb78be00..b20091b232 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -171,7 +172,7 @@ namespace AZ::Dom::Benchmark for (auto _ : state) { - Value copy = original.DeepCopy(); + Value copy = Utils::DeepCopy(original); TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 3cbd532b13..a98eb307a2 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -41,10 +41,10 @@ namespace AZ::Dom::Tests { Value shallowCopy = m_value; EXPECT_EQ(m_value, shallowCopy); - EXPECT_TRUE(m_value.DeepCompareIsEqual(shallowCopy)); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_value, shallowCopy)); - Value deepCopy = m_value.DeepCopy(); - EXPECT_TRUE(m_value.DeepCompareIsEqual(deepCopy)); + Value deepCopy = Utils::DeepCopy(m_value); + EXPECT_TRUE(Utils::DeepCompareIsEqual(m_value, deepCopy)); } Value m_value; From 233349ffe3117bb7da54af3404660c7c1126224c Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Wed, 5 Jan 2022 13:35:09 -0600 Subject: [PATCH 064/272] Removed unused Editor code from EditMode/Geometry/Include/LightmapCompiler Signed-off-by: Chris Galvan --- Code/Editor/EditMode/DeepSelection.cpp | 138 ---- Code/Editor/EditMode/DeepSelection.h | 87 --- Code/Editor/Geometry/TriMesh.cpp | 587 ------------------ Code/Editor/Geometry/TriMesh.h | 238 ------- Code/Editor/Include/HitContext.h | 4 - .../Include/IAnimationCompressionManager.h | 20 - Code/Editor/Include/IAssetItem.h | 433 ------------- Code/Editor/Include/IAssetItemDatabase.h | 259 -------- Code/Editor/Include/IAssetViewer.h | 46 -- Code/Editor/Include/IFileUtil.h | 3 - .../SimpleTriangleRasterizer.cpp | 506 --------------- .../SimpleTriangleRasterizer.h | 181 ------ Code/Editor/Objects/ObjectManager.cpp | 1 - Code/Editor/Util/FileUtil.cpp | 102 --- Code/Editor/Util/FileUtil.h | 6 - Code/Editor/Util/FileUtil_impl.cpp | 5 - Code/Editor/Util/FileUtil_impl.h | 3 - Code/Editor/editor_lib_files.cmake | 9 - 18 files changed, 2628 deletions(-) delete mode 100644 Code/Editor/EditMode/DeepSelection.cpp delete mode 100644 Code/Editor/EditMode/DeepSelection.h delete mode 100644 Code/Editor/Geometry/TriMesh.cpp delete mode 100644 Code/Editor/Geometry/TriMesh.h delete mode 100644 Code/Editor/Include/IAnimationCompressionManager.h delete mode 100644 Code/Editor/Include/IAssetItem.h delete mode 100644 Code/Editor/Include/IAssetItemDatabase.h delete mode 100644 Code/Editor/Include/IAssetViewer.h delete mode 100644 Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.cpp delete mode 100644 Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.h diff --git a/Code/Editor/EditMode/DeepSelection.cpp b/Code/Editor/EditMode/DeepSelection.cpp deleted file mode 100644 index 3e232a230c..0000000000 --- a/Code/Editor/EditMode/DeepSelection.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "DeepSelection.h" - -// Editor -#include "Objects/BaseObject.h" - - -//! Functor for sorting selected objects on deep selection mode. -struct NearDistance -{ - NearDistance(){} - bool operator()(const CDeepSelection::RayHitObject& lhs, const CDeepSelection::RayHitObject& rhs) const - { - return lhs.distance < rhs.distance; - } -}; - -//----------------------------------------------------------------------------- -CDeepSelection::CDeepSelection() - : m_Mode(DSM_NONE) - , m_previousMode(DSM_NONE) - , m_CandidateObjectCount(0) - , m_CurrentSelectedPos(-1) -{ - m_LastPickPoint = QPoint(-1, -1); -} - -//----------------------------------------------------------------------------- -CDeepSelection::~CDeepSelection() -{ -} - -//----------------------------------------------------------------------------- -void CDeepSelection::Reset(bool bResetLastPick) -{ - for (int i = 0; i < m_CandidateObjectCount; ++i) - { - m_RayHitObjects[i].object->ClearFlags(OBJFLAG_NO_HITTEST); - } - - m_CandidateObjectCount = 0; - m_CurrentSelectedPos = -1; - - m_RayHitObjects.clear(); - - if (bResetLastPick) - { - m_LastPickPoint = QPoint(-1, -1); - } -} - -//----------------------------------------------------------------------------- -void CDeepSelection::AddObject(float distance, CBaseObject* pObj) -{ - m_RayHitObjects.push_back(RayHitObject(distance, pObj)); -} - -//----------------------------------------------------------------------------- -bool CDeepSelection::OnCycling (const QPoint& pt) -{ - QPoint diff = m_LastPickPoint - pt; - LONG epsilon = 2; - m_LastPickPoint = pt; - - if (abs(diff.x()) < epsilon && abs(diff.y()) < epsilon) - { - return true; - } - else - { - return false; - } -} - -//----------------------------------------------------------------------------- -void CDeepSelection::ExcludeHitTest(int except) -{ - int nExcept = except % m_CandidateObjectCount; - - for (int i = 0; i < m_CandidateObjectCount; ++i) - { - m_RayHitObjects[i].object->SetFlags(OBJFLAG_NO_HITTEST); - } - - m_RayHitObjects[nExcept].object->ClearFlags(OBJFLAG_NO_HITTEST); -} - -//----------------------------------------------------------------------------- -int CDeepSelection::CollectCandidate(float fMinDistance, float fRange) -{ - m_CandidateObjectCount = 0; - - if (!m_RayHitObjects.empty()) - { - std::sort(m_RayHitObjects.begin(), m_RayHitObjects.end(), NearDistance()); - - for (std::vector::iterator itr = m_RayHitObjects.begin(); - itr != m_RayHitObjects.end(); ++itr) - { - if (itr->distance - fMinDistance < fRange) - { - ++m_CandidateObjectCount; - } - else - { - break; - } - } - } - - return m_CandidateObjectCount; -} - -//----------------------------------------------------------------------------- -CBaseObject* CDeepSelection::GetCandidateObject(int index) -{ - m_CurrentSelectedPos = index % m_CandidateObjectCount; - - return m_RayHitObjects[m_CurrentSelectedPos].object; -} - -//----------------------------------------------------------------------------- -//! -void CDeepSelection::SetMode(EDeepSelectionMode mode) -{ - m_previousMode = m_Mode; - m_Mode = mode; -} diff --git a/Code/Editor/EditMode/DeepSelection.h b/Code/Editor/EditMode/DeepSelection.h deleted file mode 100644 index b6f652abc5..0000000000 --- a/Code/Editor/EditMode/DeepSelection.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Deep Selection Header - - -#ifndef CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H -#define CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H -#pragma once - -class CBaseObject; - -//! Deep Selection -//! Additional output information of HitContext on using "deep selection mode". -//! At the deep selection mode, it supports second selection pass for easy -//! selection on crowded area with two different method. -//! One is to show pop menu of candidate objects list. Another is the cyclic -//! selection on pick clicking. -class CDeepSelection - : public _i_reference_target_t -{ -public: - //! Deep Selection Mode Definition - enum EDeepSelectionMode - { - DSM_NONE = 0, // Not using deep selection. - DSM_POP = 1, // Deep selection mode with pop context menu. - DSM_CYCLE = 2 // Deep selection mode with cyclic selection on each clinking same point. - }; - - //! Subclass for container of the selected object with hit distance. - struct RayHitObject - { - RayHitObject(float dist, CBaseObject* pObj) - : distance(dist) - , object(pObj) - { - } - - float distance; - CBaseObject* object; - }; - - //! Constructor - CDeepSelection(); - virtual ~CDeepSelection(); - - void Reset(bool bResetLastPick = false); - void AddObject(float distance, CBaseObject* pObj); - //! Check if clicking point is same position with last position, - //! to decide whether to continue cycling mode. - bool OnCycling (const QPoint& pt); - //! All objects in list are excluded for hitting test except one, current selection. - void ExcludeHitTest(int except); - void SetMode(EDeepSelectionMode mode); - inline EDeepSelectionMode GetMode() const { return m_Mode; } - inline EDeepSelectionMode GetPreviousMode() const { return m_previousMode; } - //! Collect object in the deep selection range. The distance from the minimum - //! distance is less than deep selection range. - int CollectCandidate(float fMinDistance, float fRange); - //! Return the candidate object in index position, then it is to be current - //! selection position. - CBaseObject* GetCandidateObject(int index); - //! Return the current selection position that is update in "GetCandidateObject" - //! function call. - inline int GetCurrentSelectPos() const { return m_CurrentSelectedPos; } - //! Return the number of objects in the deep selection range. - inline int GetCandidateObjectCount() const { return m_CandidateObjectCount; } - -private: - //! Current mode - EDeepSelectionMode m_Mode; - EDeepSelectionMode m_previousMode; - //! Last picking point to check whether cyclic selection continue. - QPoint m_LastPickPoint; - //! List of the selected objects with ray hitting - std::vector m_RayHitObjects; - int m_CandidateObjectCount; - int m_CurrentSelectedPos; -}; -#endif // CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H diff --git a/Code/Editor/Geometry/TriMesh.cpp b/Code/Editor/Geometry/TriMesh.cpp deleted file mode 100644 index efc201095d..0000000000 --- a/Code/Editor/Geometry/TriMesh.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "TriMesh.h" - -// Editor -#include "Util/fastlib.h" -#include "Objects/SubObjSelection.h" - - -////////////////////////////////////////////////////////////////////////// -CTriMesh::CTriMesh() -{ - pFaces = nullptr; - pVertices = nullptr; - pWSVertices = nullptr; - pUV = nullptr; - pColors = nullptr; - pEdges = nullptr; - pWeights = nullptr; - - nFacesCount = 0; - nVertCount = 0; - nUVCount = 0; - nEdgeCount = 0; - - selectionType = SO_ELEM_NONE; - - memset(m_streamSize, 0, sizeof(m_streamSize)); - memset(m_streamSel, 0, sizeof(m_streamSel)); - streamSelMask = 0; - - m_streamSel[VERTICES] = &vertSel; - m_streamSel[EDGES] = &edgeSel; - m_streamSel[FACES] = &faceSel; -} - -////////////////////////////////////////////////////////////////////////// -CTriMesh::~CTriMesh() -{ - free(pFaces); - free(pEdges); - free(pVertices); - free(pUV); - free(pColors); - free(pWSVertices); - free(pWeights); -} - -// Set stream size. -void CTriMesh::ReallocStream(int stream, int nNewCount) -{ - assert(stream >= 0 && stream < LAST_STREAM); - if (stream < 0 || stream >= LAST_STREAM) - { - return; - } - if (m_streamSize[stream] == nNewCount) - { - return; // Stream already have required size. - } - void* pStream = nullptr; - int nElementSize = 0; - GetStreamInfo(stream, pStream, nElementSize); - pStream = ReAllocElements(pStream, nNewCount, nElementSize); - m_streamSize[stream] = nNewCount; - - switch (stream) - { - case VERTICES: - pVertices = (CTriVertex*)pStream; - nVertCount = nNewCount; - vertSel.resize(nNewCount); - break; - case FACES: - pFaces = (CTriFace*)pStream; - nFacesCount = nNewCount; - faceSel.resize(nNewCount); - break; - case EDGES: - pEdges = (CTriEdge*)pStream; - nEdgeCount = nNewCount; - edgeSel.resize(nNewCount); - break; - case TEXCOORDS: - pUV = (SMeshTexCoord*)pStream; - nUVCount = nNewCount; - break; - case COLORS: - pColors = (SMeshColor*)pStream; - break; - case WEIGHTS: - pWeights = (float*)pStream; - break; - case LINES: - pLines = (CTriLine*)pStream; - break; - case WS_POSITIONS: - pWSVertices = (Vec3*)pStream; - break; - default: - assert(0); // unknown stream. - } - m_streamSize[stream] = nNewCount; -} - -// Set stream size. -void CTriMesh::GetStreamInfo(int stream, void*& pStream, int& nElementSize) const -{ - assert(stream >= 0 && stream < LAST_STREAM); - switch (stream) - { - case VERTICES: - pStream = pVertices; - nElementSize = sizeof(CTriVertex); - break; - case FACES: - pStream = pFaces; - nElementSize = sizeof(CTriFace); - break; - case EDGES: - pStream = pEdges; - nElementSize = sizeof(CTriEdge); - break; - case TEXCOORDS: - pStream = pUV; - nElementSize = sizeof(SMeshTexCoord); - break; - case COLORS: - pStream = pColors; - nElementSize = sizeof(SMeshColor); - break; - case WEIGHTS: - pStream = pWeights; - nElementSize = sizeof(float); - break; - case LINES: - pStream = pLines; - nElementSize = sizeof(CTriLine); - break; - case WS_POSITIONS: - pStream = pWSVertices; - nElementSize = sizeof(Vec3); - break; - default: - assert(0); // unknown stream. - } -} - -////////////////////////////////////////////////////////////////////////// -void* CTriMesh::ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element) -{ - return realloc(old_ptr, new_elem_num * size_of_element); -} - -///////////////////////////////////////////////////////////////////////////////////// -inline int FindVertexInHash(const Vec3& vPosToFind, const CTriVertex* pVectors, std::vector& hash, float fEpsilon) -{ - for (uint32 i = 0; i < hash.size(); i++) - { - const Vec3& v0 = pVectors[hash[i]].pos; - const Vec3& v1 = vPosToFind; - if (fabsf(v0.y - v1.y) < fEpsilon && fabsf(v0.x - v1.x) < fEpsilon && fabsf(v0.z - v1.z) < fEpsilon) - { - return hash[i]; - } - } - return -1; -} - -///////////////////////////////////////////////////////////////////////////////////// -inline int FindTexCoordInHash(const SMeshTexCoord& coordToFind, const SMeshTexCoord* pCoords, std::vector& hash, float fEpsilon) -{ - for (uint32 i = 0; i < hash.size(); i++) - { - const SMeshTexCoord& t0 = pCoords[hash[i]]; - const SMeshTexCoord& t1 = coordToFind; - - if (t0.IsEquivalent(t1, fEpsilon)) - { - return hash[i]; - } - } - return -1; -} - - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::SharePositions() -{ - float fEpsilon = 0.0001f; - float fHashScale = 256.0f / MAX(bbox.GetSize().GetLength(), fEpsilon); - std::vector arrHashTable[256]; - - CTriVertex* pNewVerts = new CTriVertex[GetVertexCount()]; - SMeshColor* pNewColors = nullptr; - if (pColors) - { - pNewColors = new SMeshColor[GetVertexCount()]; - } - - int nLastIndex = 0; - for (int f = 0; f < GetFacesCount(); f++) - { - CTriFace& face = pFaces[f]; - for (int i = 0; i < 3; i++) - { - const Vec3& v = pVertices[face.v[i]].pos; - uint8 nHash = static_cast(RoundFloatToInt((v.x + v.y + v.z) * fHashScale)); - - int find = FindVertexInHash(v, pNewVerts, arrHashTable[nHash], fEpsilon); - if (find < 0) - { - pNewVerts[nLastIndex] = pVertices[face.v[i]]; - if (pColors) - { - pNewColors[nLastIndex] = pColors[face.v[i]]; - } - face.v[i] = nLastIndex; - // Reserve some space already. - arrHashTable[nHash].reserve(100); - arrHashTable[nHash].push_back(nLastIndex); - nLastIndex++; - } - else - { - face.v[i] = find; - } - } - } - - SetVertexCount(nLastIndex); - memcpy(pVertices, pNewVerts, nLastIndex * sizeof(CTriVertex)); - delete []pNewVerts; - - if (pColors) - { - SetColorsCount(nLastIndex); - memcpy(pColors, pNewColors, nLastIndex * sizeof(SMeshColor)); - delete []pNewColors; - } -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::ShareUV() -{ - float fEpsilon = 0.0001f; - float fHashScale = 256.0f; - std::vector arrHashTable[256]; - - SMeshTexCoord* pNewUV = new SMeshTexCoord[GetUVCount()]; - - int nLastIndex = 0; - for (int f = 0; f < GetFacesCount(); f++) - { - CTriFace& face = pFaces[f]; - for (int i = 0; i < 3; i++) - { - const Vec2 uv = pUV[face.uv[i]].GetUV(); - uint8 nHash = static_cast(RoundFloatToInt((uv.x + uv.y) * fHashScale)); - - int find = FindTexCoordInHash(pUV[face.uv[i]], pNewUV, arrHashTable[nHash], fEpsilon); - if (find < 0) - { - pNewUV[nLastIndex] = pUV[face.uv[i]]; - face.uv[i] = nLastIndex; - arrHashTable[nHash].reserve(100); - arrHashTable[nHash].push_back(nLastIndex); - nLastIndex++; - } - else - { - face.uv[i] = find; - } - } - } - - SetUVCount(nLastIndex); - memcpy(pUV, pNewUV, nLastIndex * sizeof(SMeshTexCoord)); - delete []pNewUV; -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::CalcFaceNormals() -{ - for (int i = 0; i < nFacesCount; i++) - { - CTriFace& face = pFaces[i]; - Vec3 p1 = pVertices[face.v[0]].pos; - Vec3 p2 = pVertices[face.v[1]].pos; - Vec3 p3 = pVertices[face.v[2]].pos; - face.normal = (p2 - p1).Cross(p3 - p1); - face.normal.Normalize(); - } -} - -#define TEX_EPS 0.001f -#define VER_EPS 0.001f - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::CopyStream(CTriMesh& fromMesh, int stream) -{ - void* pTrgStream = nullptr; - void* pSrcStream = nullptr; - int nElemSize = 0; - fromMesh.GetStreamInfo(stream, pSrcStream, nElemSize); - if (pSrcStream) - { - ReallocStream(stream, fromMesh.GetStreamSize(stream)); - GetStreamInfo(stream, pTrgStream, nElemSize); - memcpy(pTrgStream, pSrcStream, nElemSize * fromMesh.GetStreamSize(stream)); - } -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::Copy(CTriMesh& fromMesh, int nCopyFlags) -{ - streamSelMask = fromMesh.streamSelMask; - - if (nCopyFlags & COPY_VERTICES) - { - CopyStream(fromMesh, VERTICES); - } - if (nCopyFlags & COPY_FACES) - { - CopyStream(fromMesh, FACES); - } - if (nCopyFlags & COPY_EDGES) - { - CopyStream(fromMesh, EDGES); - } - if (nCopyFlags & COPY_TEXCOORDS) - { - CopyStream(fromMesh, TEXCOORDS); - } - if (nCopyFlags & COPY_COLORS) - { - CopyStream(fromMesh, COLORS); - } - if (nCopyFlags & COPY_WEIGHTS) - { - CopyStream(fromMesh, WEIGHTS); - } - if (nCopyFlags & COPY_LINES) - { - CopyStream(fromMesh, LINES); - } - - if (nCopyFlags & COPY_VERT_SEL) - { - vertSel = fromMesh.vertSel; - } - if (nCopyFlags & COPY_EDGE_SEL) - { - edgeSel = fromMesh.edgeSel; - } - if (nCopyFlags & COPY_FACE_SEL) - { - faceSel = fromMesh.faceSel; - } -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::UpdateEdges() -{ - SetEdgeCount(GetFacesCount() * 3); - - std::map edgemap; - - int nEdges = 0; - for (int i = 0; i < GetFacesCount(); i++) - { - CTriFace& face = pFaces[i]; - for (int j = 0; j < 3; j++) - { - int v0 = j; - int v1 = (j != 2) ? j + 1 : 0; - CTriEdge edge; - edge.flags = 0; - - // First vertex index must always be smaller. - if (face.v[v0] < face.v[v1]) - { - edge.v[0] = face.v[v0]; - edge.v[1] = face.v[v1]; - } - else - { - edge.v[0] = face.v[v1]; - edge.v[1] = face.v[v0]; - } - edge.face[0] = i; - edge.face[1] = -1; - int nedge = stl::find_in_map(edgemap, edge, -1); - if (nedge >= 0) - { - // Assign this face as a second member of the edge. - if (pEdges[nedge].face[1] < 0) - { - pEdges[nedge].face[1] = i; - } - - face.edge[j] = nedge; - } - else - { - edgemap[edge] = nEdges; - pEdges[nEdges] = edge; - face.edge[j] = nEdges; - nEdges++; - } - } - } - - SetEdgeCount(nEdges); -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::SoftSelection(const SSubObjSelOptions& options) -{ - int i; - int nVerts = GetVertexCount(); - CTriVertex* pVerts = pVertices; - - for (i = 0; i < nVerts; i++) - { - if (pWeights[i] == 1.0f) - { - const Vec3& vp = pVerts[i].pos; - for (int j = 0; j < nVerts; j++) - { - if (pWeights[j] != 1.0f) - { - if (vp.IsEquivalent(pVerts[j].pos, options.fSoftSelFalloff)) - { - float fDist = vp.GetDistance(pVerts[j].pos); - if (fDist < options.fSoftSelFalloff) - { - float fWeight = 1.0f - (fDist / options.fSoftSelFalloff); - if (fWeight > pWeights[j]) - { - pWeights[j] = fWeight; - } - } - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CTriMesh::UpdateSelection() -{ - bool bAnySelected = false; - if (selectionType == SO_ELEM_VERTEX) - { - for (int i = 0; i < GetVertexCount(); i++) - { - if (vertSel[i]) - { - bAnySelected = true; - pWeights[i] = 1.0f; - } - else - { - pWeights[i] = 0; - } - } - } - if (selectionType == SO_ELEM_EDGE) - { - // Clear weights. - for (int i = 0; i < GetVertexCount(); i++) - { - pWeights[i] = 0; - } - - for (int i = 0; i < GetEdgeCount(); i++) - { - if (edgeSel[i]) - { - bAnySelected = true; - CTriEdge& edge = pEdges[i]; - for (int j = 0; j < 2; j++) - { - pWeights[edge.v[j]] = 1.0f; - } - } - } - } - else if (selectionType == SO_ELEM_FACE) - { - // Clear weights. - for (int i = 0; i < GetVertexCount(); i++) - { - pWeights[i] = 0; - } - - for (int i = 0; i < GetFacesCount(); i++) - { - if (faceSel[i]) - { - bAnySelected = true; - CTriFace& face = pFaces[i]; - for (int j = 0; j < 3; j++) - { - pWeights[face.v[j]] = 1.0f; - } - } - } - } - return bAnySelected; -} - - -////////////////////////////////////////////////////////////////////////// -bool CTriMesh::ClearSelection() -{ - bool bWasSelected = false; - // Remove all selections. - int i; - for (i = 0; i < GetVertexCount(); i++) - { - pWeights[i] = 0; - } - streamSelMask = 0; - for (int ii = 0; ii < LAST_STREAM; ii++) - { - if (m_streamSel[ii] && !m_streamSel[ii]->is_zero()) - { - bWasSelected = true; - m_streamSel[ii]->clear(); - } - } - return bWasSelected; -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges) -{ - // Brute force algorithm using binary search. - // for every edge check if edge vertex is inside inVertices array. - std::sort(inVertices.begin(), inVertices.end()); - for (int i = 0; i < GetEdgeCount(); i++) - { - if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast(pEdges[i].v[0])) != inVertices.end()) - { - outEdges.push_back(i); - } - else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast(pEdges[i].v[1])) != inVertices.end()) - { - outEdges.push_back(i); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CTriMesh::GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces) -{ - // Brute force algorithm using binary search. - // for every face check if face vertex is inside inVertices array. - std::sort(inVertices.begin(), inVertices.end()); - for (int i = 0; i < GetFacesCount(); i++) - { - if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast(pFaces[i].v[0])) != inVertices.end()) - { - outFaces.push_back(i); - } - else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast(pFaces[i].v[1])) != inVertices.end()) - { - outFaces.push_back(i); - } - else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast(pFaces[i].v[2])) != inVertices.end()) - { - outFaces.push_back(i); - } - } -} diff --git a/Code/Editor/Geometry/TriMesh.h b/Code/Editor/Geometry/TriMesh.h deleted file mode 100644 index a6c58b8f9d..0000000000 --- a/Code/Editor/Geometry/TriMesh.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H -#define CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H -#pragma once - -#include -#include "Util/bitarray.h" - -struct SSubObjSelOptions; - -typedef std::vector MeshElementsArray; - -////////////////////////////////////////////////////////////////////////// -// Vertex used in the TriMesh. -////////////////////////////////////////////////////////////////////////// -struct CTriVertex -{ - Vec3 pos; - //float weight; // Selection weight in 0-1 range. -}; - -////////////////////////////////////////////////////////////////////////// -// Triangle face used by the Triangle mesh. -////////////////////////////////////////////////////////////////////////// -struct CTriFace -{ - uint32 v[3]; // Indices to vertices array. - uint32 uv[3]; // Indices to texture coordinates array. - Vec3 n[3]; // Vertex normals at face vertices. - Vec3 normal; // Face normal. - uint32 edge[3]; // Indices to the face edges. - unsigned char MatID; // Index of face sub material. - unsigned char flags; // see ETriMeshFlags -}; - -////////////////////////////////////////////////////////////////////////// -// Mesh edge. -////////////////////////////////////////////////////////////////////////// -struct CTriEdge -{ - uint32 v[2]; // Indices to edge vertices. - int face[2]; // Indices to edge faces (-1 if no face). - uint32 flags; // see ETriMeshFlags - - CTriEdge() {} - bool operator==(const CTriEdge& edge) const - { - if ((v[0] == edge.v[0] && v[1] == edge.v[1]) || - (v[0] == edge.v[1] && v[1] == edge.v[0])) - { - return true; - } - return false; - } - bool operator!=(const CTriEdge& edge) const { return !(*this == edge); } - bool operator<(const CTriEdge& edge) const { return (*(uint64*)v < *(uint64*)edge.v); } - bool operator>(const CTriEdge& edge) const { return (*(uint64*)v > *(uint64*)edge.v); } -}; - -////////////////////////////////////////////////////////////////////////// -// Mesh line. -////////////////////////////////////////////////////////////////////////// -struct CTriLine -{ - uint32 v[2]; // Indices to edge vertices. - - CTriLine() {} - bool operator==(const CTriLine& edge) const - { - if ((v[0] == edge.v[0] && v[1] == edge.v[1]) || - (v[0] == edge.v[1] && v[1] == edge.v[0])) - { - return true; - } - return false; - } - bool operator!=(const CTriLine& edge) const { return !(*this == edge); } - bool operator<(const CTriLine& edge) const { return (*(uint64*)v < *(uint64*)edge.v); } - bool operator>(const CTriLine& edge) const { return (*(uint64*)v > *(uint64*)edge.v); } -}; - -////////////////////////////////////////////////////////////////////////// -struct CTriMeshPoly -{ - std::vector v; // Indices to vertices array. - std::vector uv; // Indices to texture coordinates array. - std::vector n; // Vertex normals at face vertices. - Vec3 normal; // Polygon normal. - uint32 edge[3]; // Indices to the face edges. - unsigned char MatID; // Index of face sub material. - unsigned char flags; // optional flags. -}; - -////////////////////////////////////////////////////////////////////////// -// CTriMesh is used in the Editor as a general purpose editable triangle mesh. -////////////////////////////////////////////////////////////////////////// -class CTriMesh -{ -public: - enum EStream - { - VERTICES, - FACES, - EDGES, - TEXCOORDS, - COLORS, - WEIGHTS, - LINES, - WS_POSITIONS, - LAST_STREAM, - }; - enum ECopyFlags - { - COPY_VERTICES = BIT(1), - COPY_FACES = BIT(2), - COPY_EDGES = BIT(3), - COPY_TEXCOORDS = BIT(4), - COPY_COLORS = BIT(5), - COPY_VERT_SEL = BIT(6), - COPY_EDGE_SEL = BIT(7), - COPY_FACE_SEL = BIT(8), - COPY_WEIGHTS = BIT(9), - COPY_LINES = BIT(10), - COPY_ALL = 0xFFFF, - }; - // geometry data - CTriFace* pFaces; - CTriEdge* pEdges; - CTriVertex* pVertices; - SMeshTexCoord* pUV; - SMeshColor* pColors; // If allocated same size as pVerts array. - Vec3* pWSVertices; // World space vertices. - float* pWeights; - CTriLine* pLines; - - int nFacesCount; - int nVertCount; - int nUVCount; - int nEdgeCount; - int nLinesCount; - - AABB bbox; - - ////////////////////////////////////////////////////////////////////////// - // Selections. - ////////////////////////////////////////////////////////////////////////// - CBitArray vertSel; - CBitArray edgeSel; - CBitArray faceSel; - // Every bit of the selection mask correspond to a stream, if bit is set this stream have some elements selected - int streamSelMask; - - // Selection element type. - // see ESubObjElementType - int selectionType; - - ////////////////////////////////////////////////////////////////////////// - // Vertices of the front facing triangles. - CBitArray frontFacingVerts; - - ////////////////////////////////////////////////////////////////////////// - // Functions. - ////////////////////////////////////////////////////////////////////////// - CTriMesh(); - ~CTriMesh(); - - int GetFacesCount() const { return nFacesCount; } - int GetVertexCount() const { return nVertCount; } - int GetUVCount() const { return nUVCount; } - int GetEdgeCount() const { return nEdgeCount; } - int GetLinesCount() const { return nLinesCount; } - - ////////////////////////////////////////////////////////////////////////// - void SetFacesCount(int nNewCount) { ReallocStream(FACES, nNewCount); } - void SetVertexCount(int nNewCount) - { - ReallocStream(VERTICES, nNewCount); - if (pColors) - { - ReallocStream(COLORS, nNewCount); - } - ReallocStream(WEIGHTS, nNewCount); - } - void SetColorsCount(int nNewCount) { ReallocStream(COLORS, nNewCount); } - void SetUVCount(int nNewCount) { ReallocStream(TEXCOORDS, nNewCount); } - void SetEdgeCount(int nNewCount) { ReallocStream(EDGES, nNewCount); } - void SetLinesCount(int nNewCount) { ReallocStream(LINES, nNewCount); } - - void ReallocStream(int stream, int nNewCount); - void GetStreamInfo(int stream, void*& pStream, int& nElementSize) const; - int GetStreamSize(int stream) const { return m_streamSize[stream]; }; - - // Calculate per face normal. - void CalcFaceNormals(); - - ////////////////////////////////////////////////////////////////////////// - // Welding functions. - ////////////////////////////////////////////////////////////////////////// - void SharePositions(); - void ShareUV(); - ////////////////////////////////////////////////////////////////////////// - // Recreate edges of the mesh. - void UpdateEdges(); - - void Copy(CTriMesh& fromMesh, int nCopyFlags = COPY_ALL); - - ////////////////////////////////////////////////////////////////////////// - // Sub-object selection specific methods. - ////////////////////////////////////////////////////////////////////////// - // Return true if something is selected. - bool UpdateSelection(); - // Clear all selections, return true if something was selected. - bool ClearSelection(); - void SoftSelection(const SSubObjSelOptions& options); - CBitArray* GetStreamSelection(int nStream) { return m_streamSel[nStream]; }; - // Returns true if specified stream have any selected elements. - bool StreamHaveSelection(int nStream) { return streamSelMask & (1 << nStream); } - void GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges); - void GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces); - -private: - void* ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element); - void CopyStream(CTriMesh& fromMesh, int stream); - - // For internal use. - int m_streamSize[LAST_STREAM]; - CBitArray* m_streamSel[LAST_STREAM]; -}; - -#endif // CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H diff --git a/Code/Editor/Include/HitContext.h b/Code/Editor/Include/HitContext.h index ceff0adb22..b49117bb60 100644 --- a/Code/Editor/Include/HitContext.h +++ b/Code/Editor/Include/HitContext.h @@ -17,7 +17,6 @@ class CGizmo; class CBaseObject; struct IDisplayViewport; -class CDeepSelection; struct AABB; #include @@ -105,8 +104,6 @@ struct HitContext CBaseObject* object; //! gizmo object that have been hit. CGizmo* gizmo; - //! for deep selection mode - CDeepSelection* pDeepSelection; //! For linking tool const char* name; //! true if this hit was from the object icon @@ -131,7 +128,6 @@ struct HitContext bIgnoreAxis = false; bOnlyGizmo = false; bUseSelectionHelpers = false; - pDeepSelection = 0; name = nullptr; iconHit = false; } diff --git a/Code/Editor/Include/IAnimationCompressionManager.h b/Code/Editor/Include/IAnimationCompressionManager.h deleted file mode 100644 index 64cebf620a..0000000000 --- a/Code/Editor/Include/IAnimationCompressionManager.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H -#pragma once - -struct IAnimationCompressionManager -{ - virtual bool IsEnabled() const = 0; - virtual void UpdateLocalAnimations() = 0; -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H diff --git a/Code/Editor/Include/IAssetItem.h b/Code/Editor/Include/IAssetItem.h deleted file mode 100644 index ff80331af5..0000000000 --- a/Code/Editor/Include/IAssetItem.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Standard interface for asset display in the asset browser, -// this header should be used to create plugins. -// The method Release of this interface should NOT be called. -// Instead, the FreeData from the database (from IAssetItemDatabase) should -// be used as it will safely release all the items from the database. -// It is still possible to call the release method, but this is not the -// recomended method, specially for usage outside of the plugins because there -// is no guarantee that a the asset will be properly removed from the database -// manager. - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H -#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H -#pragma once - -struct IAssetItemDatabase; - -namespace AssetViewer -{ - // Used in GetAssetFieldValue for each asset type to check if field name is the right one - inline bool IsFieldName(const char* pIncomingFieldName, const char* pFieldName) - { - return !strncmp(pIncomingFieldName, pFieldName, strlen(pIncomingFieldName)); - } -} - -// Description: -// This interface allows the programmer to extend asset display types visible in the asset browser. -struct IAssetItem - : public IUnknown -{ - DEFINE_UUID(0x04F20346, 0x2EC3, 0x43f2, 0xBD, 0xA1, 0x2C, 0x0B, 0x97, 0x76, 0xF3, 0x84); - - // The supported asset flags - enum EAssetFlags - { - // asset is visible in the database for filtering and sorting (not asset view control related) - eFlag_Visible = BIT(0), - // the asset is loaded - eFlag_Loaded = BIT(1), - // the asset is loaded - eFlag_Cached = BIT(2), - // the asset is selected in a selection set - eFlag_Selected = BIT(3), - // this asset is invalid, no thumb is shown/available - eFlag_Invalid = BIT(4), - // this asset has some errors/warnings, in the asset browser it will show some blinking/red elements - // and the user can check out the errors. Error text will be fetched using GetAssetFieldValue( "errors", &someStringVar ) - eFlag_HasErrors = BIT(5), - // this flag is set when the asset is rendering its contents using GDI, and not the engine's rendering capabilities - // (this flags is used as hint for the preview tool, which will use a double-buffer canvas if this flag is set, - // and send a memory HDC to the OnBeginPreview method, for drawing of the asset) - eFlag_UseGdiRendering = BIT(6), - // set if this asset is draggable into the render viewports, and can be created there - eFlag_CanBeDraggedInViewports = BIT(7), - // set if this asset can be moved after creation, otherwise the asset instance will just be created where user clicked - eFlag_CanBeMovedAfterDroppedIntoViewport = BIT(8), - // the asset thumbnail image is loaded - eFlag_ThumbnailLoaded = BIT(9), - // the asset thumbnail image is loaded - eFlag_UsedInLevel = BIT(10) - }; - - // Asset field name and field values map - typedef std::map < QString/*fieldName*/, QString/*value*/ > TAssetFieldValuesMap; - // Dependency category names and corresponding files map, example: "Textures"=>{ "foam.dds","water.dds","normal.dds" } - typedef std::map < QString/*dependencyCategory*/, std::set/*dependency filenames*/ > TAssetDependenciesMap; - - virtual ~IAssetItem() { - } - - // Description: - // Get the hash number/key used for database thumbnail and info records management - virtual uint32 GetHash() const = 0; - // Description: - // Set the hash number/key used for database thumbnail and info records management - virtual void SetHash(uint32 hash) = 0; - // Description: - // Get the owner database for this asset - // Return Value: - // The owner database for this asset - // See Also: - // SetOwnerDatabase() - virtual IAssetItemDatabase* GetOwnerDatabase() const = 0; - // Description: - // Set the owner database for this asset - // Arguments: - // piOwnerDisplayDatabase - the owner database - // See Also: - // GetOwnerDatabase() - virtual void SetOwnerDatabase(IAssetItemDatabase* pOwnerDisplayDatabase) = 0; - // Description: - // Get the asset's dependency files / objects - // Return Value: - // The vector with filenames which this asset is dependent upon, ex.: ["Textures"].(vector of textures) - virtual const TAssetDependenciesMap& GetDependencies() const = 0; - // Description: - // Set the file size of this asset in bytes - // Arguments: - // aSize - size of the file in bytes - // See Also: - // GetFileSize() - virtual void SetFileSize(quint64 aSize) = 0; - // Description: - // Get the file size of this asset in bytes - // Return Value: - // The file size of this asset in bytes - // See Also: - // SetFileSize() - virtual quint64 GetFileSize() const = 0; - // Description: - // Set asset filename (extension included and no path) - // Arguments: - // pName - the asset filename (extension included and no path) - // See Also: - // GetFilename() - virtual void SetFilename(const char* pName) = 0; - // Description: - // Get asset filename (extension included and no path) - // Return Value: - // The asset filename (extension included and no path) - // See Also: - // SetFilename() - virtual QString GetFilename() const = 0; - // Description: - // Set the asset's relative path - // Arguments: - // pName - file's relative path - // See Also: - // GetRelativePath() - virtual void SetRelativePath(const char* pName) = 0; - // Description: - // Get the asset's relative path - // Return Value: - // The asset's relative path - // See Also: - // SetRelativePath() - virtual QString GetRelativePath() const = 0; - // Description: - // Set the file extension ( dot(s) must be included ) - // Arguments: - // pExt - the file's extension - // See Also: - // GetFileExtension() - virtual void SetFileExtension(const char* pExt) = 0; - // Description: - // Get the file extension ( dot(s) included ) - // Return Value: - // The file extension ( dot(s) included ) - // See Also: - // SetFileExtension() - virtual QString GetFileExtension() const = 0; - // Description: - // Get the asset flags, with values from IAssetItem::EAssetFlags - // Return Value: - // The asset flags, with values from IAssetItem::EAssetFlags - // See Also: - // SetFlags(), SetFlag(), IsFlagSet() - virtual UINT GetFlags() const = 0; - // Description: - // Set the asset flags - // Arguments: - // aFlags - flags, OR-ed values from IAssetItem::EAssetFlags - // See Also: - // GetFlags(), SetFlag(), IsFlagSet() - virtual void SetFlags(UINT aFlags) = 0; - // Description: - // Set/clear a single flag bit for the asset - // Arguments: - // aFlag - the flag to set/clear, with values from IAssetItem::EAssetFlags - // See Also: - // GetFlags(), SetFlags(), IsFlagSet() - virtual void SetFlag(EAssetFlags aFlag, bool bSet = true) = 0; - // Description: - // Check if a specified flag is set - // Arguments: - // aFlag - the flag to check, with values from IAssetItem::EAssetFlags - // Return Value: - // True if the flag is set - // See Also: - // GetFlags(), SetFlags(), SetFlag() - virtual bool IsFlagSet(EAssetFlags aFlag) const = 0; - // Description: - // Set this asset's index; used in sorting, selections, and to know where an asset is in the current list - // Arguments: - // aIndex - the asset's index - // See Also: - // GetIndex() - virtual void SetIndex(UINT aIndex) = 0; - // Description: - // Get the asset's index in the current list - // Return Value: - // The asset's index in the current list - // See Also: - // SetIndex() - virtual UINT GetIndex() const = 0; - // Description: - // Get the asset's field raw data value into a user location, you must check the field's type ( from asset item's owner database ) - // before using this function and send the correct pointer to destination according to the type ( int8, float32, string, etc. ) - // Arguments: - // pFieldName - the asset field name to query the value for - // pDest - the destination variable address, must be the same type as the field type - // Return Value: - // True if the asset field name is found and the value is returned correctly - // See Also: - // SetAssetFieldValue() - virtual QVariant GetAssetFieldValue(const char* pFieldName) const = 0; - // Description: - // Set the asset's field raw data value from a user location, you must check the field's type ( from asset item's owner database ) - // before using this function and send the correct pointer to source according to the type ( int8, float32, string, etc. ) - // Arguments: - // pFieldName - the asset field name to set the value for - // pSrc - the source variable address, must be the same type as the field type - // Return Value: - // True if the asset field name is found and the value is set correctly - // See Also: - // GetAssetFieldValue() - virtual bool SetAssetFieldValue(const char* pFieldName, void* pSrc) = 0; - // Description: - // Get the drawing rectangle for the asset's thumb ( absolute viewer canvas location ) - // Arguments: - // rstDrawingRectangle - destination location to set with the asset's thumbnail rectangle location - // See Also: - // SetDrawingRectangle() - virtual void GetDrawingRectangle(QRect& rstDrawingRectangle) const = 0; - // Description: - // Set the drawing rectangle for the asset's thumb ( absolute viewer canvas location ) - // Arguments: - // crstDrawingRectangle - source to set the asset's thumbnail rectangle - // See Also: - // GetDrawingRectangle() - virtual void SetDrawingRectangle(const QRect& crstDrawingRectangle) = 0; - // Description: - // Checks if the given 2D point is inside the asset's thumb rectangle - // Arguments: - // nX - mouse pointer position on X axis, relative to the asset viewer control - // nY - mouse pointer position on Y axis, relative to the asset viewer control - // Return Value: - // True if the given 2D point is inside the asset's thumb rectangle - // See Also: - // HitTest(CRect) - virtual bool HitTest(int nX, int nY) const = 0; - // Description: - // Checks if the given rectangle intersects the asset thumb's rectangle - // Arguments: - // nX - mouse pointer position on X axis, relative to the asset viewer control - // nY - mouse pointer position on Y axis, relative to the asset viewer control - // Return Value: - // True if the given rectangle intersects the asset thumb's rectangle - // See Also: - // HitTest(int nX,int nY) - virtual bool HitTest(const QRect& roTestRect) const = 0; - // Description: - // When user drags this asset item into a viewport, this method is called when the dragging operation ends - // and the mouse button is released, for the asset to return an instance of the asset object to be placed in the level - // Arguments: - // aX - instance's X position component in world coordinates - // aY - instance's Y position component in world coordinates - // aZ - instance's Z position component in world coordinates - // Return Value: - // The newly created asset instance (Example: BrushObject*) - // See Also: - // MoveInstanceInViewport() - virtual void* CreateInstanceInViewport(float aX, float aY, float aZ) = 0; - // Description: - // When the mouse button is released after level object creation, the user now can move the mouse - // and move the asset instance in the 3D world - // Arguments: - // pDraggedObject - the actual entity or brush object (CBaseObject* usually) to be moved around with the mouse - // returned by the CreateInstanceInViewport() - // aNewX - the new X world coordinates of the asset instance - // aNewY - the new Y world coordinates of the asset instance - // aNewZ - the new Z world coordinates of the asset instance - // Return Value: - // True if asset instance was moved properly - // See Also: - // CreateInstanceInViewport() - virtual bool MoveInstanceInViewport(const void* pDraggedObject, float aNewX, float aNewY, float aNewZ) = 0; - // Description: - // This will be called when the user presses ESCAPE key when dragging the asset in the viewport, you must delete the given object - // because the creation was aborted - // Arguments: - // pDraggedObject - the asset instance to be deleted ( you must cast to the needed type, and delete it properly ) - // See Also: - // CreateInstanceInViewport() - virtual void AbortCreateInstanceInViewport(const void* pDraggedObject) = 0; - // Description: - // This method is used to cache/load asset's data, so it can be previewed/rendered - // Return Value: - // True if the asset was successfully cached - // See Also: - // UnCache() - virtual bool Cache() = 0; - // Description: - // This method is used to force cache/load asset's data, so it can be previewed/rendered - // Return Value: - // True if the asset was successfully forced cached - // See Also: - // UnCache(), Cache() - virtual bool ForceCache() = 0; - // Description: - // This method is used to load the thumbnail image of the asset - // Return Value: - // True if thumb loaded ok - // See Also: - // UnloadThumbnail() - virtual bool LoadThumbnail() = 0; - // Description: - // This method is used to unload the thumbnail image of the asset - // See Also: - // LoadThumbnail() - virtual void UnloadThumbnail() = 0; - // Description: - // This is called when the asset starts to be previewed in full detail, so here you can load the whole asset, in fine detail - // ( textures are fully loaded, models etc. ). It is called once, when the Preview dialog is shown - // Arguments: - // hPreviewWnd - the window handle of the quick preview dialog - // hMemDC - the memory DC used to render assets that can render themselves in the DC, otherwise they will render in the dialog's HWND - // See Also: - // OnEndPreview(), GetCustomPreviewPanelHeader() - virtual void OnBeginPreview(QWidget* hPreviewWnd) = 0; - // Description: - // Called when the Preview dialog is closed, you may release the detail asset data here - // See Also: - // OnBeginPreview(), GetCustomPreviewPanelHeader() - virtual void OnEndPreview() = 0; - // Description: - // If the asset has a special preview panel with utility controls, to be placed at the top of the Preview window, it can return an child dialog window - // otherwise it can return nullptr, if no panel is available - // Arguments: - // pParentWnd - a valid CDialog*, or nullptr - // Return Value: - // A valid child dialog window handle, if this asset wants to have a custom panel in the top side of the Asset Preview window, - // otherwise it can return nullptr, if no panel is available - // See Also: - // OnBeginPreview(), OnEndPreview() - virtual QWidget* GetCustomPreviewPanelHeader(QWidget* pParentWnd) = 0; - virtual QWidget* GetCustomPreviewPanelFooter(QWidget* pParentWnd) = 0; - // Description: - // Used when dragging/rotate/zoom a model, or other asset that can support preview - // Arguments: - // hRenderWindow - the rendering window handle - // rstViewport - the viewport rectangle - // aMouseX - the render window relative mouse pointer X coordinate - // aMouseY - the render window relative mouse pointer Y coordinate - // aMouseDeltaX - the X coordinate delta between two mouse movements - // aMouseDeltaY - the Y coordinate delta between two mouse movements - // aMouseWheelDelta - the mouse wheel scroll delta/step - // aKeyFlags - the key flags, see WM_LBUTTONUP - // See Also: - // OnPreviewRenderKeyEvent() - virtual void PreviewRender( - QWidget* hRenderWindow, - const QRect& rstViewport, - int aMouseX = 0, int aMouseY = 0, - int aMouseDeltaX = 0, int aMouseDeltaY = 0, - int aMouseWheelDelta = 0, UINT aKeyFlags = 0) = 0; - // Description: - // This is called when the user manipulates the assets in interactive render and a key is pressed ( with down or up state ) - // Arguments: - // bKeyDown - true if this is a WM_KEYDOWN event, else it is a WM_KEYUP event - // aChar - the char/key code pressed/released - // aKeyFlags - the key flags, compatible with WM_KEYDOWN/UP events - // See Also: - // InteractiveRender() - virtual void OnPreviewRenderKeyEvent(bool bKeyDown, UINT aChar, UINT aKeyFlags) = 0; - // Description: - // Called when user clicked once on the thumb image - // Arguments: - // point - mouse coordinates relative to the thumbnail rectangle - // aKeyFlags - the key flags, see WM_LBUTTONDOWN - // See Also: - // OnThumbDblClick() - virtual void OnThumbClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0; - // Description: - // Called when user double clicked on the thumb image - // Arguments: - // point - mouse coordinates relative to the thumbnail rectangle - // aKeyFlags - the key flags, see WM_LBUTTONDOWN - // See Also: - // OnThumbClick() - //! called when user clicked twice on the thumb image - virtual void OnThumbDblClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0; - // Description: - // Draw the cached thumb bitmap only, if any, no other kind of rendering - // Arguments: - // hDC - the destination DC, where to draw the thumb - // rRect - the destination rectangle - // Return Value: - // True if drawing of the thumbnail was done OK - // See Also: - // Render() - virtual bool DrawThumbImage(QPainter* painter, const QRect& rRect) = 0; - // Description: - // Writes asset info to a XML node. - // This is needed to save cached info as a persistent XML file for the next run of the editor. - // Arguments: - // node - An XML node to contain the info - // See Also: - // FromXML() - virtual void ToXML(XmlNodeRef& node) const = 0; - // Description: - // Gets asset info from a XML node. - // This is needed to get the asset info from previous runs of the editor without re-caching it. - // Arguments: - // node - An XML node that contains info for this asset - // See Also: - // ToXML() - virtual void FromXML(const XmlNodeRef& node) = 0; - - // From IUnknown - virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] const IID& riid, [[maybe_unused]] void** ppvObject) - { - return E_NOINTERFACE; - }; - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return 0; - }; - virtual ULONG STDMETHODCALLTYPE Release() - { - return 0; - }; -}; -#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H diff --git a/Code/Editor/Include/IAssetItemDatabase.h b/Code/Editor/Include/IAssetItemDatabase.h deleted file mode 100644 index 39fd60e8c6..0000000000 --- a/Code/Editor/Include/IAssetItemDatabase.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Standard interface for asset database creators used to -// create an asset plugin for the asset browser -// The category of the plugin must be Asset Item DB - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H -#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H -#pragma once -struct IAssetItem; -struct IAssetViewer; - -class QString; -class QStringList; - -// Description: -// This struct keeps the info, filter and sorting settings for an asset field -struct SAssetField -{ - // the condition for the current filter on the field - enum EAssetFilterCondition - { - eCondition_Any = 0, - // string conditions - // this also supports '*' and '?' as wildcards inside text - eCondition_Contains, - // this filter will search the target for at least one of the words specified - // ( ex: filter: "water car moon" , field value : "the_great_moon.dds", this will pass the test - // it also supports '*' and '?' as wildcards inside words text - eCondition_ContainsOneOfTheWords, - eCondition_StartsWith, - eCondition_EndsWith, - // string & numerical conditions - eCondition_Equal, - eCondition_Greater, - eCondition_Less, - eCondition_GreaterOrEqual, - eCondition_LessOrEqual, - eCondition_Not, - eCondition_InsideRange - }; - - // the asset field type - enum EAssetFieldType - { - eType_None = 0, - eType_Bool, - eType_Int8, - eType_Int16, - eType_Int32, - eType_Int64, - eType_Float, - eType_Double, - eType_String - }; - - // used when a field can have different specific values - typedef QStringList TFieldEnumValues; - - SAssetField( - const char* pFieldName = "", - const char* pDisplayName = "Unnamed field", - EAssetFieldType aFieldType = eType_None, - UINT aColumnWidth = 50, - bool bVisibleInUI = true, - bool bReadOnly = true) - { - m_fieldName = pFieldName; - m_displayName = pDisplayName; - m_fieldType = aFieldType; - m_filterCondition = eCondition_Equal; - m_bUseEnumValues = false; - m_bReadOnly = bReadOnly; - m_listColumnWidth = aColumnWidth; - m_bFieldVisibleInUI = bVisibleInUI; - m_bPostFilter = false; - - SetupEnumValues(); - } - - void SetupEnumValues() - { - m_bUseEnumValues = true; - - if (m_fieldType == eType_Bool) - { - m_enumValues.clear(); - m_enumValues.push_back("Yes"); - m_enumValues.push_back("No"); - } - } - - // the field's display name, used in UI - QString m_displayName, - // the field internal name, used in C++ code - m_fieldName, - // the current filter value, if its empty "" then no filter is applied - m_filterValue, - // the field's max value, valid when the field's filter condition is eAssertFilterCondition_InsideRange - m_maxFilterValue, - // the name of the database holding this field, used in Asset Browser preset editor, if its "" then the field - // is common to all current databases - m_parentDatabaseName; - // is this field visible in the UI ? - bool m_bFieldVisibleInUI, - // if true, then you cannot modify this field of an asset item, only use it - m_bReadOnly, - // this field filter is applied after the other filters - m_bPostFilter; - // the field data type - EAssetFieldType m_fieldType; - // the filter's condition - EAssetFilterCondition m_filterCondition; - // use the enum list values to choose a value for the field ? - bool m_bUseEnumValues; - // this map is used when asset field has m_bUseEnumValues on true, - // choose a value for the field from this list in the UI - TFieldEnumValues m_enumValues; - // recommended list column width - unsigned int m_listColumnWidth; -}; - -struct SFieldFiltersPreset -{ - QString presetName2; - QStringList checkedDatabaseNames; - bool bUsedInLevel; - std::vector fields; -}; - -// Description: -// This interface allows the programmer to extend asset display types -// visible in the asset browser. -struct IAssetItemDatabase - : public IUnknown -{ - DEFINE_UUID(0xFB09B039, 0x1D9D, 0x4057, 0xA5, 0xF0, 0xAA, 0x3C, 0x7B, 0x97, 0xAE, 0xA8) - - typedef std::vector TAssetFields; - typedef std::map < QString/*field name*/, SAssetField > TAssetFieldFiltersMap; - typedef std::map < QString/*asset filename*/, IAssetItem* > TFilenameAssetMap; - typedef AZStd::function MetaDataChangeListener; - - // Description: - // Refresh the database by scanning the folders/paks for files, does not load the files, only filename and filesize are fetched - virtual void Refresh() = 0; - // Description: - // Fills the asset meta data from the loaded xml meta data DB. - // Arguments: - // db - the database XML node from where to cache the info - virtual void PrecacheFieldsInfoFromFileDB(const XmlNodeRef& db) = 0; - // Description: - // Return all assets loaded/scanned by this database - // Return Value: - // The assets map reference (filename-asset) - virtual TFilenameAssetMap& GetAssets() = 0; - // Description: - // Get an asset item by its filename - // Return Value: - // A single asset from the database given the filename - virtual IAssetItem* GetAsset(const char* pAssetFilename) = 0; - // Description: - // Return the asset fields this database's items support - // Return Value: - // The asset fields vector reference - virtual TAssetFields& GetAssetFields() = 0; - // Description: - // Return an asset field object pointer by the field internal name - // Arguments: - // pFieldName - the internal field's name (ex: "filename", "relativepath") - // Return Value: - // The asset field object pointer - virtual SAssetField* GetAssetFieldByName(const char* pFieldName) = 0; - // Description: - // Get the database name - // Return Value: - // Returns the database name, ex: "Textures" - virtual const char* GetDatabaseName() const = 0; - // Description: - // Get the database supported file name extension(s) - // Return Value: - // Returns the supported extensions, separated by comma, ex: "tga,bmp,dds" - virtual const char* GetSupportedExtensions() const = 0; - // Description: - // Free the database internal data structures - virtual void FreeData() = 0; - // Description: - // Apply filters to this database which will set/unset the IAssetItem::eAssetFlag_Visible of each asset, based - // on the given field filters - // Arguments: - // rFieldFilters - a reference to the field filters map (fieldname-field) - // See Also: - // ClearFilters() - virtual void ApplyFilters(const TAssetFieldFiltersMap& rFieldFilters) = 0; - // Description: - // Clear the current filters, by setting the IAssetItem::eAssetFlag_Visible of each asset to true - // See Also: - // ApplyFilters() - virtual void ClearFilters() = 0; - virtual QWidget* CreateDbFilterDialog(QWidget* pParent, IAssetViewer* pViewerCtrl) = 0; - virtual void UpdateDbFilterDialogUI(QWidget* pDlg) = 0; - virtual void OnAssetBrowserOpen() = 0; - virtual void OnAssetBrowserClose() = 0; - // Description: - // Gets the filename for saving new cached asset info. - // Return Value: - // A file name to save new transactions to the persistent asset info DB - // See Also: - // CAssetInfoFileDB, IAssetItem::ToXML(), IAssetItem::FromXML() - virtual const char* GetTransactionFilename() const = 0; - // Description: - // Adds a callback to be called when the meta data of this asset changed. - // Arguments: - // callBack - A functor to be added - // Return Value: - // True if successful, false otherwise. - // See Also: - // RemoveMetaDataChangeListener() - virtual bool AddMetaDataChangeListener(MetaDataChangeListener callBack) = 0; - // Description: - // Removes a callback from the list of meta data change listeners. - // Arguments: - // callBack - A functor to be removed - // Return Value: - // True if successful, false otherwise. - // See Also: - // AddMetaDataCHangeListener() - virtual bool RemoveMetaDataChangeListener(MetaDataChangeListener callBack) = 0; - // Description: - // The method that should be called when the meta data of an asset item changes to notify all listeners - // Arguments: - // pAssetItem - An asset item whose meta data have changed - // See Also: - // AddMetaDataCHangeListener(), RemoveMetaDataChangeListener() - virtual void OnMetaDataChange(const IAssetItem* pAssetItem) = 0; - - //! from IUnknown - virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] REFIID riid, [[maybe_unused]] void** ppvObject) - { - return E_NOINTERFACE; - }; - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return 0; - }; - virtual ULONG STDMETHODCALLTYPE Release() - { - return 0; - }; -}; -#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H diff --git a/Code/Editor/Include/IAssetViewer.h b/Code/Editor/Include/IAssetViewer.h deleted file mode 100644 index 488ee8e508..0000000000 --- a/Code/Editor/Include/IAssetViewer.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : This file declares a control which objective is to display -// multiple assets allowing selection and preview of such things -// It also handles scrolling and changes in the thumbnail display size - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H -#pragma once -#include "IObservable.h" -#include "IAssetItemDatabase.h" - -struct IAssetItem; -struct IAssetItemDatabase; - -// Description: -// Observer for the asset viewer events -struct IAssetViewerObserver -{ - virtual void OnChangeStatusBarInfo(UINT nSelectedItems, UINT nVisibleItems, UINT nTotalItems) {}; - virtual void OnSelectionChanged() {}; - virtual void OnChangedPreviewedAsset(IAssetItem* pAsset) {}; - virtual void OnAssetDblClick(IAssetItem* pAsset) {}; - virtual void OnAssetFilterChanged() {}; -}; - -// Description: -// The asset viewer interface for the asset database plugins to use -struct IAssetViewer -{ - DEFINE_OBSERVABLE_PURE_METHODS(IAssetViewerObserver); - - virtual HWND GetRenderWindow() = 0; - virtual void ApplyFilters(const IAssetItemDatabase::TAssetFieldFiltersMap& rFieldFilters) = 0; - virtual const IAssetItemDatabase::TAssetFieldFiltersMap& GetCurrentFilters() = 0; - virtual void ClearFilters() = 0; -}; -#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H diff --git a/Code/Editor/Include/IFileUtil.h b/Code/Editor/Include/IFileUtil.h index 036a0bc5ee..ea2fe1f1a3 100644 --- a/Code/Editor/Include/IFileUtil.h +++ b/Code/Editor/Include/IFileUtil.h @@ -116,9 +116,6 @@ struct IFileUtil virtual bool ExtractFile(QString& file, bool bMsgBoxAskForExtraction = true, const char* pDestinationFilename = nullptr) = 0; virtual void EditTextureFile(const char* txtureFile, bool bUseGameFolder) = 0; - //! dcc filename calculation and extraction sub-routines - virtual bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename) = 0; - //! Reformat filter string for (MFC) CFileDialog style file filtering virtual void FormatFilterString(QString& filter) = 0; diff --git a/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.cpp b/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.cpp deleted file mode 100644 index 736465cac1..0000000000 --- a/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SimpleTriangleRasterizer.h" - -#include - -#if !defined FLT_MAX -#define FLT_MAX 3.402823466e+38F -#endif - -void CSimpleTriangleRasterizer::lambertHorizlineConservative(float fx1, float fx2, int yy, IRasterizeSink* inpSink) -{ - int x1 = (int)floorf(fx1 + 0.25f), x2 = (int)floorf(fx2 + .75f); - - if (x1 < m_iMinX) - { - x1 = m_iMinX; - } - if (x2 > m_iMaxX + 1) - { - x2 = m_iMaxX + 1; - } - if (x1 > m_iMaxX + 1) - { - x1 = m_iMaxX + 1; - } - if (x2 < m_iMinX) - { - x2 = m_iMinX; - } - - - inpSink->Line(fx1, fx2, x1, x2, yy); -} - -void CSimpleTriangleRasterizer::lambertHorizlineSubpixelCorrect(float fx1, float fx2, int yy, IRasterizeSink* inpSink) -{ - int x1 = (int)floorf(fx1 + 0.5f), x2 = (int)floorf(fx2 + 0.5f); - // int x1=(int)floorf(fx1*1023.f/1024.f+1.f),x2=(int)floorf(fx2*1023.f/1024.f+1.f); - - if (x1 < m_iMinX) - { - x1 = m_iMinX; - } - if (x2 > m_iMaxX) - { - x2 = m_iMaxX; - } - if (x1 > m_iMaxX) - { - x1 = m_iMaxX; - } - if (x2 < m_iMinX) - { - x2 = m_iMinX; - } - - inpSink->Line(fx1, fx2, x1, x2, yy); -} - -// optimizable -void CSimpleTriangleRasterizer::CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3]) -{ - outfX[0] = infX[0]; - outfY[0] = infY[0]; - outfX[1] = infX[1]; - outfY[1] = infY[1]; - outfX[2] = infX[2]; - outfY[2] = infY[2]; - - // Sort the coordinates, so that (x[1], y[1]) becomes the highest coord - float tmp; - - if (outfY[0] > outfY[1]) - { - if (outfY[1] > outfY[2]) - { - tmp = outfY[0]; - outfY[0] = outfY[1]; - outfY[1] = tmp; - tmp = outfX[0]; - outfX[0] = outfX[1]; - outfX[1] = tmp; - tmp = outfY[1]; - outfY[1] = outfY[2]; - outfY[2] = tmp; - tmp = outfX[1]; - outfX[1] = outfX[2]; - outfX[2] = tmp; - - if (outfY[0] > outfY[1]) - { - tmp = outfY[0]; - outfY[0] = outfY[1]; - outfY[1] = tmp; - tmp = outfX[0]; - outfX[0] = outfX[1]; - outfX[1] = tmp; - } - } - else - { - tmp = outfY[0]; - outfY[0] = outfY[1]; - outfY[1] = tmp; - tmp = outfX[0]; - outfX[0] = outfX[1]; - outfX[1] = tmp; - - if (outfY[1] > outfY[2]) - { - tmp = outfY[1]; - outfY[1] = outfY[2]; - outfY[2] = tmp; - tmp = outfX[1]; - outfX[1] = outfX[2]; - outfX[2] = tmp; - } - } - } - else - { - if (outfY[1] > outfY[2]) - { - tmp = outfY[1]; - outfY[1] = outfY[2]; - outfY[2] = tmp; - tmp = outfX[1]; - outfX[1] = outfX[2]; - outfX[2] = tmp; - - if (outfY[0] > outfY[1]) - { - tmp = outfY[0]; - outfY[0] = outfY[1]; - outfY[1] = tmp; - tmp = outfX[0]; - outfX[0] = outfX[1]; - outfX[1] = tmp; - } - } - } -} - -void CSimpleTriangleRasterizer::CallbackFillRectConservative(float _x[3], float _y[3], IRasterizeSink* inpSink) -{ - inpSink->Triangle(m_iMinY); - - float fMinX = (std::min)(_x[0], (std::min)(_x[1], _x[2])); - float fMaxX = (std::max)(_x[0], (std::max)(_x[1], _x[2])); - float fMinY = (std::min)(_y[0], (std::min)(_y[1], _y[2])); - float fMaxY = (std::max)(_y[0], (std::max)(_y[1], _y[2])); - - int iMinX = (std::max)(m_iMinX, (int)floorf(fMinX)); - int iMaxX = (std::min)(m_iMaxX + 1, (int)ceilf(fMaxX)); - int iMinY = (std::max)(m_iMinY, (int)floorf(fMinY)); - int iMaxY = (std::min)(m_iMaxY + 1, (int)ceilf(fMaxY)); - - for (int y = iMinY; y < iMaxY; y++) - { - inpSink->Line(fMinX, fMaxX, iMinX, iMaxX, y); - } -} - - - - -void CSimpleTriangleRasterizer::CallbackFillConservative(float _x[3], float _y[3], IRasterizeSink* inpSink) -{ - float x[3], y[3]; - - CopyAndSortY(_x, _y, x, y); - - // Calculate interpolation steps - float fX1toX2step = 0.0f; - float fX1toX3step = 0.0f; - float fX2toX3step = 0.0f; - if (fabsf(y[1] - y[0]) > FLT_EPSILON) - { - fX1toX2step = (x[1] - x[0]) / (float)(y[1] - y[0]); - } - if (fabsf(y[2] - y[0]) > FLT_EPSILON) - { - fX1toX3step = (x[2] - x[0]) / (float)(y[2] - y[0]); - } - if (fabsf(y[2] - y[1]) > FLT_EPSILON) - { - fX2toX3step = (x[2] - x[1]) / (float)(y[2] - y[1]); - } - - float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1]; - bool bFirstLine = true; - bool bTriangleCallDone = false; - - // Go through the scanlines of the triangle - int yy = (int)floorf(y[0]); // was floor - - for (; yy <= (int)floorf(y[2]); yy++) - // for(yy=m_iMinY; yy<=m_iMaxY; yy++) // juhu - { - float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f; - float start, end; - - // first line - if (bFirstLine) - { - fSubPixelYStart = y[0] - floorf(y[0]); - start = x[0]; - end = x[0]; - bFirstLine = false; - } - else - { - // top part without middle corner line - if (yy <= (int)floorf(y[1])) - { - start = (std::min)(fX1toX2, fX1toX3); - end = (std::max)(fX1toX2, fX1toX3); - } - else - { - start = (std::min)(fX2toX3, fX1toX3); - end = (std::max)(fX2toX3, fX1toX3); - } - } - - // middle corner line - if (yy == (int)floorf(y[1])) - { - fSubPixelYEnd = y[1] - floorf(y[1]); - - fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart); - start = (std::min)(start, fX1toX3); - end = (std::max)(end, fX1toX3); - start = (std::min)(start, x[1]); - end = (std::max)(end, x[1]); - - fSubPixelYStart = fSubPixelYEnd; - fSubPixelYEnd = 1.0f; - } - - // last line - if (yy == (int)floorf(y[2])) - { - start = (std::min)(start, x[2]); - end = (std::max)(end, x[2]); - } - else - { - // top part without middle corner line - if (yy < (int)floorf(y[1])) - { - fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart); - start = (std::min)(start, fX1toX2); - end = (std::max)(end, fX1toX2); - } - else - { - fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart); - start = (std::min)(start, fX2toX3); - end = (std::max)(end, fX2toX3); - } - - fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart); - start = (std::min)(start, fX1toX3); - end = (std::max)(end, fX1toX3); - } - - if (yy >= m_iMinY && yy <= m_iMaxY) - { - if (!bTriangleCallDone) - { - inpSink->Triangle(yy); - bTriangleCallDone = true; - } - - lambertHorizlineConservative(start, end, yy, inpSink); - } - } -} - - - -void CSimpleTriangleRasterizer::CallbackFillSubpixelCorrect(float _x[3], float _y[3], IRasterizeSink* inpSink) -{ - float x[3], y[3]; - - CopyAndSortY(_x, _y, x, y); - - if (fabs(y[0] - floorf(y[0])) < FLT_EPSILON) - { - y[0] -= FLT_EPSILON; - } - - // Calculate interpolation steps - float fX1toX2step = 0.0f; - float fX1toX3step = 0.0f; - float fX2toX3step = 0.0f; - if (fabsf(y[1] - y[0]) > FLT_EPSILON) - { - fX1toX2step = (x[1] - x[0]) / (y[1] - y[0]); - } - if (fabsf(y[2] - y[0]) > FLT_EPSILON) - { - fX1toX3step = (x[2] - x[0]) / (y[2] - y[0]); - } - if (fabsf(y[2] - y[1]) > FLT_EPSILON) - { - fX2toX3step = (x[2] - x[1]) / (y[2] - y[1]); - } - - float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1]; - bool bFirstLine = true; - bool bTriangleCallDone = false; - - y[0] -= 0.5f; - y[1] -= 0.5f; - y[2] -= 0.5f; - // y[0]=y[0]*1023.f/1024.f+1.f; - // y[1]=y[1]*1023.f/1024.f+1.f; - // y[2]=y[2]*1023.f/1024.f+1.f; - - for (int yy = (int)floorf(y[0]); yy <= (int)floorf(y[2]); yy++) - { - float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f; - float start, end; - - // first line - if (bFirstLine) - { - fSubPixelYStart = y[0] - floorf(y[0]); - start = x[0]; - end = x[0]; - bFirstLine = false; - } - else - { - // top part without middle corner line - if (yy <= (int)floorf(y[1])) - { - start = (std::min)(fX1toX2, fX1toX3); - end = (std::max)(fX1toX2, fX1toX3); - } - else - { - start = (std::min)(fX2toX3, fX1toX3); - end = (std::max)(fX2toX3, fX1toX3); - } - } - - // middle corner line - if (yy == (int)floorf(y[1])) - { - fSubPixelYEnd = y[1] - floorf(y[1]); - - fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart); - - fSubPixelYStart = fSubPixelYEnd; - fSubPixelYEnd = 1.0f; - } - - // last line - if (yy != (int)floorf(y[2])) - { - // top part without middle corner line - if (yy < (int)floorf(y[1])) - { - fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart); - } - else - { - fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart); - } - - fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart); - } - - if (start != end) - { - if (yy >= m_iMinY && yy <= m_iMaxY) - { - if (!bTriangleCallDone) - { - inpSink->Triangle(yy); - bTriangleCallDone = true; - } - - lambertHorizlineSubpixelCorrect(start, end, yy, inpSink); - } - } - } -} - - - - -// shrink triangle by n pixel, optimizable -void CSimpleTriangleRasterizer::ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount) -{ - float fX[3] = { inoutfX[0], inoutfX[1], inoutfX[2] }; - float fY[3] = { inoutfY[0], inoutfY[1], inoutfY[2] }; - - /* - // move edge to opposing vertex - float dx,dy,fLength; - - for(int a=0;a<3;a++) - { - int b=a+1;if(b>=3)b=0; - int c=b+1;if(c>=3)c=0; - - dx=fX[a]-(fX[b]+fX[c])*0.5f; - dy=fY[a]-(fY[b]+fY[c])*0.5f; - fLength=(float)sqrt(dx*dx+dy*dy); - if(fLength>1.0f) - { - dx/=fLength;dy/=fLength; - inoutfX[b]+=dx;inoutfY[b]+=dy; - inoutfX[c]+=dx;inoutfY[c]+=dy; - } - } - */ - - /* - // move vertex to opposing edge - float dx,dy,fLength; - - for(int a=0;a<3;a++) - { - int b=a+1;if(b>=3)b=0; - int c=b+1;if(c>=3)c=0; - - dx=fX[a]-(fX[b]+fX[c])*0.5f; - dy=fY[a]-(fY[b]+fY[c])*0.5f; - fLength=(float)sqrt(dx*dx+dy*dy); - if(fLength>1.0f) - { - dx/=fLength;dy/=fLength; - inoutfX[a]-=dx;inoutfY[a]-=dy; - } - } - */ - - // move vertex to get edges shifted perpendicular for 1 unit - for (int a = 0; a < 3; a++) - { - float dx1, dy1, dx2, dy2, fLength; - - int b = a + 1; - if (b >= 3) - { - b = 0; - } - int c = b + 1; - if (c >= 3) - { - c = 0; - } - - dx1 = fX[b] - fX[a]; - dy1 = fY[b] - fY[a]; - fLength = (float)sqrt(dx1 * dx1 + dy1 * dy1); - if (infAmount > 0) - { - if (fLength < infAmount) - { - continue; - } - } - if (fLength == 0.0f) - { - continue; - } - dx1 /= fLength; - dy1 /= fLength; - - dx2 = fX[c] - fX[a]; - dy2 = fY[c] - fY[a]; - fLength = (float)sqrt(dx2 * dx2 + dy2 * dy2); - if (infAmount > 0) - { - if (fLength < infAmount) - { - continue; - } - } - if (fLength == 0.0f) - { - continue; - } - dx2 /= fLength; - dy2 /= fLength; - - inoutfX[a] += (dx1 + dx2) * infAmount; - inoutfY[a] += (dy1 + dy2) * infAmount; - } -} diff --git a/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.h b/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.h deleted file mode 100644 index bcfdd7b6da..0000000000 --- a/Code/Editor/LightmapCompiler/SimpleTriangleRasterizer.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H -#define CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H -#pragma once - -class CSimpleTriangleRasterizer -{ -public: - - class IRasterizeSink - { - public: - - //! is called once per triangel for the first possible visible line - //! /param iniStartY - virtual void Triangle([[maybe_unused]] const int iniStartY) - { - } - - //! callback function - //! /param infXLeft included - not clipped against left and reight border - //! /param infXRight excluded - not clipped against left and reight border - //! /param iniXLeft included - //! /param iniXRight excluded - //! /param iniY - virtual void Line(const float infXLeft, const float infXRight, - const int iniXLeft, const int iniXRight, const int iniY) = 0; - }; - - typedef unsigned long DWORD; - - // ----------------------------------------------------- - - //! implementation sink sample - class CDWORDFlatFill - : public IRasterizeSink - { - public: - - //! constructor - CDWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, DWORD indwValue) - { - m_dwValue = indwValue; - m_pBuffer = inpBuffer; - m_dwPitchInPixels = indwPitchInPixels; - } - - virtual void Triangle(const int iniY) - { - m_pBufferLine = &m_pBuffer[iniY * m_dwPitchInPixels]; - } - - virtual void Line([[maybe_unused]] const float infXLeft, [[maybe_unused]] const float infXRight, - const int iniLeft, const int iniRight, [[maybe_unused]] const int iniY) - { - DWORD* mem = &m_pBufferLine[iniLeft]; - - for (int x = iniLeft; x < iniRight; x++) - { - *mem++ = m_dwValue; - } - - m_pBufferLine += m_dwPitchInPixels; - } - - private: - DWORD m_dwValue; //!< fill value - DWORD* m_pBufferLine; //!< to get rid of the multiplication per line - - DWORD m_dwPitchInPixels; //!< in DWORDS, not in Bytes - DWORD* m_pBuffer; //!< pointer to the buffer - }; - - // ----------------------------------------------------- - - //! constructor - //! /param iniWidth excluded - //! /param iniHeight excluded - CSimpleTriangleRasterizer(const int iniWidth, const int iniHeight) - { - m_iMinX = 0; - m_iMinY = 0; - m_iMaxX = iniWidth - 1; - m_iMaxY = iniHeight - 1; - } - /* - //! constructor - //! /param iniMinX included - //! /param iniMinY included - //! /param iniMaxX included - //! /param iniMaxY included - CSimpleTriangleRasterizer( const int iniMinX, const int iniMinY, const int iniMaxX, const int iniMaxY ) - { - m_iMinX=iniMinX; - m_iMinY=iniMinY; - m_iMaxX=iniMaxX; - m_iMaxY=iniMaxY; - } - */ - //! simple triangle filler with clipping (optimizable), not subpixel correct - //! /param pBuffer pointer o the color buffer - //! /param indwWidth width of the color buffer - //! /param indwHeight height of the color buffer - //! /param x array of the x coordiantes of the three vertices - //! /param y array of the x coordiantes of the three vertices - //! /param indwValue value of the triangle - void DWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, float x[3], float y[3], DWORD indwValue, bool inbConservative) - { - CDWORDFlatFill pix(inpBuffer, indwPitchInPixels, indwValue); - - if (inbConservative) - { - CallbackFillConservative(x, y, &pix); - } - else - { - CallbackFillSubpixelCorrect(x, y, &pix); - } - } - - // Rectangle around triangle - more stable - use for debugging purpose - void CallbackFillRectConservative(float x[3], float y[3], IRasterizeSink * inpSink); - - - //! subpixel correct triangle filler (conservative or not conservative) - //! \param pBuffer pointe to the DWORD - //! \param indwWidth width of the buffer pBuffer pointes to - //! \param indwHeight height of the buffer pBuffer pointes to - //! \param x array of the x coordiantes of the three vertices - //! \param y array of the x coordiantes of the three vertices - //! \param inpSink pointer to the sink interface (is called per triangle and per triangle line) - void CallbackFillConservative(float x[3], float y[3], IRasterizeSink * inpSink); - - //! subpixel correct triangle filler (conservative or not conservative) - //! \param pBuffer pointe to the DWORD - //! \param indwWidth width of the buffer pBuffer pointes to - //! \param indwHeight height of the buffer pBuffer pointes to - //! \param x array of the x coordiantes of the three vertices - //! \param y array of the x coordiantes of the three vertices - //! \param inpSink pointer to the sink interface (is called per triangle and per triangle line) - void CallbackFillSubpixelCorrect(float x[3], float y[3], IRasterizeSink * inpSink); - - //! - //! /param inoutfX - //! /param inoutfY - //! /param infAmount could be positive or negative - static void ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount); - -private: - - // Clipping Rect; - - int m_iMinX; //!< minimum x value included - int m_iMinY; //!< minimum y value included - int m_iMaxX; //!< maximum x value included - int m_iMaxY; //!< maximum x value included - - void lambertHorizlineConservative(float fx1, float fx2, int y, IRasterizeSink* inpSink); - void lambertHorizlineSubpixelCorrect(float fx1, float fx2, int y, IRasterizeSink* inpSink); - void CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3]); -}; - - -// extension ideas: -// * callback with coverage mask (possible non ordered sampling) -// * z-buffer behaviour -// * gouraud shading -// * texture mapping with nearest/bicubic/bilinear filter -// * further primitives: thick line, ellipse -// * build a template version -// * - -#endif // CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H diff --git a/Code/Editor/Objects/ObjectManager.cpp b/Code/Editor/Objects/ObjectManager.cpp index 1dea6ece7f..06233d4dd2 100644 --- a/Code/Editor/Objects/ObjectManager.cpp +++ b/Code/Editor/Objects/ObjectManager.cpp @@ -26,7 +26,6 @@ #include "Util/Image.h" #include "ObjectManagerLegacyUndo.h" #include "Include/HitContext.h" -#include "EditMode/DeepSelection.h" #include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h" #include diff --git a/Code/Editor/Util/FileUtil.cpp b/Code/Editor/Util/FileUtil.cpp index 182a122ea8..ce2d399dcc 100644 --- a/Code/Editor/Util/FileUtil.cpp +++ b/Code/Editor/Util/FileUtil.cpp @@ -42,8 +42,6 @@ #include "CheckOutDialog.h" #include "ISourceControl.h" #include "Dialogs/Generic/UserOptions.h" -#include "IAssetItem.h" -#include "IAssetItemDatabase.h" #include "Include/IObjectManager.h" #include "UsedResources.h" #include "Objects/BaseObject.h" @@ -223,106 +221,6 @@ void CFileUtil::EditTextureFile(const char* textureFile, [[maybe_unused]] bool b } } - -////////////////////////////////////////////////////////////////////////// -bool CFileUtil::CalculateDccFilename(const QString& assetFilename, QString& dccFilename) -{ - if (ExtractDccFilenameFromAssetDatabase(assetFilename, dccFilename)) - { - return true; - } - - if (ExtractDccFilenameUsingNamingConventions(assetFilename, dccFilename)) - { - return true; - } - - GetIEditor()->GetEnv()->pLog->LogError("Failed to find psd file for texture: '%s'", assetFilename.toUtf8().data()); - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CFileUtil::ExtractDccFilenameFromAssetDatabase(const QString& assetFilename, QString& dccFilename) -{ - IAssetItemDatabase* pCurrentDatabaseInterface = nullptr; - std::vector assetDatabasePlugins; - IEditorClassFactory* pClassFactory = GetIEditor()->GetClassFactory(); - pClassFactory->GetClassesByCategory("Asset Item DB", assetDatabasePlugins); - - for (size_t i = 0; i < assetDatabasePlugins.size(); ++i) - { - if (assetDatabasePlugins[i]->QueryInterface(__az_uuidof(IAssetItemDatabase), (void**)&pCurrentDatabaseInterface) == S_OK) - { - if (!pCurrentDatabaseInterface) - { - continue; - } - - QString assetDatabaseDccFilename; - IAssetItem* pAssetItem = pCurrentDatabaseInterface->GetAsset(assetFilename.toUtf8().data()); - if (pAssetItem) - { - if ((pAssetItem->GetFlags() & IAssetItem::eFlag_Cached)) - { - QVariant v = pAssetItem->GetAssetFieldValue("dccfilename"); - assetDatabaseDccFilename = v.toString(); - if (!v.isNull()) - { - dccFilename = assetDatabaseDccFilename; - dccFilename = Path::GetRelativePath(dccFilename, false); - - uint32 attr = CFileUtil::GetAttributes(dccFilename.toUtf8().data()); - - if (CFileUtil::FileExists(dccFilename)) - { - return true; - } - else if (GetIEditor()->IsSourceControlAvailable() && (attr & SCC_FILE_ATTRIBUTE_MANAGED)) - { - return CFileUtil::GetLatestFromSourceControl(dccFilename.toUtf8().data()); - } - } - } - } - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CFileUtil::ExtractDccFilenameUsingNamingConventions(const QString& assetFilename, QString& dccFilename) -{ - //else to try find it by naming conventions - QString tempStr = assetFilename; - int foundSplit = -1; - if ((foundSplit = tempStr.lastIndexOf('.')) > 0) - { - QString first = tempStr.mid(0, foundSplit); - tempStr = first + ".psd"; - } - if (CFileUtil::FileExists(tempStr)) - { - dccFilename = tempStr; - return true; - } - - //else try to find it by replacing post fix _ with .psd - tempStr = assetFilename; - foundSplit = -1; - if ((foundSplit = tempStr.lastIndexOf('_')) > 0) - { - QString first = tempStr.mid(0, foundSplit); - tempStr = first + ".psd"; - } - if (CFileUtil::FileExists(tempStr)) - { - dccFilename = tempStr; - return true; - } - - return false; -} - ////////////////////////////////////////////////////////////////////////// void CFileUtil::FormatFilterString(QString& filter) { diff --git a/Code/Editor/Util/FileUtil.h b/Code/Editor/Util/FileUtil.h index fc0fc942fe..a4ff5009a2 100644 --- a/Code/Editor/Util/FileUtil.h +++ b/Code/Editor/Util/FileUtil.h @@ -29,9 +29,6 @@ public: static void EditTextFile(const char* txtFile, int line = 0, IFileUtil::ETextFileType fileType = IFileUtil::FILE_TYPE_SCRIPT); static void EditTextureFile(const char* txtureFile, bool bUseGameFolder); - //! dcc filename calculation and extraction sub-routines - static bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename); - //! Reformat filter string for (MFC) CFileDialog style file filtering static void FormatFilterString(QString& filter); @@ -155,9 +152,6 @@ private: // Keep this variant of this method private! pIsSelected is captured in a lambda, and so requires menu use exec() and never use show() static void PopulateQMenu(QWidget* caller, QMenu* menu, AZStd::string_view fullGamePath, bool* pIsSelected); - - static bool ExtractDccFilenameFromAssetDatabase(const QString& assetFilename, QString& dccFilename); - static bool ExtractDccFilenameUsingNamingConventions(const QString& assetFilename, QString& dccFilename); }; class CAutoRestorePrimaryCDRoot diff --git a/Code/Editor/Util/FileUtil_impl.cpp b/Code/Editor/Util/FileUtil_impl.cpp index 28090d28d5..31e3532f33 100644 --- a/Code/Editor/Util/FileUtil_impl.cpp +++ b/Code/Editor/Util/FileUtil_impl.cpp @@ -30,11 +30,6 @@ void CFileUtil_impl::EditTextureFile(const char* txtureFile, bool bUseGameFolder CFileUtil::EditTextureFile(txtureFile, bUseGameFolder); } -bool CFileUtil_impl::CalculateDccFilename(const QString& assetFilename, QString& dccFilename) -{ - return CFileUtil::CalculateDccFilename(assetFilename, dccFilename); -} - void CFileUtil_impl::FormatFilterString(QString& filter) { CFileUtil::FormatFilterString(filter); diff --git a/Code/Editor/Util/FileUtil_impl.h b/Code/Editor/Util/FileUtil_impl.h index aa8d0bf3b5..3c8e138dab 100644 --- a/Code/Editor/Util/FileUtil_impl.h +++ b/Code/Editor/Util/FileUtil_impl.h @@ -39,9 +39,6 @@ public: bool ExtractFile(QString& file, bool bMsgBoxAskForExtraction = true, const char* pDestinationFilename = nullptr) override; void EditTextureFile(const char* txtureFile, bool bUseGameFolder) override; - //! dcc filename calculation and extraction sub-routines - bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename) override; - //! Reformat filter string for (MFC) CFileDialog style file filtering void FormatFilterString(QString& filter) override; diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index a018333925..c81a326aff 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -269,9 +269,6 @@ set(FILES LevelTreeModel.h Include/Command.h Include/HitContext.h - Include/IAnimationCompressionManager.h - Include/IAssetItem.h - Include/IAssetItemDatabase.h Include/ICommandManager.h Include/IConsoleConnectivity.h Include/IDataBaseItem.h @@ -457,18 +454,14 @@ set(FILES GameResourcesExporter.cpp GameExporter.h GameResourcesExporter.h - Geometry/TriMesh.cpp - Geometry/TriMesh.h AboutDialog.h AboutDialog.ui DocMultiArchive.h - EditMode/DeepSelection.h FBXExporterDialog.h FileTypeUtils.h GridUtils.h IObservable.h IPostRenderer.h - LightmapCompiler/SimpleTriangleRasterizer.h ToolBox.h TrackViewNewSequenceDialog.h UndoConfigSpec.h @@ -559,11 +552,9 @@ set(FILES AboutDialog.cpp ErrorReportTableModel.h ErrorReportTableModel.cpp - EditMode/DeepSelection.cpp FBXExporterDialog.cpp FBXExporterDialog.ui FileTypeUtils.cpp - LightmapCompiler/SimpleTriangleRasterizer.cpp ToolBox.cpp TrackViewNewSequenceDialog.cpp TrackViewNewSequenceDialog.ui From f71efa8b9bde2b48e04f8e88e57db45cceca4d27 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 5 Jan 2022 14:16:35 -0600 Subject: [PATCH 065/272] Updating KillAllLyProcesses tests to expect o3de.exe process Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- Tools/LyTestTools/tests/unit/test_editor_test_utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py index cd361d9e8a..849fa5c391 100644 --- a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py +++ b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py @@ -17,14 +17,15 @@ class TestEditorTestUtils(unittest.TestCase): @mock.patch('ly_test_tools.environment.process_utils.kill_processes_named') def test_KillAllLyProcesses_IncludeAP_CallsCorrectly(self, mock_kill_processes_named): - process_list = ['Editor', 'Profiler', 'RemoteConsole', 'AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder'] + process_list = ['Editor', 'Profiler', 'RemoteConsole', 'o3de', 'AssetProcessor', 'AssetProcessorBatch', + 'AssetBuilder'] editor_test_utils.kill_all_ly_processes(include_asset_processor=True) mock_kill_processes_named.assert_called_once_with(process_list, ignore_extensions=True) @mock.patch('ly_test_tools.environment.process_utils.kill_processes_named') def test_KillAllLyProcesses_NotIncludeAP_CallsCorrectly(self, mock_kill_processes_named): - process_list = ['Editor', 'Profiler', 'RemoteConsole'] + process_list = ['Editor', 'Profiler', 'RemoteConsole', 'o3de'] ap_process_list = ['AssetProcessor', 'AssetProcessorBatch', 'AssetBuilder'] editor_test_utils.kill_all_ly_processes(include_asset_processor=False) From 9c85cd19a77fde4da716ad7a97ccd4f92ed0f5dc Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 5 Jan 2022 14:17:01 -0600 Subject: [PATCH 066/272] Skipping Docking test due to unknown Jenkins failure Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/TestSuite_Main_Optimized.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py index 058c309652..7e07d125fd 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -66,6 +66,7 @@ class TestAutomationAutoTestMode(EditorTestSuite): class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest): from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module + @pytest.mark.skip("Passes locally, fails on Jenkins") class test_Docking_BasicDockedTools(EditorSharedTest): from .EditorScripts import Docking_BasicDockedTools as test_module From 55fb63da48bae2efeb76478480b09e0e1b8d70e3 Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Wed, 5 Jan 2022 12:54:41 -0800 Subject: [PATCH 067/272] Debug render aabb now include node, mesh and static aabb. (#6685) Signed-off-by: rhhong --- .../Code/Source/AtomActorDebugDraw.cpp | 46 +++++++++++++++++-- .../Code/Source/AtomActorDebugDraw.h | 8 +++- .../Source/RenderPlugin/RenderOptions.cpp | 2 + .../Rendering/RenderActorSettings.h | 9 +++- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp index 421e5828b1..21f9f69f7c 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp @@ -63,7 +63,10 @@ namespace AZ::Render // Render aabb if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB]) { - RenderAABB(instance, renderActorSettings.m_staticAABBColor); + RenderAABB(instance, + renderActorSettings.m_enabledNodeBasedAabb, renderActorSettings.m_nodeAABBColor, + renderActorSettings.m_enabledMeshBasedAabb, renderActorSettings.m_meshAABBColor, + renderActorSettings.m_enabledStaticBasedAabb, renderActorSettings.m_staticAABBColor); } // Render simple line skeleton @@ -201,11 +204,46 @@ namespace AZ::Render return AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus); } - void AtomActorDebugDraw::RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor) + void AtomActorDebugDraw::RenderAABB(EMotionFX::ActorInstance* instance, + bool enableNodeAabb, + const AZ::Color& nodeAabbColor, + bool enableMeshAabb, + const AZ::Color& meshAabbColor, + bool enableStaticAabb, + const AZ::Color& staticAabbColor) { RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue(); - const AZ::Aabb& aabb = instance->GetAabb(); - auxGeom->DrawAabb(aabb, aabbColor, RPI::AuxGeomDraw::DrawStyle::Line); + + if (enableNodeAabb) + { + AZ::Aabb aabb; + instance->CalcNodeBasedAabb(&aabb); + if (aabb.IsValid()) + { + auxGeom->DrawAabb(aabb, nodeAabbColor, RPI::AuxGeomDraw::DrawStyle::Line); + } + } + + if (enableMeshAabb) + { + AZ::Aabb aabb; + const size_t lodLevel = instance->GetLODLevel(); + instance->CalcMeshBasedAabb(lodLevel, &aabb); + if (aabb.IsValid()) + { + auxGeom->DrawAabb(aabb, meshAabbColor, RPI::AuxGeomDraw::DrawStyle::Line); + } + } + + if (enableStaticAabb) + { + AZ::Aabb aabb; + instance->CalcStaticBasedAabb(&aabb); + if (aabb.IsValid()) + { + auxGeom->DrawAabb(aabb, staticAabbColor, RPI::AuxGeomDraw::DrawStyle::Line); + } + } } void AtomActorDebugDraw::RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h index 3c0258cfef..8e985fdbc6 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h @@ -49,7 +49,13 @@ namespace AZ::Render void PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM); AzFramework::DebugDisplayRequests* GetDebugDisplay(AzFramework::ViewportId viewportId); - void RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor); + void RenderAABB(EMotionFX::ActorInstance* instance, + bool enableNodeAabb, + const AZ::Color& nodeAabbColor, + bool enableMeshAabb, + const AZ::Color& meshAabbColor, + bool enableStaticAabb, + const AZ::Color& staticAabbColor); void RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor); void RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor); void RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp index 241412c6c8..cc344db488 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp @@ -1071,6 +1071,8 @@ namespace EMStudio settings.m_mirroredBitangentsColor = m_mirroredBitangentsColor; settings.m_bitangentsColor = m_bitangentsColor; settings.m_wireframeColor = m_wireframeColor; + settings.m_nodeAABBColor = m_nodeAABBColor; + settings.m_meshAABBColor = m_meshAABBColor; settings.m_staticAABBColor = m_staticAABBColor; settings.m_skeletonColor = m_skeletonColor; settings.m_lineSkeletonColor = m_lineSkeletonColor; diff --git a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h index 0260d1aae5..8663b768c8 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h +++ b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h @@ -28,6 +28,10 @@ namespace AZ::Render float m_wireframeScale = 1.0f; float m_nodeOrientationScale = 1.0f; + bool m_enabledNodeBasedAabb = true; + bool m_enabledMeshBasedAabb = true; + bool m_enabledStaticBasedAabb = true; + AZ::Color m_hitDetectionColliderColor{0.44f, 0.44f, 0.44f, 1.0f}; AZ::Color m_selectedHitDetectionColliderColor{ 0.3f, 0.56f, 0.88f, 1.0f }; AZ::Color m_ragdollColliderColor{ 0.44f, 0.44f, 0.44f, 1.0f }; @@ -44,9 +48,12 @@ namespace AZ::Render AZ::Color m_mirroredBitangentsColor{ 1.0f, 1.0f, 0.0f, 1.0f }; AZ::Color m_bitangentsColor{ 1.0f, 1.0f, 1.0f, 1.0f }; AZ::Color m_wireframeColor{ 0.0f, 0.0f, 0.0f, 1.0f }; - AZ::Color m_staticAABBColor{ 0.0f, 0.7f, 0.7f, 1.0f }; AZ::Color m_lineSkeletonColor{ 0.33333f, 1.0f, 0.0f, 1.0f }; AZ::Color m_skeletonColor{ 0.19f, 0.58f, 0.19f, 1.0f }; AZ::Color m_jointNameColor{ 1.0f, 1.0f, 1.0f, 1.0f }; + + AZ::Color m_nodeAABBColor{ 1.0f, 0.0f, 0.0f, 1.0f }; + AZ::Color m_meshAABBColor{ 0.0f, 0.0f, 0.7f, 1.0f }; + AZ::Color m_staticAABBColor{ 0.0f, 0.7f, 0.7f, 1.0f }; }; } // namespace AZ::Render From d347a9d2c034dea3878ce357060b7e040bee6885 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 5 Jan 2022 12:56:22 -0800 Subject: [PATCH 068/272] Fix Linux build (a static_assert unfortunately fires for Clang) Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index af6d86d699..824b38e47b 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -352,7 +352,7 @@ namespace AZ::Dom } else { - static_assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); } }, m_value); From 6c3d5c434ebf166f3632f8a4e8257d0f8d09f440 Mon Sep 17 00:00:00 2001 From: Allen Jackson <23512001+jackalbe@users.noreply.github.com> Date: Wed, 5 Jan 2022 16:08:58 -0600 Subject: [PATCH 069/272] {lyn8865} Adding DataTypes::ScriptProcessorFallbackLogic (#6396) * {lyn8865} Adding DataTypes::ScriptProcessorFallbackLogic - Give the user an option how to handle fallback logic for script rules Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com> * the new code found an error in a Python script... it seems to work! Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com> * fixing up the regression test Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com> * dump version number Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com> --- .../python_builder.py | 2 +- .../TestAssets/test_chunks_builder.py | 2 +- .../DataTypes/Rules/IScriptProcessorRule.h | 8 ++ .../Behaviors/ScriptProcessorRuleBehavior.cpp | 26 ++++++- .../Behaviors/ScriptProcessorRuleBehavior.h | 2 +- .../SceneData/Rules/ScriptProcessorRule.cpp | 17 ++++- .../SceneData/Rules/ScriptProcessorRule.h | 3 + .../SceneManifest/SceneManifestRuleTests.cpp | 75 +++++++++++++++++++ 8 files changed, 126 insertions(+), 9 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene/python_builder.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene/python_builder.py index 7ad5894a86..a9759e3d33 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene/python_builder.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene/python_builder.py @@ -23,7 +23,7 @@ def output_test_data(scene): # Just write something to the file, but the filename is the main information # used for the test. f.write(f"scene.sourceFilename: {scene.sourceFilename}\n") - return True + return '' mySceneJobHandler = None diff --git a/AutomatedTesting/TestAssets/test_chunks_builder.py b/AutomatedTesting/TestAssets/test_chunks_builder.py index 2fd1ad9db9..b18902a34c 100755 --- a/AutomatedTesting/TestAssets/test_chunks_builder.py +++ b/AutomatedTesting/TestAssets/test_chunks_builder.py @@ -28,7 +28,7 @@ def update_manifest(scene): meshGroup = sceneManifest.add_mesh_group(chunkName) meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, scene.sourceFilename + chunkName)) + '}' sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by test_chunks_builder') - sceneManifest.mesh_group_set_origin(meshGroup, None, 0, 0, 0, 1.0) + sceneManifest.mesh_group_add_advanced_coordinate_system(meshGroup) for meshIndex in range(len(chunkNameList)): if (activeMeshIndex == meshIndex): sceneManifest.mesh_group_select_node(meshGroup, chunkNameList[meshIndex]) diff --git a/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h b/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h index 36be5f61d3..2b2abae561 100644 --- a/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h +++ b/Code/Tools/SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h @@ -17,6 +17,12 @@ namespace AZ { namespace DataTypes { + enum class ScriptProcessorFallbackLogic + { + FailBuild, // this will log error & fail the build + ContinueBuild // this will log the errors but continue the build logic + }; + class IScriptProcessorRule : public IRule { @@ -26,6 +32,8 @@ namespace AZ virtual ~IScriptProcessorRule() override = default; virtual const AZStd::string& GetScriptFilename() const = 0; + + virtual ScriptProcessorFallbackLogic GetScriptProcessorFallbackLogic() const = 0; }; } // DataTypes } // SceneAPI diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp index 8d413b6038..6046bfa620 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp @@ -173,10 +173,13 @@ namespace AZ::SceneAPI::Behaviors UnloadPython(); } - bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath) + bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath, Events::ProcessingResult& fallbackResult) { + using namespace AZ::SceneAPI; + + fallbackResult = Events::ProcessingResult::Failure; int scriptDiscoveryAttempts = 0; - const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest(); + const Containers::SceneManifest& manifest = scene.GetManifest(); auto view = Containers::MakeDerivedFilterView(manifest.GetValueStorage()); for (const auto& scriptItem : view) { @@ -188,6 +191,8 @@ namespace AZ::SceneAPI::Behaviors } ++scriptDiscoveryAttempts; + fallbackResult = (scriptItem.GetScriptProcessorFallbackLogic() == DataTypes::ScriptProcessorFallbackLogic::ContinueBuild) ? + Events::ProcessingResult::Ignored : Events::ProcessingResult::Failure; // check for file exist via absolute path if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str())) @@ -301,7 +306,8 @@ namespace AZ::SceneAPI::Behaviors } }; - if (LoadPython(context.GetScene(), scriptPath)) + [[maybe_unused]] Events::ProcessingResult fallbackResult; + if (LoadPython(context.GetScene(), scriptPath, fallbackResult)) { EditorPythonConsoleNotificationHandler logger; m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); @@ -333,8 +339,9 @@ namespace AZ::SceneAPI::Behaviors return Events::ProcessingResult::Ignored; } + Events::ProcessingResult fallbackResult; AZStd::string scriptPath; - if (LoadPython(scene, scriptPath)) + if (LoadPython(scene, scriptPath, fallbackResult)) { AZStd::string manifestUpdate; auto executeCallback = [&scene, &manifestUpdate, &scriptPath]() @@ -349,6 +356,12 @@ namespace AZ::SceneAPI::Behaviors EditorPythonConsoleNotificationHandler logger; m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); + // if the returned scene manifest is empty then ignore the script update + if (manifestUpdate.empty()) + { + return Events::ProcessingResult::Ignored; + } + EntityUtilityBus::Broadcast(&EntityUtilityBus::Events::ResetEntityContext); AZ::Interface::Get()->RemoveAllTemplates(); @@ -364,6 +377,11 @@ namespace AZ::SceneAPI::Behaviors } return Events::ProcessingResult::Success; } + else + { + // if the manifest was not updated by the script, then return back the fallback result + return fallbackResult; + } } return Events::ProcessingResult::Ignored; } diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h index a9ddf88df9..8903a8f257 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h @@ -54,7 +54,7 @@ namespace AZ::SceneAPI::Behaviors SCENE_DATA_API void GetManifestDependencyPaths(AZStd::vector& paths) override; protected: - bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath); + bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath, Events::ProcessingResult& fallbackResult); void UnloadPython(); bool DoPrepareForExport(Events::PreExportEventContext& context); diff --git a/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.cpp b/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.cpp index 5893764eb1..15c8c1b7f3 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.cpp +++ b/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.cpp @@ -14,6 +14,9 @@ namespace AZ { + // Enum types must have a TypeId tied to it in order for the reflection to succeed. + AZ_TYPE_INFO_SPECIALIZE(SceneAPI::DataTypes::ScriptProcessorFallbackLogic, "{3DCABF3D-E8EF-43E7-B3C7-373E05825F60}"); + namespace SceneAPI { namespace SceneData @@ -23,13 +26,23 @@ namespace AZ return m_scriptFilename; } + DataTypes::ScriptProcessorFallbackLogic ScriptProcessorRule::GetScriptProcessorFallbackLogic() const + { + return m_fallbackLogic; + } + void ScriptProcessorRule::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(1) - ->Field("scriptFilename", &ScriptProcessorRule::m_scriptFilename); + serializeContext->Class()->Version(2) + ->Field("scriptFilename", &ScriptProcessorRule::m_scriptFilename) + ->Field("fallbackLogic", &ScriptProcessorRule::m_fallbackLogic); + + serializeContext->Enum() + ->Value("FailBuild", DataTypes::ScriptProcessorFallbackLogic::FailBuild) + ->Value("ContinueBuild", DataTypes::ScriptProcessorFallbackLogic::ContinueBuild); AZ::EditContext* editContext = serializeContext->GetEditContext(); if (editContext) diff --git a/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.h b/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.h index ad5e1de063..80cb670f9f 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.h +++ b/Code/Tools/SceneAPI/SceneData/Rules/ScriptProcessorRule.h @@ -35,10 +35,13 @@ namespace AZ m_scriptFilename = AZStd::move(scriptFilename); } + DataTypes::ScriptProcessorFallbackLogic GetScriptProcessorFallbackLogic() const override; + static void Reflect(ReflectContext* context); protected: AZStd::string m_scriptFilename; + DataTypes::ScriptProcessorFallbackLogic m_fallbackLogic = DataTypes::ScriptProcessorFallbackLogic::FailBuild; }; } // SceneData } // SceneAPI diff --git a/Code/Tools/SceneAPI/SceneData/Tests/SceneManifest/SceneManifestRuleTests.cpp b/Code/Tools/SceneAPI/SceneData/Tests/SceneManifest/SceneManifestRuleTests.cpp index e0d5cca484..2bbbc1054a 100644 --- a/Code/Tools/SceneAPI/SceneData/Tests/SceneManifest/SceneManifestRuleTests.cpp +++ b/Code/Tools/SceneAPI/SceneData/Tests/SceneManifest/SceneManifestRuleTests.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -271,5 +272,79 @@ namespace AZ auto update = scriptProcessorRuleBehavior.UpdateManifest(scene, AssetImportRequest::Update, AssetImportRequest::Generic); EXPECT_EQ(update, ProcessingResult::Ignored); } + + TEST_F(SceneManifest_JSON, ScriptProcessorRule_DefaultFallbackLogic_Works) + { + using namespace AZ::SceneAPI; + + constexpr const char* defaultJson = { R"JSON( + { + "values": [ + { + "$type": "ScriptProcessorRule", + "scriptFilename": "foo.py" + } + ] + })JSON" }; + + auto scene = Containers::Scene("mock"); + auto result = scene.GetManifest().LoadFromString(defaultJson, m_serializeContext.get(), m_jsonRegistrationContext.get()); + EXPECT_TRUE(result.IsSuccess()); + EXPECT_FALSE(scene.GetManifest().IsEmpty()); + ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1); + + auto view = Containers::MakeDerivedFilterView(scene.GetManifest().GetValueStorage()); + EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::FailBuild); + } + + TEST_F(SceneManifest_JSON, ScriptProcessorRule_ExplicitFallbackLogic_Works) + { + using namespace AZ::SceneAPI; + + constexpr const char* fallbackLogicJson = { R"JSON( + { + "values": [ + { + "$type": "ScriptProcessorRule", + "scriptFilename": "foo.py", + "fallbackLogic": "FailBuild" + } + ] + })JSON" }; + + auto scene = Containers::Scene("mock"); + auto result = scene.GetManifest().LoadFromString(fallbackLogicJson, m_serializeContext.get(), m_jsonRegistrationContext.get()); + EXPECT_TRUE(result.IsSuccess()); + EXPECT_FALSE(scene.GetManifest().IsEmpty()); + ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1); + + auto view = Containers::MakeDerivedFilterView(scene.GetManifest().GetValueStorage()); + EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::FailBuild); + } + + TEST_F(SceneManifest_JSON, ScriptProcessorRule_ContinueBuildFallbackLogic_Works) + { + using namespace AZ::SceneAPI; + + constexpr const char* fallbackLogicJson = { R"JSON( + { + "values": [ + { + "$type": "ScriptProcessorRule", + "scriptFilename": "foo.py", + "fallbackLogic": "ContinueBuild" + } + ] + })JSON" }; + + auto scene = Containers::Scene("mock"); + auto result = scene.GetManifest().LoadFromString(fallbackLogicJson, m_serializeContext.get(), m_jsonRegistrationContext.get()); + EXPECT_TRUE(result.IsSuccess()); + EXPECT_FALSE(scene.GetManifest().IsEmpty()); + ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1); + + auto view = Containers::MakeDerivedFilterView(scene.GetManifest().GetValueStorage()); + EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::ContinueBuild); + } } } From 6ae8c6343194e58712eb620958ee9021555bdcab Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 5 Jan 2022 16:27:21 -0600 Subject: [PATCH 070/272] Re-enabling Periodic suite for testing on Jenkins Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index 1fc71da972..a43b3647f9 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -50,4 +50,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ Editor ) + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Periodic + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + endif() From 7d9f9f99e657af79cbe6000ccadfa79272c4410f Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 14:50:03 -0800 Subject: [PATCH 071/272] fix unit test Signed-off-by: mrieggeramzn --- .../Tests/PropertyIntCtrlCommonTests.h | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h index 712eeb99b7..d4f0c8d705 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h @@ -12,6 +12,7 @@ #include #include "IntegerPrimtitiveTestConfig.h" #include +#include #include namespace UnitTest @@ -83,18 +84,6 @@ namespace UnitTest widget->setMaximum(widget->maximum() - 1); } - static std::string GetToolTipStringAtLimits() - { - if constexpr (std::is_signed::value) - { - return "[-INF, INF]"; - } - else - { - return "[0, INF]"; - } - } - void PropertyCtrlHandlersCreated() { using ::testing::Ne; @@ -125,15 +114,19 @@ namespace UnitTest auto& widget = m_widget; auto& handler = m_handler; QString tooltip; - std::string expected; + std::stringstream expected; // Retrieve the tooltip string for this widget auto success = handler->ModifyTooltip(widget, tooltip); - expected = GetToolTipStringAtLimits(); + + const QString minString = QLocale().toString(widget->minimum()); + const QString maxString = QLocale().toString(widget->maximum()); + + expected << "[" << minString.toStdString() << ", " << maxString.toStdString() << "]"; // Expect the operation to be successful and a valid limit tooltip string generated EXPECT_TRUE(success); - EXPECT_STREQ(tooltip.toStdString().c_str(), expected.c_str()); + EXPECT_STREQ(tooltip.toStdString().c_str(), expected.str().c_str()); } void HandlerMinMaxLessLimit_ModifyHandler_ExpectSuccessAndValidLessLimitToolTipString() @@ -149,7 +142,11 @@ namespace UnitTest // Retrieve the tooltip string for this widget auto success = handler->ModifyTooltip(widget, tooltip); - expected << "[" << widget->minimum() << ", " << widget->maximum() << "]"; + + const QString minString = QLocale().toString(widget->minimum()); + const QString maxString = QLocale().toString(widget->maximum()); + + expected << "[" << minString.toStdString() << ", " << maxString.toStdString() << "]"; // Expect the operation to be successful and a valid less than limit tooltip string generated EXPECT_TRUE(success); From 01c5fb78178eeefd74172ba0556461dcc5c6b0b2 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Wed, 5 Jan 2022 15:27:52 -0800 Subject: [PATCH 072/272] Add clamp mode to Draw2d (#6630) Signed-off-by: abrmich --- Gems/LyShine/Code/Include/LyShine/Draw2d.h | 11 ++++++++++- Gems/LyShine/Code/Source/Draw2d.cpp | 22 +++++++++++++++++----- Gems/LyShine/Code/Source/LyShine.cpp | 10 ++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Include/LyShine/Draw2d.h index 881479bd23..f92c6ce2e1 100644 --- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/Draw2d.h @@ -50,6 +50,7 @@ public: // types { AZ::Vector3 color = AZ::Vector3(1.0f, 1.0f, 1.0f); Rounding pixelRounding = Rounding::Nearest; + bool m_clamp = false; RenderState m_renderState; }; @@ -145,6 +146,7 @@ public: // member functions virtual void DrawQuad(AZ::Data::Instance image, VertexPosColUV* verts, Rounding pixelRounding = Rounding::Nearest, + bool clamp = false, const RenderState& renderState = RenderState{}); //! Draw a line @@ -257,6 +259,8 @@ protected: // types and constants { AZ::RHI::ShaderInputImageIndex m_imageInputIndex; AZ::RHI::ShaderInputConstantIndex m_viewProjInputIndex; + AZ::RPI::ShaderVariantId m_shaderOptionsClamp; + AZ::RPI::ShaderVariantId m_shaderOptionsWrap; }; class DeferredPrimitive @@ -281,6 +285,7 @@ protected: // types and constants AZ::Vector2 m_texCoords[4]; uint32 m_packedColors[4]; AZ::Data::Instance m_image; + bool m_clamp; RenderState m_renderState; }; @@ -455,11 +460,12 @@ public: // member functions //! See IDraw2d:DrawQuad for parameter descriptions void DrawQuad(AZ::Data::Instance image, CDraw2d::VertexPosColUV* verts, IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + bool clamp = false, const CDraw2d::RenderState& renderState = CDraw2d::RenderState{}) { if (m_draw2d) { - m_draw2d->DrawQuad(image, verts, pixelRounding, renderState); + m_draw2d->DrawQuad(image, verts, pixelRounding, clamp, renderState); } } @@ -545,6 +551,9 @@ public: // member functions //! Set the base state (that blend mode etc is combined with) used for images, default is GS_NODEPTHTEST. void SetImageDepthState(const AZ::RHI::DepthState& depthState) { m_imageOptions.m_renderState.m_depthState = depthState; } + //! Set image clamp mode + void SetImageClamp(bool clamp) { m_imageOptions.m_clamp = clamp; } + //! Set the text font. void SetTextFont(AZStd::string_view fontName) { m_textOptions.fontName = fontName; } diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index 6b6356aa4f..917c1bb168 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -103,10 +103,7 @@ void CDraw2d::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) LyShinePassRequestBus::EventResult(uiCanvasPass, sceneId, &LyShinePassRequestBus::Events::GetUiCanvasPass); m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(); - AZ::RPI::ShaderOptionList shaderOptions; - shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); - shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false"))); - m_dynamicDraw->InitShaderWithVariant(shader, &shaderOptions); + m_dynamicDraw->InitShader(shader); m_dynamicDraw->InitVertexFormat( { {"POSITION", AZ::RHI::Format::R32G32B32_FLOAT}, {"COLOR", AZ::RHI::Format::B8G8R8A8_UNORM}, @@ -136,6 +133,16 @@ void CDraw2d::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) m_shaderData.m_viewProjInputIndex = layout->FindShaderInputConstantIndex(AZ::Name(worldToProjIndexName)); AZ_Error("Draw2d", m_shaderData.m_viewProjInputIndex.IsValid(), "Failed to find shader input constant %s.", worldToProjIndexName); + + // Cache shader variants that will be used + AZ::RPI::ShaderOptionList shaderOptionsClamp; + shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true"))); + shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); + m_shaderData.m_shaderOptionsClamp = m_dynamicDraw->UseShaderVariant(shaderOptionsClamp); + AZ::RPI::ShaderOptionList shaderOptionsWrap; + shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false"))); + shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); + m_shaderData.m_shaderOptionsWrap = m_dynamicDraw->UseShaderVariant(shaderOptionsWrap); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -181,6 +188,8 @@ void CDraw2d::DrawImage(AZ::Data::Instance image, AZ::Vector2 po quad.m_image = image; + quad.m_clamp = actualImageOptions->m_clamp; + // add the blendMode flags to the base state quad.m_renderState = actualImageOptions->m_renderState; @@ -206,7 +215,7 @@ void CDraw2d::DrawImageAligned(AZ::Data::Instance image, AZ::Vec //////////////////////////////////////////////////////////////////////////////////////////////////// void CDraw2d::DrawQuad(AZ::Data::Instance image, VertexPosColUV* verts, Rounding pixelRounding, - const CDraw2d::RenderState& renderState) + bool clamp, const CDraw2d::RenderState& renderState) { // define quad DeferredQuad quad; @@ -217,6 +226,7 @@ void CDraw2d::DrawQuad(AZ::Data::Instance image, VertexPosColUV* quad.m_packedColors[i] = PackARGB8888(verts[i].color); } quad.m_image = image; + quad.m_clamp = clamp; // add the blendMode flags to the base state quad.m_renderState = renderState; @@ -766,6 +776,8 @@ void CDraw2d::DeferredQuad::Draw(AZ::RHI::Ptr dynam vertices[i].st = Vec2(m_texCoords[j].GetX(), m_texCoords[j].GetY()); } + dynamicDraw->SetShaderVariant(m_clamp ? shaderData.m_shaderOptionsClamp : shaderData.m_shaderOptionsWrap); + // Set up per draw SRG AZ::Data::Instance drawSrg = dynamicDraw->NewDrawSrg(); diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index d19bc3f92d..683d72f4ab 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -668,7 +668,7 @@ void CLyShine::LoadUiCursor() { if (!m_cursorImagePathToLoad.empty()) { - m_uiCursorTexture = CDraw2d::LoadTexture(m_cursorImagePathToLoad); // LYSHINE_ATOM_TODO - add clamp option to draw2d and set cursor to clamp + m_uiCursorTexture = CDraw2d::LoadTexture(m_cursorImagePathToLoad); m_cursorImagePathToLoad.clear(); } } @@ -691,7 +691,13 @@ void CLyShine::RenderUiCursor() AZ::RHI::Size cursorSize = m_uiCursorTexture->GetDescriptor().m_size; const AZ::Vector2 dimensions(aznumeric_cast(cursorSize.m_width), aznumeric_cast(cursorSize.m_height)); - m_draw2d->DrawImage(m_uiCursorTexture, position, dimensions); + CDraw2d::ImageOptions imageOptions; + imageOptions.m_clamp = true; + const float opacity = 1.0f; + const float rotation = 0.0f; + const AZ::Vector2* pivotPoint = nullptr; + const AZ::Vector2* minMaxTexCoords = nullptr; + m_draw2d->DrawImage(m_uiCursorTexture, position, dimensions, opacity, rotation, pivotPoint, minMaxTexCoords, &imageOptions); } #ifndef _RELEASE From ee6709a85c0b32ab8737cb13af0b0fc696c594d7 Mon Sep 17 00:00:00 2001 From: Sean Masterson Date: Wed, 5 Jan 2022 15:47:11 -0800 Subject: [PATCH 073/272] Move and convert ShadowTest level and include object files Signed-off-by: Sean Masterson --- .../Graphics/ShadowTest/ShadowTest.prefab | 566 ++++++++++++++++++ .../Levels/Graphics/ShadowTest/tags.txt | 12 + .../Objects/ShaderBall_simple.fbx | 3 + AutomatedTesting/Objects/bunny.fbx | 3 + AutomatedTesting/Objects/cone.fbx | 3 + AutomatedTesting/Objects/cube.fbx | 3 + AutomatedTesting/Objects/cylinder.fbx | 3 + AutomatedTesting/Objects/plane.fbx | 3 + AutomatedTesting/Objects/suzanne.fbx | 3 + 9 files changed, 599 insertions(+) create mode 100644 AutomatedTesting/Levels/Graphics/ShadowTest/ShadowTest.prefab create mode 100644 AutomatedTesting/Levels/Graphics/ShadowTest/tags.txt create mode 100644 AutomatedTesting/Objects/ShaderBall_simple.fbx create mode 100644 AutomatedTesting/Objects/bunny.fbx create mode 100644 AutomatedTesting/Objects/cone.fbx create mode 100644 AutomatedTesting/Objects/cube.fbx create mode 100644 AutomatedTesting/Objects/cylinder.fbx create mode 100644 AutomatedTesting/Objects/plane.fbx create mode 100644 AutomatedTesting/Objects/suzanne.fbx diff --git a/AutomatedTesting/Levels/Graphics/ShadowTest/ShadowTest.prefab b/AutomatedTesting/Levels/Graphics/ShadowTest/ShadowTest.prefab new file mode 100644 index 0000000000..86d16328e9 --- /dev/null +++ b/AutomatedTesting/Levels/Graphics/ShadowTest/ShadowTest.prefab @@ -0,0 +1,566 @@ +{ + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "ShadowTest", + "Components": { + "Component_[10182366347512475253]": { + "$type": "EditorPrefabComponent", + "Id": 10182366347512475253 + }, + "Component_[12917798267488243668]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12917798267488243668 + }, + "Component_[3261249813163778338]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3261249813163778338 + }, + "Component_[3837204912784440039]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 3837204912784440039 + }, + "Component_[4272963378099646759]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 4272963378099646759, + "Parent Entity": "" + }, + "Component_[4848458548047175816]": { + "$type": "EditorVisibilityComponent", + "Id": 4848458548047175816 + }, + "Component_[5787060997243919943]": { + "$type": "EditorInspectorComponent", + "Id": 5787060997243919943 + }, + "Component_[7804170251266531779]": { + "$type": "EditorLockComponent", + "Id": 7804170251266531779 + }, + "Component_[7874177159288365422]": { + "$type": "EditorEntitySortComponent", + "Id": 7874177159288365422 + }, + "Component_[8018146290632383969]": { + "$type": "EditorEntityIconComponent", + "Id": 8018146290632383969 + }, + "Component_[8452360690590857075]": { + "$type": "SelectionComponent", + "Id": 8452360690590857075 + } + } + }, + "Entities": { + "Entity_[232650527119]": { + "Id": "Entity_[232650527119]", + "Name": "DirectionalLight", + "Components": { + "Component_[10660156197505313227]": { + "$type": "EditorLockComponent", + "Id": 10660156197505313227 + }, + "Component_[14184823757717157844]": { + "$type": "EditorInspectorComponent", + "Id": 14184823757717157844, + "ComponentOrderEntryArray": [ + { + "ComponentId": 9854879901259791898 + }, + { + "ComponentId": 3968519938187714949, + "SortIndex": 1 + } + ] + }, + "Component_[1495573908681275492]": { + "$type": "EditorEntitySortComponent", + "Id": 1495573908681275492 + }, + "Component_[15580233403487968826]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 15580233403487968826 + }, + "Component_[3968519938187714949]": { + "$type": "AZ::Render::EditorDirectionalLightComponent", + "Id": 3968519938187714949, + "Controller": { + "Configuration": { + "Intensity": 0.0, + "CameraEntityId": "", + "ShadowmapSize": "Size2048" + } + } + }, + "Component_[4961040003466069196]": { + "$type": "EditorEntityIconComponent", + "Id": 4961040003466069196 + }, + "Component_[7824884165323036147]": { + "$type": "EditorVisibilityComponent", + "Id": 7824884165323036147 + }, + "Component_[8741866916946672319]": { + "$type": "EditorPendingCompositionComponent", + "Id": 8741866916946672319 + }, + "Component_[9288966876314965560]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9288966876314965560 + }, + "Component_[9313163355156975968]": { + "$type": "SelectionComponent", + "Id": 9313163355156975968 + }, + "Component_[9854879901259791898]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 9854879901259791898, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 2.0 + ], + "Rotate": [ + -32.05662536621094, + -26.103206634521484, + 47.54806137084961 + ] + } + } + } + }, + "Entity_[260824893221]": { + "Id": "Entity_[260824893221]", + "Name": "SpotLight", + "Components": { + "Component_[16098295228434057928]": { + "$type": "EditorDiskShapeComponent", + "Id": 16098295228434057928, + "ShapeColor": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "DiskShape": { + "Configuration": { + "Radius": 0.0 + } + } + }, + "Component_[16175995808158769171]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16175995808158769171, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Translate": [ + 0.6417449712753296, + 1.3211734294891357, + 3.022759199142456 + ], + "Rotate": [ + 243.31329345703125, + 0.0, + 0.0 + ] + } + }, + "Component_[17136787899581093377]": { + "$type": "EditorEntitySortComponent", + "Id": 17136787899581093377 + }, + "Component_[17938027566627202610]": { + "$type": "EditorPendingCompositionComponent", + "Id": 17938027566627202610 + }, + "Component_[190081405128299223]": { + "$type": "SelectionComponent", + "Id": 190081405128299223 + }, + "Component_[2181418147135573579]": { + "$type": "EditorEntityIconComponent", + "Id": 2181418147135573579 + }, + "Component_[2564149706319215342]": { + "$type": "EditorOnlyEntityComponent", + "Id": 2564149706319215342 + }, + "Component_[3716169383940064541]": { + "$type": "EditorInspectorComponent", + "Id": 3716169383940064541, + "ComponentOrderEntryArray": [ + { + "ComponentId": 16175995808158769171 + }, + { + "ComponentId": 16665800442781289114, + "SortIndex": 1 + } + ] + }, + "Component_[4143676462074671972]": { + "$type": "AZ::Render::EditorAreaLightComponent", + "Id": 4143676462074671972, + "Controller": { + "Configuration": { + "LightType": 2, + "AttenuationRadius": 31.62277603149414, + "EnableShutters": true, + "InnerShutterAngleDegrees": 22.5, + "OuterShutterAngleDegrees": 27.5, + "Enable Shadow": true, + "Shadowmap Max Size": "Size2048", + "Filtering Sample Count": 32 + } + } + }, + "Component_[6706371214647538019]": { + "$type": "EditorVisibilityComponent", + "Id": 6706371214647538019 + }, + "Component_[7493944209625718550]": { + "$type": "EditorLockComponent", + "Id": 7493944209625718550 + }, + "Component_[7614113482082939165]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7614113482082939165 + } + } + }, + "Entity_[269117486973]": { + "Id": "Entity_[269117486973]", + "Name": "Floor", + "Components": { + "Component_[10562678944594915756]": { + "$type": "EditorEntitySortComponent", + "Id": 10562678944594915756 + }, + "Component_[1175452962278157526]": { + "$type": "EditorEntityIconComponent", + "Id": 1175452962278157526 + }, + "Component_[13598353801231166887]": { + "$type": "EditorPendingCompositionComponent", + "Id": 13598353801231166887 + }, + "Component_[13735087293504923475]": { + "$type": "SelectionComponent", + "Id": 13735087293504923475 + }, + "Component_[13888244442459268363]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 13888244442459268363, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{E65E9ED3-3E38-5ABA-9E22-95E34DA4C3AE}", + "subId": 280178048 + }, + "assetHint": "objects/plane.azmodel" + }, + "LodOverride": 255 + } + } + }, + "Component_[1525720357937234014]": { + "$type": "EditorMaterialComponent", + "Id": 1525720357937234014, + "materialSlotsByLodEnabled": true + }, + "Component_[16568998871680422442]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 16568998871680422442 + }, + "Component_[2147751093058990131]": { + "$type": "EditorInspectorComponent", + "Id": 2147751093058990131, + "ComponentOrderEntryArray": [ + { + "ComponentId": 3266761149114817871 + }, + { + "ComponentId": 13888244442459268363, + "SortIndex": 1 + }, + { + "ComponentId": 1525720357937234014, + "SortIndex": 2 + } + ] + }, + "Component_[3266761149114817871]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 3266761149114817871, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Scale": [ + 100.0, + 100.0, + 100.0 + ], + "UniformScale": 100.0 + } + }, + "Component_[4625895382416898670]": { + "$type": "EditorVisibilityComponent", + "Id": 4625895382416898670 + }, + "Component_[4856699190357614535]": { + "$type": "EditorLockComponent", + "Id": 4856699190357614535 + }, + "Component_[6466465153982575739]": { + "$type": "EditorOnlyEntityComponent", + "Id": 6466465153982575739 + } + } + }, + "Entity_[282757803856]": { + "Id": "Entity_[282757803856]", + "Name": "Cube", + "Components": { + "Component_[11189870094752260272]": { + "$type": "EditorEntitySortComponent", + "Id": 11189870094752260272 + }, + "Component_[11909086967677513257]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 11909086967677513257, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{593006BE-FE73-5A4B-A0A6-06C02EFFE458}", + "subId": 285127096 + }, + "loadBehavior": "PreLoad", + "assetHint": "objects/cube.azmodel" + }, + "LodOverride": 255 + } + } + }, + "Component_[1443341568598731610]": { + "$type": "EditorVisibilityComponent", + "Id": 1443341568598731610 + }, + "Component_[18339772707807258951]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18339772707807258951, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Translate": [ + 0.6083869934082031, + 3.137901782989502, + 0.5876787900924683 + ] + } + }, + "Component_[2447207272572065708]": { + "$type": "EditorEntityIconComponent", + "Id": 2447207272572065708 + }, + "Component_[3281906807632213471]": { + "$type": "SelectionComponent", + "Id": 3281906807632213471 + }, + "Component_[3412442673858204671]": { + "$type": "EditorPendingCompositionComponent", + "Id": 3412442673858204671 + }, + "Component_[5382641380294287889]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5382641380294287889 + }, + "Component_[7221534636342494619]": { + "$type": "EditorInspectorComponent", + "Id": 7221534636342494619, + "ComponentOrderEntryArray": [ + { + "ComponentId": 18339772707807258951 + }, + { + "ComponentId": 11909086967677513257, + "SortIndex": 1 + } + ] + }, + "Component_[7701217952253676487]": { + "$type": "EditorLockComponent", + "Id": 7701217952253676487 + }, + "Component_[7758436981023123121]": { + "$type": "EditorOnlyEntityComponent", + "Id": 7758436981023123121 + } + } + }, + "Entity_[372196702077]": { + "Id": "Entity_[372196702077]", + "Name": "Bunny", + "Components": { + "Component_[11345914745205508221]": { + "$type": "EditorEntityIconComponent", + "Id": 11345914745205508221 + }, + "Component_[11507863983962969790]": { + "$type": "EditorMaterialComponent", + "Id": 11507863983962969790, + "materialSlotsByLodEnabled": true + }, + "Component_[1342998773562921470]": { + "$type": "EditorPendingCompositionComponent", + "Id": 1342998773562921470 + }, + "Component_[14975835087235718844]": { + "$type": "EditorInspectorComponent", + "Id": 14975835087235718844, + "ComponentOrderEntryArray": [ + { + "ComponentId": 5012565883129470759 + }, + { + "ComponentId": 7975043234993822905, + "SortIndex": 1 + }, + { + "ComponentId": 11507863983962969790, + "SortIndex": 2 + } + ] + }, + "Component_[16460806723667032929]": { + "$type": "EditorOnlyEntityComponent", + "Id": 16460806723667032929 + }, + "Component_[18225690044585951363]": { + "$type": "EditorLockComponent", + "Id": 18225690044585951363 + }, + "Component_[18314752491697618927]": { + "$type": "EditorEntitySortComponent", + "Id": 18314752491697618927 + }, + "Component_[2431610550789583502]": { + "$type": "EditorVisibilityComponent", + "Id": 2431610550789583502 + }, + "Component_[5012565883129470759]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 5012565883129470759, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 0.20401419699192047 + ] + } + }, + "Component_[7975043234993822905]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 7975043234993822905, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{0C6BBB76-4EC2-583A-B8C6-1A4C4FD1FE9D}", + "subId": 283109893 + }, + "assetHint": "objects/bunny.azmodel" + }, + "LodOverride": 255 + } + } + }, + "Component_[8510666363380501112]": { + "$type": "SelectionComponent", + "Id": 8510666363380501112 + }, + "Component_[9639060480533776634]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 9639060480533776634 + } + } + }, + "Entity_[670308843764]": { + "Id": "Entity_[670308843764]", + "Name": "Camera1", + "Components": { + "Component_[12951260100632682169]": { + "$type": "GenericComponentWrapper", + "Id": 12951260100632682169, + "m_template": { + "$type": "FlyCameraInputComponent" + } + }, + "Component_[14180723329646459524]": { + "$type": "EditorPendingCompositionComponent", + "Id": 14180723329646459524 + }, + "Component_[14996469885773917977]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 14996469885773917977, + "Parent Entity": "ContainerEntity", + "Transform Data": { + "Translate": [ + 4.563776969909668, + 0.7667046785354614, + 3.000542640686035 + ], + "Rotate": [ + -9.740042686462402, + -20.20942497253418, + 63.57760238647461 + ] + } + }, + "Component_[17638492356673689530]": { + "$type": "EditorInspectorComponent", + "Id": 17638492356673689530 + }, + "Component_[2421853983468750254]": { + "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent", + "Id": 2421853983468750254, + "Controller": { + "Configuration": { + "Field of View": 90.00020599365234, + "EditorEntityId": 666013876468 + } + } + }, + "Component_[2572028619185965684]": { + "$type": "EditorEntityIconComponent", + "Id": 2572028619185965684 + }, + "Component_[2782900516907042776]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 2782900516907042776 + }, + "Component_[2849166119438883669]": { + "$type": "EditorVisibilityComponent", + "Id": 2849166119438883669 + }, + "Component_[4618311795498613781]": { + "$type": "EditorOnlyEntityComponent", + "Id": 4618311795498613781 + }, + "Component_[5402004894214413002]": { + "$type": "EditorEntitySortComponent", + "Id": 5402004894214413002 + }, + "Component_[6111028576371006514]": { + "$type": "SelectionComponent", + "Id": 6111028576371006514 + }, + "Component_[8203141294643544464]": { + "$type": "EditorLockComponent", + "Id": 8203141294643544464 + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Graphics/ShadowTest/tags.txt b/AutomatedTesting/Levels/Graphics/ShadowTest/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/Graphics/ShadowTest/tags.txt @@ -0,0 +1,12 @@ +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 diff --git a/AutomatedTesting/Objects/ShaderBall_simple.fbx b/AutomatedTesting/Objects/ShaderBall_simple.fbx new file mode 100644 index 0000000000..50b7b8f44d --- /dev/null +++ b/AutomatedTesting/Objects/ShaderBall_simple.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5f7a86a693878c10f91783955cc72535bf7d7c495163087a4c1982f228d27f0 +size 2145248 diff --git a/AutomatedTesting/Objects/bunny.fbx b/AutomatedTesting/Objects/bunny.fbx new file mode 100644 index 0000000000..f0a16349f7 --- /dev/null +++ b/AutomatedTesting/Objects/bunny.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef71257b240a7e704731806f8cd4b966af5d3c60f22881f9c6a6320180ee71a4 +size 2496384 diff --git a/AutomatedTesting/Objects/cone.fbx b/AutomatedTesting/Objects/cone.fbx new file mode 100644 index 0000000000..081b8b119d --- /dev/null +++ b/AutomatedTesting/Objects/cone.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:531b6473b314259504ab595e4983838b5866035ef4d70cedaf4cc9c7d9e65c3a +size 24512 diff --git a/AutomatedTesting/Objects/cube.fbx b/AutomatedTesting/Objects/cube.fbx new file mode 100644 index 0000000000..616c7b4ff3 --- /dev/null +++ b/AutomatedTesting/Objects/cube.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e32877eab35459499c73ff093df898f93bf3e7379de25eef6875d693be9bec81 +size 18015 diff --git a/AutomatedTesting/Objects/cylinder.fbx b/AutomatedTesting/Objects/cylinder.fbx new file mode 100644 index 0000000000..18ab200b4c --- /dev/null +++ b/AutomatedTesting/Objects/cylinder.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2949a50eec079a7d43a1d92e056c580ef625ee39e00e91cc25318319e37dcd3b +size 115689 diff --git a/AutomatedTesting/Objects/plane.fbx b/AutomatedTesting/Objects/plane.fbx new file mode 100644 index 0000000000..b274bfa282 --- /dev/null +++ b/AutomatedTesting/Objects/plane.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a1f8d75dcd85e8b4aa57f6c0c81af0300ff96915ba3c2b591095c215d5e1d8c +size 12072 diff --git a/AutomatedTesting/Objects/suzanne.fbx b/AutomatedTesting/Objects/suzanne.fbx new file mode 100644 index 0000000000..171a6d21e9 --- /dev/null +++ b/AutomatedTesting/Objects/suzanne.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3bcfac5de831c269dac58e7d73d1dc61eb8d9f6d8a241f5c029537b6bcdf166 +size 1088304 From 0bcb514c27299df1f09c8cdfe8e6e94247ff2f89 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 15:56:53 -0800 Subject: [PATCH 074/272] removing qlocale.h compile issue Signed-off-by: mrieggeramzn --- .../AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h index d4f0c8d705..1bd6f72a19 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h @@ -12,7 +12,6 @@ #include #include "IntegerPrimtitiveTestConfig.h" #include -#include #include namespace UnitTest From 09fd52ef73e199137bb1a38abcba7cd1242604a6 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 5 Jan 2022 16:07:52 -0800 Subject: [PATCH 075/272] AzCore Math tests produce errors that need to be disabled in debug (#6678) * Tests produce errors that need to be disabled in debug Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * PR suggestion Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/Math/Plane.inl | 8 +++----- Code/Framework/AzCore/Tests/Math/MathTest.h | 19 +++++++++++++++++++ .../AzCore/Tests/Math/PlaneTests.cpp | 11 ++++++++++- Code/Framework/AzCore/Tests/ScriptMath.cpp | 8 ++++++++ .../AzCore/Tests/azcoretests_files.cmake | 1 + 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 Code/Framework/AzCore/Tests/Math/MathTest.h diff --git a/Code/Framework/AzCore/AzCore/Math/Plane.inl b/Code/Framework/AzCore/AzCore/Math/Plane.inl index 795ee8b4bc..22c449dc6f 100644 --- a/Code/Framework/AzCore/AzCore/Math/Plane.inl +++ b/Code/Framework/AzCore/AzCore/Math/Plane.inl @@ -26,7 +26,6 @@ namespace AZ AZ_MATH_INLINE Plane Plane::CreateFromNormalAndDistance(const Vector3& normal, float dist) { - AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized"); Plane result; result.Set(normal, dist); return result; @@ -35,7 +34,6 @@ namespace AZ AZ_MATH_INLINE Plane Plane::CreateFromCoefficients(const float a, const float b, const float c, const float d) { - AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized"); Plane result; result.Set(a, b, c, d); return result; @@ -68,21 +66,21 @@ namespace AZ AZ_MATH_INLINE void Plane::Set(const Vector3& normal, float d) { - AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized"); + AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized"); m_plane.Set(normal, d); } AZ_MATH_INLINE void Plane::Set(float a, float b, float c, float d) { - AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized"); + AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is not normalized"); m_plane.Set(a, b, c, d); } AZ_MATH_INLINE void Plane::SetNormal(const Vector3& normal) { - AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized"); + AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized"); m_plane.SetX(normal.GetX()); m_plane.SetY(normal.GetY()); m_plane.SetZ(normal.GetZ()); diff --git a/Code/Framework/AzCore/Tests/Math/MathTest.h b/Code/Framework/AzCore/Tests/Math/MathTest.h new file mode 100644 index 0000000000..783c08a553 --- /dev/null +++ b/Code/Framework/AzCore/Tests/Math/MathTest.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#if AZ_DEBUG_BUILD + #define AZ_MATH_TEST_START_TRACE_SUPPRESSION AZ_TEST_START_TRACE_SUPPRESSION + #define AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(x) AZ_TEST_STOP_TRACE_SUPPRESSION(x) +#else + #define AZ_MATH_TEST_START_TRACE_SUPPRESSION + #define AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(x) +#endif diff --git a/Code/Framework/AzCore/Tests/Math/PlaneTests.cpp b/Code/Framework/AzCore/Tests/Math/PlaneTests.cpp index 016a7ec6e2..398c1320ed 100644 --- a/Code/Framework/AzCore/Tests/Math/PlaneTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/PlaneTests.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace AZ; @@ -47,7 +48,9 @@ namespace UnitTest TEST(MATH_Plane, TestSet) { Plane pl; + AZ_MATH_TEST_START_TRACE_SUPPRESSION; pl.Set(12.0f, 13.0f, 14.0f, 15.0f); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetDistance(), 15.0f); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetX(), 12.0f); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetY(), 13.0f); @@ -57,7 +60,9 @@ namespace UnitTest TEST(MATH_Plane, TestSetVector3) { Plane pl; + AZ_MATH_TEST_START_TRACE_SUPPRESSION; pl.Set(Vector3(22.0f, 23.0f, 24.0f), 25.0f); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetDistance(), 25.0f); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetX(), 22.0f); AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetY(), 23.0f); @@ -177,17 +182,21 @@ namespace UnitTest pl.Set(1.0f, 0.0f, 0.0f, 0.0f); AZ_TEST_ASSERT(pl.IsFinite()); const float infinity = std::numeric_limits::infinity(); + AZ_MATH_TEST_START_TRACE_SUPPRESSION; pl.Set(infinity, infinity, infinity, infinity); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); AZ_TEST_ASSERT(!pl.IsFinite()); } TEST(MATH_Plane, CreateFromVectorCoefficients_IsEquivalentToCreateFromCoefficients) { + AZ_MATH_TEST_START_TRACE_SUPPRESSION; Plane planeFromCoefficients = Plane::CreateFromCoefficients(1.0, 2.0, 3.0, 4.0); - + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); Vector4 coefficients(1.0, 2.0, 3.0, 4.0); Plane planeFromVectorCoefficients = Plane::CreateFromVectorCoefficients(coefficients); + EXPECT_EQ(planeFromVectorCoefficients, planeFromCoefficients); } } diff --git a/Code/Framework/AzCore/Tests/ScriptMath.cpp b/Code/Framework/AzCore/Tests/ScriptMath.cpp index 35541c5eec..927ea4a3cd 100644 --- a/Code/Framework/AzCore/Tests/ScriptMath.cpp +++ b/Code/Framework/AzCore/Tests/ScriptMath.cpp @@ -15,6 +15,8 @@ #include #include +#include + using namespace AZ; namespace UnitTest @@ -1409,13 +1411,17 @@ namespace UnitTest script->Execute("AZTestAssertFloatClose(pl:GetNormal().y,-1)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().z,0)"); + AZ_MATH_TEST_START_TRACE_SUPPRESSION; script->Execute("pl:Set(12, 13, 14, 15)"); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); script->Execute("AZTestAssertFloatClose(pl:GetDistance(), 15)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().x, 12)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().y, 13)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().z, 14)"); + AZ_MATH_TEST_START_TRACE_SUPPRESSION; script->Execute("pl:Set(Vector3(22, 23, 24), 25)"); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); script->Execute("AZTestAssertFloatClose(pl:GetDistance(), 25)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().x, 22)"); script->Execute("AZTestAssertFloatClose(pl:GetNormal().y, 23)"); @@ -1493,7 +1499,9 @@ namespace UnitTest script->Execute("pl:Set(1, 0, 0, 0)"); script->Execute("AZTestAssert(pl:IsFinite())"); + AZ_MATH_TEST_START_TRACE_SUPPRESSION; script->Execute("pl:Set(math.huge, math.huge, math.huge, math.huge)"); + AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1); script->Execute("AZTestAssert( not pl:IsFinite())"); } diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 3777071168..834e3431b6 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -148,6 +148,7 @@ set(FILES Math/Matrix4x4PerformanceTests.cpp Math/Matrix4x4Tests.cpp Math/MatrixUtilsTests.cpp + Math/MathTest.h Math/MathTestData.h Math/ObbPerformanceTests.cpp Math/ObbTests.cpp From d378544bbc813d87db5b0a897e6024a914d72aae Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 5 Jan 2022 17:06:44 -0800 Subject: [PATCH 076/272] Fixing crash log name bugs in test tools Signed-off-by: evanchia --- .../_internal/pytest_plugin/test_tools_fixtures.py | 2 +- .../ly_test_tools/o3de/editor_test_utils.py | 11 ++++++++++- .../LyTestTools/tests/unit/test_editor_test_utils.py | 12 +++++++++--- Tools/LyTestTools/tests/unit/test_fixtures.py | 11 +++++------ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index af29064766..1c17d6d519 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -413,7 +413,7 @@ def crash_log_watchdog(request, workspace): def _crash_log_watchdog(request, workspace, raise_on_crash): """Separate implementation to call directly during unit tests""" - error_log = os.path.join(workspace.paths.project_log(), 'error.log') + error_log = workspace.paths.crash_log() crash_log_watchdog = ly_test_tools.environment.watchdog.CrashLogWatchdog( error_log, raise_on_condition=raise_on_crash) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py index 9f1e01342c..54ac67f56e 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py @@ -10,6 +10,7 @@ from __future__ import annotations import os import time import logging +import re import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter @@ -71,7 +72,15 @@ def retrieve_crash_output(run_id: int, workspace: AbstractWorkspaceManager, time :return str: The contents of the editor crash file (error.log) """ crash_info = "-- No crash log available --" - crash_log = os.path.join(retrieve_log_path(run_id, workspace), 'error.log') + error_log_regex = "" + log_path = retrieve_log_path(run_id, workspace) + # Gather all of the files in the log directory + dir_files = [f for f in os.listdir(log_path) if os.path.isfile(os.path.join(log_path, f))] + for file_name in dir_files: + # Search for all .log files with either "crash" or "error" because they could be renamed + if ("error" in file_name.lower() or "crash" in file_name.lower()) and (file_name.endswith(".log")): + crash_log = os.path.join(log_path, file_name) + break try: waiter.wait_for(lambda: os.path.exists(crash_log), timeout=timeout) except AssertionError: diff --git a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py index cd361d9e8a..f7678c44c0 100644 --- a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py +++ b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py @@ -59,22 +59,28 @@ class TestEditorTestUtils(unittest.TestCase): assert expected == editor_test_utils.retrieve_log_path(0, mock_workspace) + @mock.patch('os.listdir') @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') + @mock.patch('os.path.isfile', mock.MagicMock()) @mock.patch('ly_test_tools.environment.waiter.wait_for', mock.MagicMock()) - def test_RetrieveCrashOutput_CrashLogExists_ReturnsLogInfo(self, mock_retrieve_log_path): - mock_retrieve_log_path.return_value = 'mock_log_path' + def test_RetrieveCrashOutput_CrashLogExists_ReturnsLogInfo(self, mock_retrieve_log_path, mock_listdir): + mock_retrieve_log_path.return_value = 'mock_path' mock_workspace = mock.MagicMock() mock_log = 'mock crash info' + mock_listdir.return_value = ['mock_error_log.log'] with mock.patch('builtins.open', mock.mock_open(read_data=mock_log)) as mock_file: assert mock_log == editor_test_utils.retrieve_crash_output(0, mock_workspace, 0) + @mock.patch('os.listdir') @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') + @mock.patch('os.path.isfile', mock.MagicMock()) @mock.patch('ly_test_tools.environment.waiter.wait_for', mock.MagicMock()) - def test_RetrieveCrashOutput_CrashLogNotExists_ReturnsError(self, mock_retrieve_log_path): + def test_RetrieveCrashOutput_CrashLogNotExists_ReturnsError(self, mock_retrieve_log_path, mock_listdir): mock_retrieve_log_path.return_value = 'mock_log_path' mock_workspace = mock.MagicMock() error_message = "No crash log available" + mock_listdir.return_value = ['mock_file.log'] assert error_message in editor_test_utils.retrieve_crash_output(0, mock_workspace, 0) diff --git a/Tools/LyTestTools/tests/unit/test_fixtures.py b/Tools/LyTestTools/tests/unit/test_fixtures.py index 32dc204bd2..eb36cf6998 100755 --- a/Tools/LyTestTools/tests/unit/test_fixtures.py +++ b/Tools/LyTestTools/tests/unit/test_fixtures.py @@ -323,20 +323,19 @@ class TestFixtures(object): @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog') def test_CrashLogWatchdog_Instantiates_CreatesWatchdog(self, under_test): mock_workspace = mock.MagicMock() - mock_path = 'C:/foo' - mock_workspace.paths.project_log.return_value = mock_path + mock_workspace.paths.crash_log.return_value = mock.MagicMock() mock_request = mock.MagicMock() mock_request.addfinalizer = mock.MagicMock() mock_raise_on_crash = mock.MagicMock() mock_watchdog = test_tools_fixtures._crash_log_watchdog(mock_request, mock_workspace, mock_raise_on_crash) - under_test.assert_called_once_with(os.path.join(mock_path, 'error.log'), raise_on_condition=mock_raise_on_crash) + under_test.assert_called_once_with(mock_workspace.paths.crash_log.return_value, raise_on_condition=mock_raise_on_crash) @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.start') def test_CrashLogWatchdog_Instantiates_StartsThread(self, under_test): mock_workspace = mock.MagicMock() mock_path = 'C:/foo' - mock_workspace.paths.project_log.return_value = mock_path + mock_workspace.paths.crash_log.return_value = mock_path mock_request = mock.MagicMock() mock_request.addfinalizer = mock.MagicMock() mock_raise_on_crash = mock.MagicMock() @@ -348,7 +347,7 @@ class TestFixtures(object): def test_CrashLogWatchdog_Instantiates_AddsTeardown(self): mock_workspace = mock.MagicMock() mock_path = 'C:/foo' - mock_workspace.paths.project_log.return_value = mock_path + mock_workspace.paths.crash_log.return_value = mock_path mock_request = mock.MagicMock() mock_request.addfinalizer = mock.MagicMock() mock_raise_on_crash = mock.MagicMock() @@ -361,7 +360,7 @@ class TestFixtures(object): def test_CrashLogWatchdog_Teardown_CallsStop(self, mock_stop): mock_workspace = mock.MagicMock() mock_path = 'C:/foo' - mock_workspace.paths.project_log.return_value = mock_path + mock_workspace.paths.crash_log.return_value = mock_path mock_request = mock.MagicMock() mock_request.addfinalizer = mock.MagicMock() mock_raise_condition = mock.MagicMock() From 52ab5a1c0fb5f0744df0c879844ca3512b48109d Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 5 Jan 2022 17:10:18 -0800 Subject: [PATCH 077/272] removing unused import Signed-off-by: evanchia --- Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py index 54ac67f56e..69c6eda2ee 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py @@ -10,7 +10,6 @@ from __future__ import annotations import os import time import logging -import re import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter From e2a960e44296fe4a1a844abf1f90df2260cc91cd Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 Jan 2022 17:21:15 -0800 Subject: [PATCH 078/272] Fixed a sync issue when a PrefaDOM was taken from a PrefabDocument. When a PrefabDOM was taken from a PrefabDocument the Instance would continue to have the data from the original Prefab, which means they'd no longer be in sync as the Prefab would be empty. This was fixed by resetting the Instance so they're both clear. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- .../Prefab/Spawnable/PrefabDocument.cpp | 10 ++++++++-- .../Prefab/Spawnable/PrefabProcessorContext.cpp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp index c0eb5257b0..04fdea30d2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp @@ -16,7 +16,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils : m_name(AZStd::move(name)) , m_instance(AZStd::make_unique()) { - m_instance->SetTemplateSourcePath(AZ::IO::Path("InMemory") / name); + m_instance->SetTemplateSourcePath(AZ::IO::Path("InMemory") / m_name); } bool PrefabDocument::SetPrefabDom(const PrefabDom& prefab) @@ -64,8 +64,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { if (m_isDirty) { - m_isDirty = !PrefabDomUtils::StoreInstanceInPrefabDom(*m_instance, m_dom); + [[maybe_unused]] bool storedSuccessfully = PrefabDomUtils::StoreInstanceInPrefabDom(*m_instance, m_dom); + AZ_Assert(storedSuccessfully, "Failed to store Instance '%s' to PrefabDom.", m_name.c_str()); + m_isDirty = false; } + // After the PrefabDom is moved an empty PrefabDom is left behind. This should be reflected in the Instance, + // so reset it so it's empty as well. + m_instance->Reset(); + m_instance->SetTemplateSourcePath(AZ::IO::Path("InMemory") / m_name); return AZStd::move(m_dom); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index fd8ce43836..12625712b7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -245,7 +245,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZ::Data::Asset(target->m_spawnable.GetId(), azrtti_typeid()), alias.m_tag, sourceIndex, targetIndex, alias.m_aliasType, alias.m_loadBehavior == EntityAliasSpawnableLoadBehavior::QueueLoad); - + // Register the dependency between the two spawnables. RegisterProductAssetDependency(source->m_spawnable.GetId(), target->m_spawnable.GetId(), loadBehavior); From 5f9a4a5eed421480094884b2b78ac309d2d77fde Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 5 Jan 2022 17:21:55 -0800 Subject: [PATCH 079/272] docstring clarification and addressing review comments Signed-off-by: Scott Murray --- .../editor_entity_utils.py | 95 +++++++++++-------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 4dd7ec1446..d354c4ece6 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -22,7 +22,7 @@ import azlmbr.legacy.general as general from editor_python_test_tools.utils import Report -class Entity_Type(Enum): +class EditorEntityType(Enum): GAME = azlmbr.entity.EntityType().Game LEVEL = azlmbr.entity.EntityType().Level @@ -39,7 +39,7 @@ class EditorComponent: def __init__(self, type_id: uuid): self.type_id = type_id self.id = None - self.property_tree = None + self.property_tree_editor = None def get_component_name(self) -> str: """ @@ -52,7 +52,7 @@ class EditorComponent: def get_property_tree(self, force_get: bool = False): """ - Used to get the property tree object of component that has following functions associated with it: + Used to get and cache the property tree editor of component that has following functions associated with it: 1. prop_tree.is_container(path) 2. prop_tree.get_container_count(path) 3. prop_tree.reset_container(path) @@ -60,32 +60,36 @@ class EditorComponent: 5. prop_tree.remove_container_item(path, key) 6. prop_tree.update_container_item(path, key, value) 7. prop_tree.get_container_item(path, key) - :param force_get: Force a fresh property tree to be returned rather than using an existing self.property_tree - :return: Property tree object of a component + :param force_get: Force a fresh property tree editor rather than the cached self.property_tree_editor + :return: Property tree editor of the component """ - if (not force_get) and (self.property_tree is not None): - return self.property_tree + if (not force_get) and (self.property_tree_editor is not None): + return self.property_tree_editor build_prop_tree_outcome = editor.EditorComponentAPIBus( bus.Broadcast, "BuildComponentPropertyTreeEditor", self.id ) assert ( build_prop_tree_outcome.IsSuccess() - ), f"Failure: Could not build property tree of component: '{self.get_component_name()}'" + ), f"Failure: Could not build property tree editor of component: '{self.get_component_name()}'" prop_tree = build_prop_tree_outcome.GetValue() Report.info(prop_tree.build_paths_list()) - self.property_tree = prop_tree - return self.property_tree + self.property_tree_editor = prop_tree + return self.property_tree_editor def is_property_container(self, component_property_path: str) -> bool: """ - Used to determine if a component property is a container. Containers are similar to a dictionary with int keys. + Used to determine if a component property is a container. + Containers are a collection of same typed values that can expand/shrink to contain more or less. + There are two types of containers; indexed and associative. + Indexed containers use integer key and are something like a linked list + Associative containers utilize keys of the same type which could be any supported type. :param component_property_path: String of component property. (e.g. 'Settings|Visible') :return: Boolean True if the property is a container False if it is not. """ - if self.property_tree is None: + if self.property_tree_editor is None: self.get_property_tree() - result = self.property_tree.is_container(component_property_path) + result = self.property_tree_editor.is_container(component_property_path) if not result: Report.info(f"{self.get_component_name()}: '{component_property_path}' is not a container") return result @@ -99,7 +103,7 @@ class EditorComponent: assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - container_count_outcome = self.property_tree.get_container_count(component_property_path) + container_count_outcome = self.property_tree_editor.get_container_count(component_property_path) assert ( container_count_outcome.IsSuccess() ), f"Failure: get_container_count did not return success for '{component_property_path}'" @@ -107,21 +111,22 @@ class EditorComponent: def reset_container(self, component_property_path: str): """ - Used to rest a container to empty + Used to reset a container to empty :param component_property_path: String of component property. (e.g. 'Settings|Visible') :return: None """ assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - reset_outcome = self.property_tree.reset_container(component_property_path) + reset_outcome = self.property_tree_editor.reset_container(component_property_path) assert ( reset_outcome.IsSuccess() ), f"Failure: could not reset_container on '{component_property_path}'" def append_container_item(self, component_property_path: str, value: any): """ - Used to append a container item without providing an index key. + Used to append a value to an indexed container item without providing an index key. + Append will fail on an associative container :param component_property_path: String of component property. (e.g. 'Settings|Visible') :param value: Value to be set :return: None @@ -129,38 +134,44 @@ class EditorComponent: assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - append_outcome = self.property_tree.append_container_item(component_property_path, value) + append_outcome = self.property_tree_editor.append_container_item(component_property_path, value) assert ( append_outcome.IsSuccess() ), f"Failure: could not append_container_item to '{component_property_path}'" def add_container_item(self, component_property_path: str, key: any, value: any): """ - Used to add a container item at a specified key. In practice key should be an integer index. + Used to add a container item at a specified key. + There are two types of containers; indexed and associative. + Indexed containers use integer key. + Associative containers utilize keys of the same type which could be any supported type. :param component_property_path: String of component property. (e.g. 'Settings|Visible') - :param key: Zero index integer key, although this could be any unique unused key value + :param key: Zero index integer key or any supported type for associative container :param value: Value to be set :return: None """ assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - add_outcome = self.property_tree.add_container_item(component_property_path, key, value) + add_outcome = self.property_tree_editor.add_container_item(component_property_path, key, value) assert ( add_outcome.IsSuccess() ), f"Failure: could not add_container_item '{key}' to '{component_property_path}'" def get_container_item(self, component_property_path: str, key: any) -> any: """ - Used to retrieve a container item value at the specified key. In practice key should be an integer index. + Used to retrieve a container item value at the specified key. + There are two types of containers; indexed and associative. + Indexed containers use integer key. + Associative containers utilize keys of the same type which could be any supported type. :param component_property_path: String of component property. (e.g. 'Settings|Visible') - :param key: Zero index integer key + :param key: Zero index integer key or any supported type for associative container :return: Value stored at the key specified """ assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - get_outcome = self.property_tree.get_container_item(component_property_path, key) + get_outcome = self.property_tree_editor.get_container_item(component_property_path, key) assert ( get_outcome.IsSuccess() ), f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]" @@ -168,31 +179,37 @@ class EditorComponent: def remove_container_item(self, component_property_path: str, key: any): """ - Used to remove a container item value at the specified key. In practice key should be an integer index. + Used to remove a container item value at the specified key. + There are two types of containers; indexed and associative. + Indexed containers use integer key. + Associative containers utilize keys of the same type which could be any supported type. :param component_property_path: String of component property. (e.g. 'Settings|Visible') - :param key: Zero index integer key + :param key: Zero index integer key or any supported type for associative container :return: None """ assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - remove_outcome = self.property_tree.remove_container_item(component_property_path, key) + remove_outcome = self.property_tree_editor.remove_container_item(component_property_path, key) assert ( remove_outcome.IsSuccess() ), f"Failure: could not remove_container_item '{key}' from '{component_property_path}'" def update_container_item(self, component_property_path: str, key: any, value: any): """ - Used to update a container item at a specified key. In practice key should be an integer index. + Used to update a container item at a specified key. + There are two types of containers; indexed and associative. + Indexed containers use integer key. + Associative containers utilize keys of the same type which could be any supported type. :param component_property_path: String of component property. (e.g. 'Settings|Visible') - :param key: Zero index integer key + :param key: Zero index integer key or any supported type for associative container :param value: Value to be set :return: None """ assert ( self.is_property_container(component_property_path) ), f"Failure: '{component_property_path}' is not a property container" - update_outcome = self.property_tree.update_container_item(component_property_path, key, value) + update_outcome = self.property_tree_editor.update_container_item(component_property_path, key, value) assert ( update_outcome.IsSuccess() ), f"Failure: could not update '{key}' in '{component_property_path}'" @@ -252,7 +269,7 @@ class EditorComponent: editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) @staticmethod - def get_type_ids(component_names: list, entity_type: Entity_Type = Entity_Type.GAME) -> list: + def get_type_ids(component_names: list, entity_type: EditorEntityType = EditorEntityType.GAME) -> list: """ Used to get type ids of given components list :param component_names: List of components to get type ids @@ -426,7 +443,7 @@ class EditorEntity: :return: List of newly added components to the entity """ components = [] - type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) + type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME) for type_id in type_ids: new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorComponentAPIBus( @@ -454,7 +471,7 @@ class EditorEntity: :param component_names: List of component names to remove :return: None """ - type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) + type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME) for type_id in type_ids: remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id]) assert ( @@ -468,7 +485,7 @@ class EditorEntity: :return: List of Entity Component objects of given component name """ component_list = [] - type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.GAME) + type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME) for type_id in type_ids: component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorComponentAPIBus( @@ -488,7 +505,7 @@ class EditorEntity: :param component_name: Name of component to check for :return: True, if entity has specified component. Else, False """ - type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.GAME) + type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.GAME) return editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", self.id, type_ids[0]) def get_start_status(self) -> int: @@ -690,7 +707,7 @@ class EditorLevelEntity: :return: List of newly added components to the level """ components = [] - type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.LEVEL) + type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.LEVEL) for type_id in type_ids: new_comp = EditorComponent(type_id) add_component_outcome = editor.EditorLevelComponentAPIBus( @@ -711,7 +728,7 @@ class EditorLevelEntity: :return: List of Level Component objects of given component name """ component_list = [] - type_ids = EditorComponent.get_type_ids(component_names, Entity_Type.LEVEL) + type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.LEVEL) for type_id in type_ids: component = EditorComponent(type_id) get_component_of_type_outcome = editor.EditorLevelComponentAPIBus( @@ -732,7 +749,7 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: True, if level has specified component. Else, False """ - type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.LEVEL) + type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.LEVEL) return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0]) @staticmethod @@ -742,5 +759,5 @@ class EditorLevelEntity: :param component_name: Name of component to check for :return: integer count of occurences of level component attached to level or zero if none are present """ - type_ids = EditorComponent.get_type_ids([component_name], Entity_Type.LEVEL) + type_ids = EditorComponent.get_type_ids([component_name], EditorEntityType.LEVEL) return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0]) From da0a10bb4cde930c7266bbb24d2cd6f5f7dedfbf Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Wed, 5 Jan 2022 19:04:55 -0800 Subject: [PATCH 080/272] fix for edit SC action in entity context menu (#6686) * on demand reflect az events when they are the return value of ebuses Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> * fix crash and functionality for edit sc editor context menu action Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp | 6 ++++-- Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp index 9bbdddfedb..1b5e97ba36 100644 --- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp @@ -265,11 +265,13 @@ namespace ScriptCanvasEditor action = entityMenu->addAction(QString("%1").arg(QString(displayName.c_str()))); - QObject::connect(action, &QAction::triggered, [assetId] + QObject::connect(action, &QAction::triggered, [assetInfo] { AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas); + SourceHandle sourceHandle(nullptr, assetInfo.m_assetId.m_guid, ""); + CompleteDescriptionInPlace(sourceHandle); GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset - , SourceHandle(nullptr, assetId.m_guid, "") + , sourceHandle , Tracker::ScriptCanvasFileState::UNMODIFIED, -1); }); } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 6222d902da..1176df61dc 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -1139,7 +1139,7 @@ namespace ScriptCanvasEditor auto loadedGraphOutcome = LoadFromFile(fileAssetId.Path().c_str()); if (!loadedGraphOutcome.IsSuccess()) { - return AZ::Failure(AZStd::string("Failed to load graph at %s", fileAssetId.Path().c_str())); + return AZ::Failure(AZStd::string::format("Failed to load graph at %s", fileAssetId.Path().c_str())); } auto loadedGraph = loadedGraphOutcome.TakeValue(); From 23293a13c14b90402c9aee42dedfbf53cb3b0934 Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Wed, 5 Jan 2022 21:51:42 -0700 Subject: [PATCH 081/272] Improved DiffuseProbeGrid blending around the edges of the volume Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../DiffuseComposite.azsl | 2 +- .../diffuseprobegridrender.azshader | Bin 240003 -> 219075 bytes ...fuseprobegridrender_dx12_0.azshadervariant | Bin 32631 -> 30575 bytes ...fuseprobegridrender_null_0.azshadervariant | Bin 589 -> 589 bytes ...seprobegridrender_vulkan_0.azshadervariant | Bin 24581 -> 24081 bytes .../DiffuseProbeGrid.cpp | 22 ++++++++++++++---- .../DiffuseProbeGrid.h | 5 +++- 7 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl index 9aa169beea..e3237e59a2 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl @@ -150,7 +150,7 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex) float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex); float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb); float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex); - float probeIrradianceBlendWeight = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a; + float probeIrradianceBlendWeight = saturate(PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a); float3 diffuse = float3(0.0f, 0.0f, 0.0f); if (probeIrradianceBlendWeight > 0.0f) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader index 781d7e26e514ab7a100ea668bd864c3b9ef1f0b9..1f045706254b0b0c859f4bc976030ea3b50a5844 100644 GIT binary patch delta 2922 zcmeHJeN0 z()sn48w~~n8#CU?+%=7hYP^p;v!My6&l07YtnF4mGf9@KJ z#vF?V54cDrwjZR~xOg?(rJWbMIMIb3iKesJkj%nr3Jd-qvqpa|dTMDGD%qr0ND>y; zP#MP>VJQZe5t+3gx3ad7jLHP0G5^JlY}G_Q2JWR+v{izYxyEJ9IkshzF3lP1y`cYF zzY}Qpi#4|IWemE(j-wewMq4`R6ASFPNl2_@Kw^`lGE*!@YzRRr^L#5azatBO$`!WC zO=N$>`TlKUgPvTn_m$A~7Q(O{z6L`6L@*M#@I!NE)-`oN6^~73KO34bY zd`!*(Dl3UeJzINVQR4A%VQ{s8b@%6>cL)|Jd<{_eFLE|%QqNpDP5zj;kBTjZzL)d8 zVRyBGUq$M-{7X6ybdV^WQ54~mkjbiVDAH~^zj+vZmj9zBqo~PEnEN1DuqB`N=%XJ2 z9PIFk23;E73C~AH?8~w|TyG&ccz6aj%}=qalRM@GEa`=1`016He(R|{^E%(!r}c5m zItO1KP=y?jFTXr@(m}mVq9ZZWG1HXYDI1@UQY$O%k;b=IhS@=#z z55~C*`eT@ROd9Tp3&E&>!lsy|R@t!Z+1Qb2Zrj&V9aC(_hDE!fS;Vk?Db)U5V>~w4 zxwAFYUm9P~f!O&?JDgS40lscc?gs-n6&guu7gy(QlxXv PTeDy6z2!fY_0it}yUs(O delta 6935 zcmeHLdrXs86z}=I7D^Q;C`gMHG>TImtuixBoY24)MCGNRa}KFe1t;R8^${JbqMM?V z$AO*9*F+7Qq5-Y)8Rr8tgR&tnXW}v+MJKwAOo@LjPT1{hiopf5#bsIl;ePktbIy0p zE%$eR-|y=x&-^Q1)uY6c4|Z)mqc%r~(*Zl;LuK+fefGjELym4K4w=#c99q6p07unX zzy^$(x(VfDBv^N4q+6`spvzv&tQLU?)0ve>sLtnx0Gg7-)Vh)L6V$t5vy2{9K!jJO z&3Ky5pkJP?TTJU8g9@wN62OF74+XCfiRk=RPD^{Aa4K`b)}wCtp;Cggd_&~&oVi)f zj3(#k7UJGpSyZIwJn$Xg5mem(;sHHEPtJ5&m8p3N9E>gLoAtH4WmGA`!Nwh6zKeKq@vvAJ9eLz*y>mUbn_C1JT*L1$Yb66N830|z)A z;&h7_BxSGGFHT*FoktZg3t^6qny!OHYW+vj>gLU}uH&+Im6)MXVRKDdug(NDTsl@q ziz%-ayv*Z;aS+(^T%SovzZ{oMQqvwOsLhK`?)2#SKI(LbbfM@b#B#6{&+~(%zx*`e z#{IQnG1TG#V{pfXOzDA&?Gfz-+MRebCF0Y5{8;q98RPc;8bfN62|@J53XFSq1l#yU4lk_{j=%NZ>Lg30?X7@uvE5!c62 zMh7S)~X?OD4 zHTSA4CLziTDrG`Z3ZE(#G&A`5ys$4Aj4l@7VgW7|@G>kw@O%hTDMjbPKF4(NxgC8aNaZ>EQBRMvsIFttOf+sGj;GzmHs^Fpu|1wpuf>*PwFSxZb)J`Bg zJc_?4tZSIjAQC3N&42FEgFy_N$n}vyY_NS_pT83JLLC7Dsc9n@KukqA3o5hDt={9m zswI%7hVjkYsi7`0fr$y2SCPrIg|^U-+28VZ4bC~|i;dxfXs?(HEQwIUU}`DlBC%+r z7}eovZ0Zvar8bXnd~hZRvky*Xi`qIUW5dt{&`{MiCd?EZV#_RSI2B%m)$DQTSPeFv z@~4DLVBgVT^x>Iyp90%{i8anQP|SvwMA&9`FL`~Q-I;6kq!FvTbTD#Bwy0!xot1*mQ^;vu)D=dN30f+ILwB^hnn^vJt3?v_K6F*@K2kHo8JsXsqlINgu0cgGVcb18QN=TvK~ z+XCC}3Kcd99M`uG9T!afZ#7RBOxY061yg-fj$aH@R^4kZYa^X)p#7Wjmz_v3;i@kR zSQ@CTV%UjSsDat#xju+s5Xf}AIGT1FR{diVSZi;6px8-no$!A_Ev+6Ud$jJ>LHFkg HEb@NE2SB|uTfG_i1uL>-z*K9#S5M;gr zu0p{HEroAm z=%^d;LkwR?VNppqsZvBC=n>PsP>>DsF`h7TlA=#DTzgA${zpIEelBf`o{tQTU7AQw zI9m&ynQ(5^Ge5V>p3HdLbh?c1n9b00PxW^2slN6?O9I8^aWq0`nh&Pgn{6hEr$M&XJ#vkzckFpC*u}*jmR# zl6waS^)|Lmd`l42<-TYj{9%uM=NfdJ`n`;V7D05le6^EHL3;8Yd>TJ9u|O>?4S$HA zp6rTGR^ZpNIlnonyt7MIJKXgq2p@e($MKZ9Ar?aQ+w_*h{zNO-!(C$)r13n5{EV$t zokRXrM1DDjw@E8m7O1_H`5l+gp|Mot6JZlpjO%1cKNY>kpL{Y(0 zO?V^DfveOT6q`(y8c(3~+c>6er6xUM(;klLdq}O(ifV-#>tQb#?=SLkg23xME*LT1 zD+u?!m%J|(qeq0;r96nTyB@y0dZiaVJvk>ck%~X$mw6x|Gl7ra>X(_s#vdwBOD5nG z(=rdwVf4nxiWqf{VlZn3ak6{1o^7y%Im$=bNli1!`pcv|CZ z@`4NI9$GJQ!L)tBICE*3v91L{4b8V^!5H>RYH%7pwJS3z4S!(4<*0;9OmNc@Zdaq( z>tV^7<+c}P-9qiQFw4iUuYR9fnKgEP_lfgM)htBj))r^_k@O>Ki?L?H+8X+BDM@#| zXTS6yAv0A3hLE{Sk$FUvnaJh{F2x!Tn;TCGOh-lfJt(uOQqu|GF_GSOf&QCTg<=%7N&2wMA|4uPh$MrZ)msL>RyuU97MK*vYhj zZm7-8$yT>s---2h(x=nuZ3JjZfP&x)ohW6)hslA2Riz?b;@6NG{4X-YmrnFhQ1HZ6 z3I&GfsTji$*D4rl#LWtx8gZ*aq}EgB8sH?dPv_w*p{1PDhLEHe;zi&@R?bj)0ZP$9 zg3NbAQw(^6)=q~L&X8UKirz|sOrjuy8;0F&2yMCx^(W#)16#F^!7SPX&-5P2r1}I~{ zOm(k;SjHI*=T9@zf4w#yYJIzW!d0OKO?Rk;g7=($&_4qd8i-SmB!1Oijst zQyTi^FrE6eP9TzUJ-a|p1L@rZoR*4a;0~Qvtt18kV-dS6Q4kTGl0?hy@MJgvrRjsO zzS}yP>YI68={JUHP-75)))pGUG(>CHF@@(NjPWnw#uMR^Is7{YXAW}|$oR9)y!JE@ zX-30&cFhT;{tpax6dIarEE>gG4rtAgz({U19xY9;E8JO;J5UP5|J53U0;6C5V4I1t zs@V%It|n*()I^$@=U0@JB5G2U_Yo^?dT?&EF!&5@XCY#zFN2I8f}XXtNr;VDRP}iN zV-#+Gt@!}Pu^|0F!l~1L6LPi9bJe|UUbbUVdT#_${`sy9XdR2-dm@H9L=Vzl6T2%Z zS&*2#E-u19E+R6GmMvR{jNcX5*FsW)qRK#=iBY>^ccp^Ac!}|QBg2!Uh4FELg5<>LG+K_#H|wa%(3}3*^yB>w ztN4t^yS?w~H`obpNzWV(vZIx4IGiLsW7n{cSO#xs zFQ)4qtVQ{E%7*dTTwv9-kWY#|Z0WAc<+SuwAi4!oh@QX+yCo&+R2k|?>!-0I6Zo^= zz=WRvb#i%4P0ZaZAOEeg1(RI$?>?b~Hv_!qugeVta^5V+x!1g40?n3YFdv!+`hdJO zKwgaG8Y0iOseaopiL~tU&lzh$gp5Uf8c+V@ZkKd@-&d(W>*EZ3zSn2D!AGNQ!~YnTjS!4$qtZ_ej4P7=sqEJSSay zLuim&NI#GE=TbJ0TUisX@O5;tQwCX{$B`5|pHHu~A59E*of)0!nV9Th(YukRO2jDFmN{Olcf6^}I$ygu zI+in7&XW0PQhGYl-k2ONJ^bgvc!G58|;$G_I(vzwm}-c!43wIT!ln3 zPHG6Uc--e<$U-!~GDXG-!eSzQqId63Ns3(W4}xqr;}9ej--8Q4YM)g#($&3`MCPN3!MlT_EUN!qJ`Sj@-RyGngX8L* zRgR-b;KRChF!2t2Xx?$aW1iA0$QTQ+yWFb3?&RYB)#@Adz|+piHpnLa-x^#+rytzdIBic3-l zww{0Pv-reVL5x?l08C*AhTla>7wJ(K;9hP!}&9`Rp7pcgXO94zXjx+``@Zr?XMV^dwT0%Wb* zZ8*yjT6R2`-+REicsyS{U0zd|F3;as+MVAgEN!XF1#4q4SR0Q?|Dy@q;*40j{u0y0 zvf0JOy`i?w>0+bXO<-_jLD8UPTO~6Fz=EPs*^9Nx`gLdLtBBpKZN4sG^nUm|+Q7^K zs?l!}9P|++3w#l)fuVcpgWUR*e;I7qTZtc(7Je9d?^NK`71_wf9jNPX!c76QeqLSw z{JIu-IBnD6AXc>!>-vc|ax}hCXiO%MXGG-R8Cq|7TB`)Q9{Y9oDfJV__3IsJ zH#oE>0@L62oBqKud%MwWX_$pwq6I_8(#gs4#u>YbO%5+Nt^Divl~s_FrMFWR&*>81 zsVc#VmE?Ra+@rb7qvf&3n67ZmV`omKOtUpZ$uRq4gmV6e41tZ=%R+jiBp`+`l<6B3 zTvU8-2&w^n&;p>2=)&P33=LsFQf1NL^w}r(wN?EWIb~YlLsTXSFn)uQxGn zHmiGyHS7mRC#NQX>m2$EHh8=Xvn+Ewm-=ee`XAV z_ArlL>6P(o*fwhyu+d;Gr5ELlHxH-Rfh}*KdbWE+nnThaK}2L?V0=VmOpv6UWccOD z(2>y{C8NP3qj~(VV9`!JSE|{|E8d`!b6Zo-`LNa*_-@aHUq)Erz7 zK{)W~3V!^+PXqXw1wU`W&9}A<9nRmQmcChrm=A*fQvav<#=!ND=KB+-V~SCmRq(jF zA(r(9C2TW2{r%$?X>4LTn@$0i79$^i4u@6bC~8|yl2J6eD7x%~B#Xx|4U+vcm&d|=Fip@8q)j$hdI6gb^qT+T zqk({=a5_SI))-mIgbW04+I6|fnW#RiIskKZog54ZbVakKrjAzuz?UOSCeHg7iFV(w zyhyjui^+0E^UzvHPf!TFJ*OaB9MCo!?Xx^%8Tf=EiYy5|W9kZb|0!`BrBz zfO~BJgGwM>1j(NnI)DLt{qC(W)JLmTU#vz8Ymo6`(GxeLZ@gDOOz3`2$=GAn5pCsz z1)7@k#al&Tkq{PQ+7amUBe+LI0W&4r`GDtmR~c38Dgu3s z7rg)Fx;Emw^eMINsNYTgLAouQ+<0<#vvtYv!%4qliibzZ?S z5%2BWR%_(C`#I-l?dN6z7%eIsgJV5ho%!P?gG!Sr@sh!D<9;y$a{K;RgdwA}CqoFY z_Rq6uz`r3>@5_%Y+LfX4w4XfJN`Au7n49|t2>&&55eUCb9^@i8)QJueAl(9g6-jnM z=|3_z85Nrbo15H4nM^6Qcofe?ix2%ex-j-K>1vs`M;^vAPr4fL<7)poKXhxpc##QBbhO)Ku9~%Zz=Sg>(y4SKdzJ>! zOa!Kis5b%+2M{d*qu2C)O4oYAAivBZKOZBHw|?Zr42>xYd18+I8Zi5Q)5X9z(=PyF z(|QC5Ey99&315YU8TNje2ZI-p>4f-282kdp^!WBHRf$05mNP_0CWAN*Y5l>|n&Ewv z2}I2;7WHia${P^{k_J+d5El-DAXsS^R%+TNHeT=q^iAL*j6W2@XpdGEK-g#s%vN`z zg38BCj@GYpA7tn`as@XAFEQt z4Ul-+7-ci6LdeH@E)Koq=@N;r=O3)MS>-t-le9&vBI$sM%{OnDX7_9q+Gat zuO-A>o?~PqZnH_(7J1o7&(J$b(5l^#pA&`+8$uTWf{w(An9fjRA&P#N1f}eT_BdkL zCk&y0UWgKg6Oo;v2tcRXNRT$T#h542!UYt49!39^1bG5V?T%p&7(!>jtz?|25ClnnHTem`IQy5^~C`_ZK&md0j z$njIlYbaf3fztXE*o`d*mivuwyBoGNDyGmH5zyt%?wVkTE0T8Kk3_voHo)* z9j6s~EJDaiE+w>dsWqXd71my#gj?yzNmDxqpICno=jh1EQY(Pf{kChgak&(UO98!C z!flB2TZh8!4U_OSm~gXyzs9(=H34PHr6en@8}b4OC~(m6u`c?W93bXBI2Tedx@||% zj)$Y?c7Q*z<`i(CN1Fzw4T+sO1Yf{t8oiuNQ^sNv*pHc;%T|41$=dUnl^Blj=MIEF zx8&&RV!voT{tx_|pytBUa*Ev*5uLPe(+Aot^DIiP#6$sJCiH%cPZ^ur^Uf(;!vi_j zJs*&HndE`peraZg-gN5--|BV0!pp?9{Qfr`)59H#N0WodX8z0G-pQUR7Pb2bvx(DZcdZ!>D_zSXm5<^61GxUaQx4oyPM%B(C(k(3hU|YQ6S?J0VrjDzlUFSM*N_MU$=LD!D zEE!?kkkG0L@b#6~orKQr7n#U8-=fcSNZejAtFa=xZ)UkXn;a|6z3m5+RmS;BY8e0n zNsfbWI3}(U_rK|H8}7~NK~8_b1li0|V1kP4E1R9`tXysaqQbnn`Z5zaJa4kpv>g%y zlJlsn?zFp2y5@1aVX@l{LUtEHKHMeeQg(KZFS926GNuc*-s@Rdk9rOxEuwu4AJ=br z1hC7gwuz||qX1iU^~?cDrO;LGF&(Wo&a-Z7#O3k1bF(+CyMynv%phw z(#M0NgaUY?WjE~m`E+Zk@dCbY&QI@-K3e$k*T#x#`F(DmuC1zQzBm7GAO*bz9D|Px zz67I3c&+dQhn^k-mZSy-fgFLl}x%X9E6DsTSRn*cEDe7pp+-n{H zI&K3xRt}a2nB<{7KRM{@=0=w5^?KVIF7B5aotZa3;P*K&nIpCsZM`Dh#7BtAJbqVu zeRk6Kdlf)_3C>;sGK5wL{|{770c0a$tI>Ag6Z5Q}8=sRJ7Xd7ur zi>t!z7DH|9H84MqRiMrRQ-lFi2tU-Q_NNFU79;Iegmc_rK1STSsHF5vzT){zpWJqq zB#)b_xhs#8P(~5gp6d(+t{q+o$lR7f;K$Hmw$;>N`JIdzZ{1bVx~{pfyAt+%0rSlB zgEr=GJ-8%9cx6fG$dX;^28nJ4DTQ>u*X%2^`|PW0xDKS{T!-qKY%s4to^9NKjtEVJI;fMnnPeeWc8Nwf{&`-oEKL$s=5=^;=G z0bq}I_%Li)bswPO!5NS#^X`AsDSXsf`RG#TL{HCXIl_TJ8oSM`2l*!d>y3QD448Wq>rH6~FV7q+*N#Tb)V6Yy&9i*m=Exto+ z|8VEsUr>Yp2yQ6@*!*B#= zXCM+o#c<91sUB*9$DsoY`us07?46^*dF+UzU2eOwCZ zOaYzoC)k<%C6Ls?Q~a}?pr=xq0dH~&9CzEEtuV4il#Jl#E^a&gm^ zrNM$&J8!4>&wc4ds%({L(0}^e=ew(E)-9zkqicGb3U-$ns&-@s_=q3 z4G^@(Li!$1-6o`pJBvf_hZKQQilDd?cp__*rg8zeu)lb>)^w}TT!lNWmz-Vpr>_B0 z)Itj9mtKIyv8%CVB>!4|^T5U@%6u@S=4iiCFvUqK*sd2k99;AOxUjSsw`96?9F5Ro z7LvyhS~_!Sf4X~DS1W>L-R@oUPk(~gD`YWKou1S4;bOpA;` z3P|xqC6&@_eMCfI&`#RM`^Gy99t0b1G5o^t0oc!tAvwe)@LxlmPCNoyNw)E)u5z!& zIK(0woxsPsDPsvLTE36i4lw&iU=B7Or9aBnnYbQNQPuO0ChoTl%LdyfSyW;76f**> zn=}=M2ier4w6PZ1ceu+#z#^x@x!E?cryKyrt|n+b>#ONSGRjMkQQS&!DbuayIAr8! zt(F=1p4A6v-8UT+2Qy!F`T{#{zHC_Ro{%+9r@N8WqdC8?PsOJZJPl0plUnp=AWmSp zm5C56{01Nzeq(+OqG5$fpVHd8RS2kF&TOuCYjk0OZNwZxs#A?dKt4A_%oGw-RGd3n zOe+Z)4mSK?uMw;{l&R_K zuQa&VU_2VaJ#I93e51Q&B594TEQzjR3Tl+`G4Y9;FI9h2**0;vXNnItR{v)DUS9*w z0F+mvqt=8eo_;8}4R+;1)wUeez)YCFujU&-$E*oY`TFxwb7o?qt!uDtw6ljr>3+|| z%}30~5`w1BrnPc2hN>V0jH&T}ZT0%c8)&mS=5=OMJ)`+bE!Y@1HEa5uS*sZmW78`+ zHiH+wjFRNYI=~A((#}e$Fh-j5=MPwMPo}2NFRMCn2s;7#UH8+Dkkp2t4fn4ocO?&P;N@_rkwKY~yH z(R%v*oYsFBxw-;vJ!P)(3vClaT_;;z=MaO`W`iSchIz*g3tyxc3hN4sU#OiQNI(BV zt;C;pjdS5;wAt(9W^YH#{(5oYZ*_BR3!o5{P7`TL_j@gCG-sD;w)4GgnH*kb!!V_q zBEMA2bg8_e-bU?j#|lW30&hN-(#ZzzJ%v-WXtGNqwbbX2y;fqq9hn_D=HAXeQ9aZ9 zmLtjCzFS^R62?myxH$%gDg|#%Ws5zy6m$~!gX0ksoMBX7N|Try8ztCeCKHC~{rzOe z!uo$-B*GqcAYQXkps^%rn9f|=C~!Q~m41Yf5wR!B+&iOnk2l4ahBMW%r`YY;!dXzKIkm3nf$>9-Y5edy2pk6~+GI~}Maj{+ z+yR8!7nNChZOeH5-79@xU)fdC^E!pthe)`ZQ7<057C0%?$*X^8?kl zR+0_B+)zj>2{j$sfvA_K$i4|0Wh2{H@Y+nE`UFA63pN67;7kx1cQlOdtio8QnamUG zFYx~))_idNBeC9sN8WdCSRXcpM#*4Ce|juqXBTem|Hh)T*vXT zq3XP_R@D+hLPf&Kb(@box%td?Tj_6$;8!UnV5{xl4@y5y-s5U z9ds0%Lee{IcP-J*OCr zL56Cbm>h5_0i{5JB4Qf^xloZ(3zk|h)vLGt)(KVczWe*$d;WxkoU_;3d+oK?UT6Jx zetn7g<4;Vr5JPf$uD|v5&FoOcN{rCdk?kGo>2)B6Y;(|bq2*_?3mX>%;Kwisg0LMG z)ff|Okab-L#sR|_;~+>lf6N!9)n6qSEkZQ`eeB$2C+t8hQ$cp{(w$XxaG5$ki2A*SnTQ8@}p_lfvKh5 zG<=t?AwT~hp~zz7)v*T{&RqyDt+Tlc|bQ~Yl>f-%K^!x zT+cG-%Je@MP@voy!3xlsD_W`;b}@8iP_dI&InJZMn5@!j%A_G zw|2q?rfCL^lJde4vOKMle=1xAuNwSf#npudzL5Ahl`BqC-jgiR2oa6!M6T zMky#Gx%kla%hy!vlPyfN@R9ss>)4~#l2=rk*8<3fYvdy|MW@Ae2z-sqZ zr!D-8-W##)cut26C7;X1b7JP}JS)l*z#QTmMLQHV?hcAW1Wo%oMEh61_N6@9PpP!m zLqzMXn>eT;|2#%FWEx9fusYXTv^cWU5f)-1FYZp2VkHAz{Y8sDDk{`5$Z@wkZ1%vI6XU-@I`s^n6WULh7^!L-%*1 z7W1yiqrD2GJ>zTtJV|>=r;Rs~e@>*0@wMwxX~TTluZh}+Q?Ub*S;N?qT~Uy|Q{>A= zNC?P6^rQVz&se~crxa!F63bKEh$*GuAF`LcS-!Mr=)`%s^~d>ATyb}DE~nEbx!V71 zq&@$j6m$*F)^$;zi|Qhwy0EE%MK+3VR|h+`;S08D>#WJT*FSr*&T2THsq)T=@Whw# z5yh{I92p4Z*GAggMB1-Iv>CTRx(XD(EwWN9qZkno!r|1kM#Y9OAB?r)T$n3~M9tF4 z4(GUoCmWh+EUnH;Vi5Q5CGHza-=CPZ&o?VMF)N8h1?E;!_nL)HnyF+F+2ohyljR@^MU;DM#ylHwt4jWO%*mH); zOalXpVwsB1oDCG;ko7dJkdw*yQtl&Dg=yF##+b~!1AG#{T@kLAfMXJ zAuX?$`Pz3BvCd%J>txzS7?;p2P0xq%+V8?&dKn!5z%}2iVnIdp_`_cu~4jd30)g9cp7nTu;M1WC0rmU8PR zz9QDRV5x}y8kxf*3FG5PaS`d_ftE~xw$lLX(bV#jyc-+? z;mKgv8%p04T%CrLOG?)gzM>SFqzV|5Ti-cFP&`Wd#a4G^*D#FxN`j>(kxB#e@EDql z#3=|t!vAVw#iio`)EDvgx%LyC6Kx%FS8@{4Ph=2x6QPT7PwtI&H?1 zJ}e^xdVNCUk`~%))5Ib3Neu0kBkgxb!JG8MMXWcNWuW7oiaziSLD~43R4d&)@~yIB z;@IVmoa5F3Fp_cNZUT%X?8&|ECRN9kp4KtQO8lha>oEGp@`;PI>D%5DtI*q^o9JzM z?LA%HXg9OP@u-z9Osse*vTMt|(t+CPJDc1Dkeovzpf+OWRJd|q!E~$g#-uVv2Uhxq zn4L{JQqYQL>;EZ9L&$$t3%G%iUU?Qwyw`Fbbz9zL(ihjSF1p2Cbj!lE*2=Zk>5i7L z#{wO{DcDy>*@aM>z)xDS(G*kxc_AHVv`>do%*w|4#xc5vwEZP%e6oe3fFaL=72xRy ztx&h8Njap-MhX*;^Wota)e5*Nk+@-^t1j8YNx;>}FJe_R`GLQB6tPOv{J?J9K6*wQ zEDeQL^JkF}O;r;YyN>(Ycf@y%2V9A7PAzMy#`v{oaP>NnbnZ~k)LcVe2=8^v6bHPm z8=sEjl5oQKE#Z>nD6buHJCcNw2x-cWBxa6x0BR3z>7%LVQ=A_RTcY)O!avYPD*Pj~ z5ifpAd{l}g4jQQMzaPM*P@7T%`%evQd}@4pW8c6)ZzyA9AHh zS9o}pA8>Lmu`LHrJdoCahX!AMXu!ViK%UWT9V&{jRhq#e7yeH2!lImiuC`f7k!N%z!3VhAtz8$(VE{&yE%OR(#ysnL_YhP#7LjtEck zf_WRj$Rdq$A~zf7AHQX5RBX)F6u)>$Oq5?jWYk{0jBssO`Co}IUnFtnUkm9Sa*cKoL@R## z{LAAB{x8QbPJC;BdHjk^&Psc&9k~4a=yh{2Mq-`6?d_6$k9XVN)vmC;y`5aHSkb&9 zsm@kWV%wi;Rp&X5o3aGo?!DC0{<3PM>)w-lLnDK|?JZ+Hg9E3V#zuM|+ANuveZ-1Bx^sOIXhR9*I?L%*ZNdjpzV;yL38mYh6@!{9`o+s_2XFh&* zx@X|U^q*h@YncC?%2rg(7t)VwbHjoV~r8`$mZbKs6A_vVz$I@Nr{b%@=1z~42g|Q*{YY3rVoyC zTRZ`d()iuSxt4CXzpQoqGWErR&fMcR6V%*| zHDygdxUIQ!eRaz&7aUbJ6W9*wZTwL9&U^U(NVvZn-mq161yWo5+_1en_h+|sL*T`vvGu-{Em;NJ7yQ3@QLh8AlukD zClX}eoH1FhT-o`!rtlMc1%tgf>1U~o`%;YKM}u9xd5h~bV=u^k$jlt8C~hGp-EAnk zFnG7?+&xo|r!@X(Ik{(Qw54EorqK0u@J~X>LBb^IC#tF6JHfh-oAJrk!43}Tfo&Ws z|CCak872NGVtKI8=w!?H`oa(?=agZ~NpE$;;jJANhM++`k`SQ)jJby|G$MuU4pZIz2_ z)eYxjEnyN5jj4_2CoWR8U&dcqdF7G~^|PNRL?ER?E0YXTM36lVwYQ5}zZ!y&Uo8kgx*X|JEBDKkPr-Pq5s{%%Q@*ck|kz!eQmz&c|(q>*Y0%3$^ZEQx-OK%F*Bl zTjx!6evzs$Uui5o!R*im4}>w8i(@c^oz<8iTzyc<^?fBbi9Uj*)%=5-_t%YCO!Q^HP$nv>S-SV6Z|5sK;yz}VHZ0Vh;lCHSa)_@O1Ls^ z9h-jQ4o#>n=2q|5U1Q5EpWflp6bJNdJ@Qvrf{kj@|J|Bt>1p;@V)lc~tgo20cm#IZ zNLfos*pv0AVUB9d&}@oj@rTezcuG1odR^(8Nc2F{BG1I69pO={CHq$INRgl+1v05U z+=b}fkEWtSz7HN1`Vp0N^C(V^;MXd%`>6$uM? zK1R^Z;0)p)qhJzfHbkVL2|~EKnO{asi||_uDI)US&6pHRTMB zJZTz(2h0Vqs{c~*Ns#Cnz}_CZKL1P@WBrDr{?OuwXdd|#Uv?gLcMDGyNhUDuRy&4(%C@^l3bktFot>4%mAP^$8UPF$ zPXy49ZiIcsI-`=#pk}B$1Tk$;rOH%69s=F5hwd0Og_5Y5S{o(?R=ylx`Rn_YZ*o?> zJ+taxmsY*Iv+8}vs(%lx`g8KLzcT2WXYtm0cyqvPl%rl(onKUT|p zSsf~tw?{qOD5w3=n^JAjuzs-2AiT^Vk!^HPVAL^es=}C!NX%cAnQv?2?EaDSecFPN zrUlXIyrgno$Fs#M+>){KrLUWpiblLc@zUkt-ooe%p{Pt4tQ798@CjD>wBkh@9;{0e z#iQqgmCa;vIcTrXbGOw*w0;eRpW;al*^S8^>Zfxt9O&+Hh>=^o3GX1X|a z`R4NQ+g$|J`=O9A(nP={munrvctsZoxAqFXn8q=$g-op56K-{oDF$LJpGRsjjki8{ zK4&ERoTW*0+zv@fGUOOWp%o3C4?AHNHdwN8eiPx|d6rw3cx zRaJODW2ePN4Ydt7+#70Y8*G$ok5Ipp+iPF3YweuKwMTQM_=Ka4UXrz0AQK(|?2p79 zwa>W{=g$?QvLLpOyiz~wk5=JRdO>m2_+`zmT+p82U+q)ZJ%1TS5i+-k(@L5q3r^Ti z$wD=J{(&smV1X>mQ!M5rV=+Hc5lIb5Y>gxpt{mZ>iknt51y5W zXCKeQb9V)0t}~Fy@B(Tx7yXa(rQ>x58S2{bX9P{QC@%87(>OV4rDXu$*>4k>lWDP5J;g#v{mE2@7X|Mj1^lP7PzgDp(G|& z`?uD+9eQ`@`4mrsQ)w5WMvTZ-AP50o-QdR;e(K<70)F1Y#eXiSyYKJ~hV$AMH6nui zoBXK}2jKG$Mtn_H9xDq<^?fi2uR5usWW2z5F-E^K z!NgwLWbXMY#B;-uHirbJ0T_o~`fy3}^HnM@-@_!AX3x^pb<%=$r3NHu$xjV))jG9I zqRoD5)oYP1GsdJv@>*ucS36Xehi({2!Lu=N_qMyla3c+h?<1ll zE^VAn`<<(uz^6P<)qWkQ4O}9LPcCC=zoOILDvnc3c;X@A{!-#Z9?A{A=4-!2w4X!W zUKI0xZ_0tDzSefXDyp(|Ie#rD9m~!6VtG*vdo?k(O4sqYrVc$ zX%=1kLb%cZoX)YD$aOPZZ7zdpg+-R9?wP|fvA}##VAd`{5kjlPup2l!lQss$xS&3V-l1j6Z@=)Zn zP}AHGx#^TQW8|;BEIf#4+4a$sgD62L{QG;dRH$}GA=`9FV*UcK;|INvNQ7SxL>&2^lsU znN46)Y3~s#^h7SfTNE9k{da03(;inFZct$Urqp~u0v0qKfSJWm)jU(HaaszXoKmwM zjQQxW(cc({USu-^f}%emLI0035zVOI<+53;!ORiU8jjV|VK??*^inG*ALFGuIPKyr z$|pNWS6dVJld@98S-~W=3;Cijc{RKzf&XCs)yu3uI#RDOtgOm99T<4iN8Rw$@(VwgarE_9s@M6~zwm$CWq6bw?3r}l zmu2P6W#DtXP4EiL=A(7<7UMDVP_O%e_7;%D25<)7;87Vk}VLhiJ3u2J$MN%BU(-=wWLb`!Vl{zE( zXECgwsYn1^11|NwF>AY&dl{*W<3{tn68OGs^TM!Y}A zlq#u6FR5I8XJXS$}_KWOjvwVe+h)b`S(b!(q3B&^gSEE;B<6&% zQaJG!=!S-;(X%nQdM)oBLaw90S6*1RlW&H>YMfH!2~1p1=rZxmhCKWY;1G!t9Gg-X zNNL~-Lggn*Wrm}|mSFUevdr;CsXmXi-a$kU!*DpH%ae*>K{CO~QLtBDq}brOkKp1c z$d(r?`aCyK(gH;EG}j_lhi5?DQm^G0LSlHDnBuB9;@wRV%;S(S<|29udtP1SauP;t`R{*FnTe{`rY-?L;pxF6g|R@bcTscA|tddJdGrG(QtAe$iOW!dJlK%Z4)c zXYPqSx6+*^Up+Lrs>7_`$!w@$-ouzbLn+hdp(C1DhjD;VJH zH2{rWap8eGl4H?F@Kw>#$x$iHoQ$QX*PX{@1wgrF1Ea5h6O{9f2k~rcwA?zU^H8tA zCN4BgN$bFv4Ln=&qu0{W@}-jzX_J(tjsoeV{BsqH@veqF^qE%L!#PaC>O|aM@JPSV z$B5%Y{O3vaGc3Qt@kJvW7z;dwt8t!pg%Wz4U4N*iu;J{(GU&2yY)={O3=~Fb0oJ{; zx?z@_ZhT^&wax+V2~AJ8)CYKs>EZBnaYbt;e>prh9F1dyDYZf~q<;NI8;gz2f=&Y& z*?A&b`$gk$&y*an%H8cQbDypP3LQY)FnxlZaVjo$)wg`||_36biGDl-Q!GFf~+eKkCu z@_NPvW^O>(Oi!nr$HjOJ6L-@&;Z7Vqd=lfBRS(j;xMsN9w>{imE~zHyrAJ)%qsF)59k-OfJ2f21MVKS16!SmBaKC-i+kHL z1uF*{SE}j{J?;x?lQ(o0-)*}V&o~_ih+wbhh+jmnthsVxgW{1k>OyE`5=ugULpQ&V)a@6~o8AhOT|?E> znX3Od@VC;B?6WDwQ+sXneR`1_+_|m z!^XZdYd-uLyyo=Ar_+Dp*{P@xICS2HkxFN%&BZRQl`jLJ?u!;9#yaDV+jjt$Pov+5 zIc_^8-15mxEDz=xwoDgA1*Axb`;#jkIY6M8)$6eyRr~Rgo>ui40q8YaW|zkDt7!hR zFFy8K`a{?Trs+oG-i@c3W@}*OJni0imiZLVE=6l|PMxjbr`@xV)e5wBUXpg8Ji;G< z^4|;&e+{kCRXG;J8i=0ZCW$*@6H?R^$!o{11lV=(Q6}F*AY{dS^p}OwEJNYc?jH;Z zM&92T@>~n6LU;mF9E|6@sLlz3#EfeHw!NB2c$1=w#JQJ5uFL*MPR1v%pr_UNMe%=$mrSsES6T9(DdnbEMwvS+L4 zy!?smO=y6BG=R!>oxxf)+?x&V*FPa!)f9+VF(zj(fGMOii^3qpNZ2xqYmxS%(<*x8 z4AVL=zr!?P#lTHY4CPSxy1 z(h6)Ig-B!VBhsEGReq~F=r|a`?YkE$? z7)Ihu>LKP9%xGM1yeZUVV_;E{ieMR3k_j15U*n-?tL=X}XFvYR{?%%SH?N;5^ zJJ~clIaoR`Ot*FRc;+ne;zcWX+noh@uVruoA~bYkaTsH5QCR3kW5D3(Heb>LTeZT& zlr5E&5MakI`(a8WWR!^L8B$dr4Z0hU z+g4cE;D;h3i0`*zBOx`Kzhz6JByx)+#mNQg;|V5rVMk6MChpL4O zopsFR0PL)nuV1abQ_HI5y4~VR0o~uQxWRS2?o*SgoVQT?ju+PosHJ!kQz6@IhpT^S(nm1;^>4Q`dIZ{zrZJ|K7MPH z-KCY|B0BzB5zBO5jo_vnt}?FG$@1juL(Te&Sqy7OflB(POrjq~s`OUdEp6#j(CH z3)^Pjx+6Rs#jK*JgqW1AC@I-vQVSFRbVj4JKP0pybVD(7(;748CKJ<*8;Zd{Fkg%Y z!#*@+h3+cTpm^P=A*TiCN_2FvYsl_`dZq9EFBctgXM`>}f}We0K1iVk3TADUC*Ww^ ztJsmqW=F#9M;>46Eq%6TsUE&_4lFIV?!Af?9xKo(`}q-Lmvo4J;y}3?QNSm^JVNui zY1{z(qhfIE@0s&^=W-ZkuK2p^?OHfn4}6_cx0?sFt1gY7`cD`)Cg;|4)~t zu*m13@@uQOi!W3!K35M%xNg)yKYNx1gu>oLRBQP;;L3uW0P6*DApHF*FGJXG)%`~! z^WS+JySHe$ncF3`lI$Kh7dOz-espq3Iye9!1$2=X)~_bg9M!t47NIBPK#$XWmxkI! z^{xO(g{wUwA(DBihb8j0hcu@P^2Ot12*tFC++4^R&jcpx?i$KVM=iG^UqP{4K}lxX z+9oj%Sb`Bf$lJG5V6-;9lm2FI_3DmfG)Y^&?`UdiKi>^w?jBUNLQlvG??F$Tr$_DL zYT4lG>Rwk}n$2!GW!+9ePPDvqk*gpav4@R9%XkN zgOfh`LZfJu`N2U1QVT5h)<9=32-v7Gr1#tNM@9h6qxSf~#W0ItwVG^;I}fqi5LHmT z*0{evRDJg6#Kt1VMq>!t)>&G@G_L^KV6>q) zeBTV;){H=3dFU9xg3JWpto@`M4r#p6a4~u+Ks7jWUbOyDki6||;X@@PPLA7ha&jP| z!x2v70Q!@%1vlZc;BIH7n#1#T-M8jYbEmJH1keYR3#4xvQD8T>txbNSQr?hT2&;^@ zjXI4(KVU^>_WfLwWnwkt6@oFZ%Y28<@6=ct9vc^%5G6@kBZ*Ipi%Mc6ocY5!|d`(2?=;Yh>RlRa)eqclWFm;R(D438AXR0y|w`|L{b0YrD87kbC#^AIKhSHO?;qWd#5hd=X< zO`D|csA03_ngmE<69U)hWjHowX*Mwinll@VSUEB{mfKQl&LaiXNgTV!3Ic5k*Tx3U zjVKH~(pB*IhqY*kM~~#eGrWX4CQ0KGe&-4pQrx~G7JdxgrSFCP|H^Cs>H_~7m;3p4 zox0V6t#dboJ4O9-xdCTSFgPy*2PcH_Kf~vVvCZMC9-F7D=U?tA^>3N~yeE@?ibuUx zzoHQ@F{_4W{uRul%bezJUX9ygVZi}-oeAt&KfB&K1u?>V_q&F?E(9Td{L9prnXW zCkgRW>J$f`f1pmGb=B+Bankyy2{-yDb~oSMoURmexeWMHkeJ*3oO<=!&Fb&VeEPMV z@$6H$t92O~c~)Owsz?p*!*`~(eSOGOEP#R{ag`KJcu+x!pgsV;H0zUjIR%rn#Y)#h{h?OGFgzcb?wk zcoCjVh!mwOO)=IYOdV!(8V0ksE@R6LJf^;Gab$q5RIb(b4OXx;dMNLp9cv^aiw1vs zEv>`DI3?C!m=opZ#3p{0?BGFD{ez|?oLS~?Z+8a1*~y}&Fb*>g9%ks5nvyIDnn;?s zbcFd;8S~b^O&r7X5EhBxf3M8sRvGiE)+d+m7ISA`#&5i-LCW6~LppTk*j)#hmHz?j CJlqHX diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant index 77bb34183936f274b4c8c2928fa299896c948bb7..7a90c7f3527ed732e34b54009bc1b661365655d5 100644 GIT binary patch delta 16 XcmX@ha+YO-D-%bZZdTV91_lNIGC~D4 delta 16 XcmX@ha+YO-D-%cUobJ8)3=9kaGxP;A diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_vulkan_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_vulkan_0.azshadervariant index 117f993f2808b36d1ebb8e9992312f0123a4bb29..4cbb76954dbaef688dfb2961b893a2156f11785a 100644 GIT binary patch delta 2089 zcmZ9NU1(HC6vt=o-Fx?LjGNeQ-0W`lBQ7?rA)hLW8VyqX0MW#xmO^pa>KZKBG$c}J z1y_(35&UT9LFhxJ2(9fyD_rP9wIzrks7R|IwhygTs1Jhag9TeG^#7l|cRS|5nVIuD zbMDNX`M4j<$&W6}i(91kD6#n7ons$gQ9I?9?9w-Fs~8nR3L)ZRGfK)5VUhSh%WA}N zL`*p9(|pl??A~)^(!bWc&-M?rUa(azk&|gPl&EA2A|l!mX+a~(?(d9RhF0{YW?Yp|{bLj2O@oT3YdQaq7{-)c%=yso*)G3QHWiqPf z-8{;cXgA7uf#teFK82L)Je5k*<^84dp}|!`Fwvem7wycrXbExXz3EEt;Qro&)$&9I zw!@XGuM5e_B3L8k+1as~iBh#R_0CMSJPD+GG^5s$v*qgaWM!t#J+T;#FlNWWsY-cf ztkHpAj)!sKi2gr?v(6hH@G>Yjb}Ob#yAzrW>?YLo^8nFLn|=yyPSy0&reCV-FXdIN z>v)Z+pcLzs*oI}0@rz_!P{=q7vQ~rH0ZSN+N09w^BpJ&CLm{IWtfmL6e=ySM=op>C zi3~4boTM4Yer8-a*`r1r+4FI=dT!0Ya7A-QAldVQxL9CjT)1kcE?gnm!Z@-<9LCoM zQ!{J?vctkavPK}xIilj#TBij&~_@$NCFGl$$WyDvjK3}x4xNaIEPwZEiaAHLWd zKoPI^F@-lLrrsJTzA^+tVe-@PGm-4Qkq|Po1=2uD6}~qcZU+%+!;z}b5|&|H={1^5=JyX(%w_5S(?1Dy0FCC!BO_RJ59*uHUFws)c{!@S+ncHF4*2ImAI6U2 z#&8G6;G>@svhjf76gSvw0b|z@jK@9L1B3DGPyZ-%BMuAiB7Oe~Dc0gC9xr|A9qD=d I#1ruU0N-NYxBvhE delta 2557 zcmb7_U1(fI6vyZ8?%nPt*`)18vwQa=O_nxFXtwpcv1wx^X(COtag#I;4ckq#i7T6J z*aRCXax3DKP?32k)USs^Di&hpf)CniUVN$)LGZx`D~ca4MZqc}QvCmC?~Ow!r~@;1 z&+nZ7%-lI=?!I=_czNBpGH8VIBQN!i%}n2sM~%UOwj+LDW{VJp5TaQe!pOEw_!Qyu zgH|CLL`dXwlZAn)@xp9r>13_ExO}QsC|74oE9L6E^S-eVu!ABZ0uaa0C(EVN`PzJ8 z0pZKVa%H5rT&k6emEqaph2nha$x;G;Zq8~Uj zyITgv^)sK6>3E`>r_9rS0P24^ZMi>Q@CQXu-blB_kvg&b{9>tRskpFMQD=%*Zx$i> zR{T*j1h0@^TZsq~P%E$Sz{Bv3`Z7jH?y|Zt9<{nuTtL3nw%9|X5j^uB6xd{+IwX?EG% zDbH0aoKthKSyc4>-=d=CzZ4bYko>g1u&P+Ms&JTL5td)3GDcYbnQF&qrMoc>s_~N` z$<1J!(IDSVXN*RblqO7?D=sa0H(+u38O*aqMC2XhI)wE6<3CcamWs7}J$uef`+3uD zfV&f&HFX&EMY{t%>Drv0e%@L7Y17X}o3*L?Y18k;b9voQn|^maxw7-c=`d_IUJ5o| z9x~2B#x*@g9obfm`CW#x-iYHxXIxCa-qLR42ad#31yq*FOmxo7%y_HyZ(^HujMH`A zj?QX2GEHZz1qgMax9xRJNTvyuj!f5iuf`pFnBdhD|`Ww>Vne=Nyvdu!Wy0ESb zy1KKPj%>4zOxMxR_10}o$fG9wTw_c&**6+vA(H)~u|}8O))AgR1nsHpNpsZyx6Z@fHW8(NX)Q4vp z-H&eJoR~oV=^Vh5jdmI%^K~COKN4Q&>S>X}2Y;=nu+z&Zy_}J=9K;i^p=z3YXq3CM znQ%V{Tccddo;SIJKKaz1AMp<_#N)1twLm59emt3THqU0h*=TdGOf?&Az9ZAj=Gja! zn`bkceM@2B-6p>vi8d@I~bBk6nc8!oKhJ za?>B7bAdigM*Au{7og1pyoSyVD!;SV`$fn0bGSA4de4ehd9)^xrTm#d$ZHJ}T)O!^BL%IBfdaJT~Dn+>s47=`x1qFfUVg3FindShaderInputConstantIndex(Name("m_modelToWorld")); - AZ::Matrix3x4 modelToWorld = AZ::Matrix3x4::CreateFromTransform(m_transform) * AZ::Matrix3x4::CreateScale(m_extents); + AZ::Matrix3x4 modelToWorld = AZ::Matrix3x4::CreateFromTransform(m_transform) * AZ::Matrix3x4::CreateScale(m_renderExtents); m_renderObjectSrg->SetConstant(constantIndex, modelToWorld); constantIndex = srgLayout->FindShaderInputConstantIndex(Name("m_modelToWorldInverse")); - AZ::Matrix3x4 modelToWorldInverse = AZ::Matrix3x4::CreateFromTransform(m_transform).GetInverseFull(); + AZ::Matrix3x4 modelToWorldInverse = modelToWorld.GetInverseFull(); m_renderObjectSrg->SetConstant(constantIndex, modelToWorldInverse); constantIndex = srgLayout->FindShaderInputConstantIndex(Name("m_obbHalfLengths")); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h index 6c3017fe33..a828fe4b96 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h @@ -183,11 +183,14 @@ namespace AZ // extents of the probe grid AZ::Vector3 m_extents = AZ::Vector3(0.0f, 0.0f, 0.0f); + // expanded extents for rendering the volume + AZ::Vector3 m_renderExtents = AZ::Vector3(0.0f, 0.0f, 0.0f); + // probe grid OBB (world space), built from transform and extents AZ::Obb m_obbWs; // per-axis spacing of probes in the grid - AZ::Vector3 m_probeSpacing; + AZ::Vector3 m_probeSpacing = AZ::Vector3(0.0f, 0.0f, 0.0f); // per-axis number of probes in the grid uint32_t m_probeCountX = 0; From ada7c41a34031b3d50807d7f86b0bc50cce66b83 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Wed, 15 Dec 2021 19:18:24 -0800 Subject: [PATCH 082/272] feature: add Exception Handler support for unix REF: https://github.com/o3de/o3de/issues/5886 Signed-off-by: Michael Pollind --- .../UnixLike/AzCore/Debug/Trace_UnixLike.cpp | 155 ++++++++++++------ Code/Legacy/CrySystem/SystemInit.cpp | 42 ----- 2 files changed, 105 insertions(+), 92 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp index 92a80b0d9a..b0ee4ea1e3 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp @@ -6,74 +6,129 @@ * */ +#include #include #include #include +#include #include #include -namespace AZ::Debug::Platform +namespace AZ::Debug { #if defined(AZ_ENABLE_DEBUG_TOOLS) - bool performDebuggerDetection() + void ExceptionHandler(int signal); +#endif + + constexpr int MaxMessageLength = 4096; + constexpr int MaxStackLines = 100; + + namespace Platform { - AZ::IO::SystemFile processStatusFile; - if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY)) +#if defined(AZ_ENABLE_DEBUG_TOOLS) + bool performDebuggerDetection() { - return false; - } - - char buffer[4096]; - AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer); - - const AZStd::string_view processStatusView(buffer, buffer + numRead); - constexpr AZStd::string_view tracerPidString = "TracerPid:"; - const size_t tracerPidOffset = processStatusView.find(tracerPidString); - if (tracerPidOffset == AZStd::string_view::npos) - { - return false; - } - for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i) - { - if (!::isspace(processStatusView[i])) + AZ::IO::SystemFile processStatusFile; + if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY)) { - return processStatusView[i] != '0'; + return false; + } + + char buffer[4096]; + AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer); + + const AZStd::string_view processStatusView(buffer, buffer + numRead); + constexpr AZStd::string_view tracerPidString = "TracerPid:"; + const size_t tracerPidOffset = processStatusView.find(tracerPidString); + if (tracerPidOffset == AZStd::string_view::npos) + { + return false; + } + for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i) + { + if (!::isspace(processStatusView[i])) + { + return processStatusView[i] != '0'; + } + } + return false; + } + + bool IsDebuggerPresent() + { + static bool s_detectionPerformed = false; + static bool s_debuggerDetected = false; + if (!s_detectionPerformed) + { + s_debuggerDetected = performDebuggerDetection(); + s_detectionPerformed = true; + } + return s_debuggerDetected; + } + + bool AttachDebugger() + { + // Not supported yet + AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet"); + return false; + } + + void SignalHandler(int handler) + { + } + + void HandleExceptions(bool isEnabled) + { + if (isEnabled) + { + signal(SIGSEGV, ExceptionHandler); + signal(SIGTRAP, ExceptionHandler); + signal(SIGILL, ExceptionHandler); + } + else + { + signal(SIGSEGV, SIG_DFL); + signal(SIGTRAP, SIG_DFL); + signal(SIGILL, SIG_DFL); } } - return false; - } - bool IsDebuggerPresent() - { - static bool s_detectionPerformed = false; - static bool s_debuggerDetected = false; - if (!s_detectionPerformed) + void DebugBreak() { - s_debuggerDetected = performDebuggerDetection(); - s_detectionPerformed = true; + raise(SIGINT); } - return s_debuggerDetected; - } - - bool AttachDebugger() - { - // Not supported yet - AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet"); - return false; - } - - void HandleExceptions(bool) - {} - - void DebugBreak() - { - raise(SIGINT); - } #endif // AZ_ENABLE_DEBUG_TOOLS - void Terminate(int exitCode) + void Terminate(int exitCode) + { + _exit(exitCode); + } + } // namespace Platform + +#if defined(AZ_ENABLE_DEBUG_TOOLS) + void ExceptionHandler(int signal) { - _exit(exitCode); + char message[MaxMessageLength]; + Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); + azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal)); + Debug::Trace::Instance().Output(nullptr, message); + + void* buffers[MaxStackLines]; + int numberBacktraceStrings = backtrace(buffers, MaxStackLines); + char** backtraceResults = backtrace_symbols(buffers, numberBacktraceStrings); + if (backtraceResults == nullptr) + { + Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); + return; + } + for (int j = 0; j < numberBacktraceStrings; j++) + { + Debug::Trace::Instance().Output(nullptr, backtraceResults[j]); + } + + Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); } -} // namespace AZ::Debug::Platform +#endif + +} // namespace AZ::Debug diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index 09bbc3773a..f3f9442322 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -115,43 +115,6 @@ extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExce #include AZ_RESTRICTED_FILE(SystemInit_cpp) #endif -#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER - -#include -#include -void CryEngineSignalHandler(int signal) -{ - char resolvedPath[_MAX_PATH]; - - // it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir) - if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath("@log@/crash.log", resolvedPath, _MAX_PATH)) - { - fprintf(stderr, "Crash Signal Handler - logged to %s\n", resolvedPath); - FILE* file = fopen(resolvedPath, "a"); - if (file) - { - char sTime[128]; - time_t ltime; - time(<ime); - struct tm* today = localtime(<ime); - strftime(sTime, 40, "<%Y-%m-%d %H:%M:%S> ", today); - fprintf(file, "%s: Error: signal %s:\n", sTime, strsignal(signal)); - fflush(file); - void* array[100]; - int s = backtrace(array, 100); - backtrace_symbols_fd(array, s, fileno(file)); - fclose(file); - CryLogAlways("Successfully recorded crash file: '%s'", resolvedPath); - abort(); - } - } - - CryLogAlways("Could not record crash file..."); - abort(); -} - -#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER - ////////////////////////////////////////////////////////////////////////// #define DEFAULT_LOG_FILENAME "@log@/Log.txt" @@ -697,11 +660,6 @@ public: ///////////////////////////////////////////////////////////////////////////////// bool CSystem::Init(const SSystemInitParams& startupParams) { -#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER - signal(SIGSEGV, CryEngineSignalHandler); - signal(SIGTRAP, CryEngineSignalHandler); - signal(SIGILL, CryEngineSignalHandler); -#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER // Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the // global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is From 833598d68fc737c82982b85608be387ad9922886 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Thu, 16 Dec 2021 20:30:56 -0800 Subject: [PATCH 083/272] chore: remove signal handler Signed-off-by: Michael Pollind --- .../AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h | 1 - .../Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h | 1 - Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h | 1 - .../AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h | 1 - Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h | 1 - 5 files changed, 5 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h b/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h index e8efce1133..e99f29e051 100644 --- a/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h +++ b/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h @@ -98,7 +98,6 @@ #define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN)); #define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0 #define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1 -#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0 #define AZ_TRAIT_USE_POSIX_STRERROR_R 1 #define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0 #define AZ_TRAIT_USE_WINDOWS_FILE_API 0 diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h b/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h index 59d5f3c5ed..e5e52995a1 100644 --- a/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h +++ b/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h @@ -98,7 +98,6 @@ #define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN)); #define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0 #define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0 -#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1 #define AZ_TRAIT_USE_POSIX_STRERROR_R 1 #define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0 #define AZ_TRAIT_USE_WINDOWS_FILE_API 0 diff --git a/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h b/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h index 1a3d0663e1..9a6c76fe2d 100644 --- a/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h +++ b/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h @@ -98,7 +98,6 @@ #define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN)); #define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0 #define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0 -#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1 #define AZ_TRAIT_USE_POSIX_STRERROR_R 1 #define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0 #define AZ_TRAIT_USE_WINDOWS_FILE_API 0 diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h b/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h index 1a83aba267..71d6b395c5 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h @@ -98,7 +98,6 @@ #define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE #define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1 #define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0 -#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0 #define AZ_TRAIT_USE_POSIX_STRERROR_R 0 #define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1 #define AZ_TRAIT_USE_WINDOWS_FILE_API 1 diff --git a/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h b/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h index 7a75af71fb..11a0ba84e0 100644 --- a/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h +++ b/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h @@ -99,7 +99,6 @@ #define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN)); #define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0 #define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0 -#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1 #define AZ_TRAIT_USE_POSIX_STRERROR_R 1 #define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0 #define AZ_TRAIT_USE_WINDOWS_FILE_API 0 From 21850aa73ea90c6846f2b47903d5ac1b6b916b05 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Thu, 23 Dec 2021 15:09:29 -0800 Subject: [PATCH 084/272] chore: replace stack trace logic with StackRecorder Signed-off-by: Michael Pollind --- .../UnixLike/AzCore/Debug/Trace_UnixLike.cpp | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp index b0ee4ea1e3..67de4a3219 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp @@ -9,11 +9,9 @@ #include #include #include +#include -#include -#include #include -#include namespace AZ::Debug { @@ -114,19 +112,15 @@ namespace AZ::Debug azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal)); Debug::Trace::Instance().Output(nullptr, message); - void* buffers[MaxStackLines]; - int numberBacktraceStrings = backtrace(buffers, MaxStackLines); - char** backtraceResults = backtrace_symbols(buffers, numberBacktraceStrings); - if (backtraceResults == nullptr) - { - Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); - return; + StackFrame frames[MaxStackLines]; + SymbolStorage::StackLine stackLines[MaxStackLines]; + SymbolStorage decoder; + const unsigned int numberOfFrames = StackRecorder::Record(frames, MaxStackLines); + decoder.DecodeFrames(frames, numberOfFrames, stackLines); + for(int i = 0; i < numberOfFrames; ++i) { + azsnprintf(message, MaxMessageLength, "%s \n", stackLines[i]); + Debug::Trace::Instance().Output(nullptr, message); } - for (int j = 0; j < numberBacktraceStrings; j++) - { - Debug::Trace::Instance().Output(nullptr, backtraceResults[j]); - } - Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); } #endif From 39c09ba6f70fade423993b8d120b3fa66527ff60 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Tue, 4 Jan 2022 21:10:56 -0800 Subject: [PATCH 085/272] chore: correct formatting and address comments Signed-off-by: Michael Pollind --- .../UnixLike/AzCore/Debug/Trace_UnixLike.cpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp index 67de4a3219..e1f1a0f801 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp @@ -6,10 +6,10 @@ * */ +#include #include #include #include -#include #include @@ -33,7 +33,7 @@ namespace AZ::Debug return false; } - char buffer[4096]; + char buffer[MaxMessageLength]; AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer); const AZStd::string_view processStatusView(buffer, buffer + numRead); @@ -72,10 +72,6 @@ namespace AZ::Debug return false; } - void SignalHandler(int handler) - { - } - void HandleExceptions(bool isEnabled) { if (isEnabled) @@ -108,20 +104,22 @@ namespace AZ::Debug void ExceptionHandler(int signal) { char message[MaxMessageLength]; - Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); + // Trace::RawOutput + Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n"); azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal)); - Debug::Trace::Instance().Output(nullptr, message); + Debug::Trace::Instance().RawOutput(nullptr, message); StackFrame frames[MaxStackLines]; SymbolStorage::StackLine stackLines[MaxStackLines]; SymbolStorage decoder; const unsigned int numberOfFrames = StackRecorder::Record(frames, MaxStackLines); - decoder.DecodeFrames(frames, numberOfFrames, stackLines); - for(int i = 0; i < numberOfFrames; ++i) { + decoder.DecodeFrames(frames, numberOfFrames, stackLines); + for (int i = 0; i < numberOfFrames; ++i) + { azsnprintf(message, MaxMessageLength, "%s \n", stackLines[i]); - Debug::Trace::Instance().Output(nullptr, message); + Debug::Trace::Instance().RawOutput(nullptr, message); } - Debug::Trace::Instance().Output(nullptr, "==================================================================\n"); + Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n"); } #endif From 66985e3569c13ab7b640ef31667e25b18bccd668 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Thu, 6 Jan 2022 09:26:16 +0000 Subject: [PATCH 086/272] Updates to ViewportTitleDlg to better expose grid snapping visualization (#6700) * updates to ViewportTitleDlg to better expose grid snapping visualization Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * small typo fix Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add escape handling for widget to be more consistent with other QMenu behavior Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * remove unneeded [[maybe_unused]] Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- Code/Editor/ViewportTitleDlg.cpp | 117 ++++++++++++++++++++++--------- Code/Editor/ViewportTitleDlg.h | 11 +-- 2 files changed, 88 insertions(+), 40 deletions(-) diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp index 888089fd72..90aa044d25 100644 --- a/Code/Editor/ViewportTitleDlg.cpp +++ b/Code/Editor/ViewportTitleDlg.cpp @@ -14,6 +14,7 @@ #include "ViewportTitleDlg.h" // Qt +#include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include @@ -51,6 +53,8 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING #endif //! defined(Q_MOC_RUN) +static constexpr int MiniumOverflowMenuWidth = 200; + // CViewportTitleDlg dialog namespace @@ -257,21 +261,56 @@ void CViewportTitleDlg::SetupHelpersButton() void CViewportTitleDlg::SetupOverflowMenu() { - // Setup the overflow menu - QMenu* overFlowMenu = new QMenu(this); + // simple override of QMenu that does not respond to keyboard events + // note: this prevents the menu from being prematurely closed + class IgnoreKeyboardMenu : public QMenu + { + public: + IgnoreKeyboardMenu(QWidget *parent = nullptr) : QMenu(parent) + { + } - m_audioMuteAction = new QAction("Mute Audio", overFlowMenu); + private: + void keyPressEvent(QKeyEvent* event) override + { + // regular escape key handling + if (event->key() == Qt::Key_Escape) + { + QMenu::keyPressEvent(event); + } + } + }; + + // setup the overflow menu + auto* overflowMenu = new IgnoreKeyboardMenu(this); + overflowMenu->setMinimumWidth(MiniumOverflowMenuWidth); + + m_audioMuteAction = new QAction("Mute Audio", overflowMenu); connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio); - overFlowMenu->addAction(m_audioMuteAction); + overflowMenu->addAction(m_audioMuteAction); - overFlowMenu->addSeparator(); + overflowMenu->addSeparator(); - m_enableGridSnappingAction = new QAction("Enable Grid Snapping", overFlowMenu); - connect(m_enableGridSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnGridSnappingToggled); - m_enableGridSnappingAction->setCheckable(true); - overFlowMenu->addAction(m_enableGridSnappingAction); + m_enableGridSnappingCheckBox = new QCheckBox("Enable Grid Snapping", overflowMenu); + AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableGridSnappingCheckBox); + auto gridSnappingWidgetAction = new QWidgetAction(overflowMenu); + gridSnappingWidgetAction->setDefaultWidget(m_enableGridSnappingCheckBox); + connect(m_enableGridSnappingCheckBox, &QCheckBox::stateChanged, this, &CViewportTitleDlg::OnGridSnappingToggled); + overflowMenu->addAction(gridSnappingWidgetAction); - m_gridSizeActionWidget = new QWidgetAction(overFlowMenu); + m_enableGridVisualizationCheckBox = new QCheckBox("Show Grid", overflowMenu); + AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableGridVisualizationCheckBox); + auto gridVisualizationWidgetAction = new QWidgetAction(overflowMenu); + gridVisualizationWidgetAction->setDefaultWidget(m_enableGridVisualizationCheckBox); + connect( + m_enableGridVisualizationCheckBox, &QCheckBox::stateChanged, + [](const int state) + { + SandboxEditor::SetShowingGrid(state == Qt::Checked); + }); + overflowMenu->addAction(gridVisualizationWidgetAction); + + m_gridSizeActionWidget = new QWidgetAction(overflowMenu); m_gridSpinBox = new AzQtComponents::DoubleSpinBox(); m_gridSpinBox->setValue(SandboxEditor::GridSnappingSize()); m_gridSpinBox->setMinimum(1e-2f); @@ -281,31 +320,33 @@ void CViewportTitleDlg::SetupOverflowMenu() m_gridSpinBox, QOverload::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &CViewportTitleDlg::OnGridSpinBoxChanged); 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); - connect(m_enableAngleSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnAngleSnappingToggled); - m_enableAngleSnappingAction->setCheckable(true); - overFlowMenu->addAction(m_enableAngleSnappingAction); + m_enableAngleSnappingCheckBox = new QCheckBox("Enable Angle Snapping", overflowMenu); + AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableAngleSnappingCheckBox); + auto angleSnappingWidgetAction = new QWidgetAction(overflowMenu); + angleSnappingWidgetAction->setDefaultWidget(m_enableAngleSnappingCheckBox); + connect(m_enableAngleSnappingCheckBox, &QCheckBox::stateChanged, this, &CViewportTitleDlg::OnAngleSnappingToggled); + overflowMenu->addAction(angleSnappingWidgetAction); - m_angleSizeActionWidget = new QWidgetAction(overFlowMenu); + m_angleSizeActionWidget = new QWidgetAction(overflowMenu); m_angleSpinBox = new AzQtComponents::DoubleSpinBox(); m_angleSpinBox->setValue(SandboxEditor::AngleSnappingSize()); m_angleSpinBox->setMinimum(1e-2f); - m_angleSpinBox->setToolTip(tr("Angle Snapping")); + m_angleSpinBox->setToolTip(tr("Angle size")); QObject::connect( m_angleSpinBox, QOverload::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &CViewportTitleDlg::OnAngleSpinBoxChanged); 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); - connect(overFlowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState); + connect(overflowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState); UpdateMuteActionText(); } @@ -982,43 +1023,49 @@ void CViewportTitleDlg::CheckForCameraSpeedUpdate() } } -void CViewportTitleDlg::OnGridSnappingToggled() +void CViewportTitleDlg::OnGridSnappingToggled(const int state) { - m_gridSizeActionWidget->setEnabled(m_enableGridSnappingAction->isChecked()); + m_gridSizeActionWidget->setEnabled(state == Qt::Checked); + m_enableGridVisualizationCheckBox->setEnabled(state == Qt::Checked); MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->trigger(); } -void CViewportTitleDlg::OnAngleSnappingToggled() +void CViewportTitleDlg::OnAngleSnappingToggled(const int state) { - m_angleSizeActionWidget->setEnabled(m_enableAngleSnappingAction->isChecked()); + m_angleSizeActionWidget->setEnabled(state == Qt::Checked); MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->trigger(); } -void CViewportTitleDlg::OnGridSpinBoxChanged(double value) +void CViewportTitleDlg::OnGridSpinBoxChanged(const double value) { - SandboxEditor::SetGridSnappingSize(static_cast(value)); + SandboxEditor::SetGridSnappingSize(aznumeric_cast(value)); } -void CViewportTitleDlg::OnAngleSpinBoxChanged(double value) +void CViewportTitleDlg::OnAngleSpinBoxChanged(const double value) { - SandboxEditor::SetAngleSnappingSize(static_cast(value)); + SandboxEditor::SetAngleSnappingSize(aznumeric_cast(value)); } 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); - m_enableGridSnappingAction->setChecked(gridSnappingActive); + QSignalBlocker signalBlocker(m_enableGridSnappingCheckBox); + m_enableGridSnappingCheckBox->setChecked(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); - m_enableAngleSnappingAction->setChecked(angleSnappingActive); + QSignalBlocker signalBlocker(m_enableAngleSnappingCheckBox); + m_enableAngleSnappingCheckBox->setChecked(angleSnappingActive); } m_angleSizeActionWidget->setEnabled(angleSnappingActive); + + { + QSignalBlocker signalBlocker(m_enableGridVisualizationCheckBox); + m_enableGridVisualizationCheckBox->setChecked(SandboxEditor::ShowingGrid()); + } } namespace diff --git a/Code/Editor/ViewportTitleDlg.h b/Code/Editor/ViewportTitleDlg.h index ba3dba858a..b8da7f20ea 100644 --- a/Code/Editor/ViewportTitleDlg.h +++ b/Code/Editor/ViewportTitleDlg.h @@ -140,8 +140,8 @@ protected: void CheckForCameraSpeedUpdate(); - void OnGridSnappingToggled(); - void OnAngleSnappingToggled(); + void OnGridSnappingToggled(int state); + void OnAngleSnappingToggled(int state); void OnGridSpinBoxChanged(double value); void OnAngleSpinBoxChanged(double value); @@ -160,8 +160,9 @@ protected: QAction* m_fullInformationAction = nullptr; QAction* m_compactInformationAction = nullptr; QAction* m_audioMuteAction = nullptr; - QAction* m_enableGridSnappingAction = nullptr; - QAction* m_enableAngleSnappingAction = nullptr; + QCheckBox* m_enableGridSnappingCheckBox = nullptr; + QCheckBox* m_enableGridVisualizationCheckBox = nullptr; + QCheckBox* m_enableAngleSnappingCheckBox = nullptr; QComboBox* m_cameraSpeed = nullptr; AzQtComponents::DoubleSpinBox* m_gridSpinBox = nullptr; AzQtComponents::DoubleSpinBox* m_angleSpinBox = nullptr; @@ -175,7 +176,7 @@ protected: namespace AzToolsFramework { - //! A component to reflect scriptable commands for the Editor + //! A component to reflect scriptable commands for the Editor. class ViewportTitleDlgPythonFuncsHandler : public AZ::Component { From dae82b38586bcb07eff683c432c662d03bfe902a Mon Sep 17 00:00:00 2001 From: "T.J. McGrath-Daly" Date: Fri, 16 Jul 2021 16:15:23 +0800 Subject: [PATCH 087/272] Fix: only files can be selected Signed-off-by: T.J. McGrath-Daly --- .../AssetImporter/AssetImporterManager/AssetImporterManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp index baa287e47f..73c3d6f9ed 100644 --- a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp +++ b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp @@ -191,6 +191,7 @@ void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLin fileDialog.setViewMode(QFileDialog::List); fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal); fileDialog.setWindowTitle(tr("Select import destination")); + fileDialog.setFileMode(QFileDialog::Directory); QSettings settings; QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString(); From 14661af13f51028a5e92ed32ff59c01df2f1ebcd Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Thu, 6 Jan 2022 09:19:42 -0600 Subject: [PATCH 088/272] Terrain/mbalfour/misc bugfixes (#6712) * Bumped up terrain world limit to allow up to (and including) 4096 x 4096. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed loop calculations to handle floating-point math better. By looping on floating-point values, query resolutions of unstable values like "0.200000007" would sometimes cause the loop to go one more time than it should. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Components/TerrainWorldComponent.cpp | 4 +-- .../TerrainWorldDebuggerComponent.cpp | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp index 8d6bf8e4b0..8b612b86ce 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp @@ -139,8 +139,8 @@ namespace Terrain AZ::Outcome TerrainWorldConfig::DetermineMessage(float numSamples) { - const float maximumSamplesAllowed = 8.0f * 1024.0f * 1024.0f; - if (numSamples < maximumSamplesAllowed) + const float maximumSamplesAllowed = 16.0f * 1024.0f * 1024.0f; + if (numSamples <= maximumSamplesAllowed) { return AZ::Success(); } diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp index 8daccd7d61..f3e0d59537 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -339,17 +339,17 @@ namespace Terrain AZ::Aabb region = sector.m_aabb; region.SetMax(region.GetMax() + AZ::Vector3(gridResolution.GetX(), gridResolution.GetY(), 0.0f)); + // We need 4 vertices for each grid point in our sector to hold the _| shape. + const size_t numSamplesX = aznumeric_cast(ceil(region.GetExtents().GetX() / gridResolution.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(region.GetExtents().GetY() / gridResolution.GetY())); + sector.m_lineVertices.clear(); + sector.m_lineVertices.reserve(numSamplesX * numSamplesY * 4); + // This keeps track of the height from the previous point for the _ line. float previousHeight = 0.0f; // This keeps track of the heights from the previous row for the | line. - AZStd::vector rowHeights(aznumeric_cast(ceil(region.GetExtents().GetX() / gridResolution.GetX()))); - - // We need 4 vertices for each grid point in our sector to hold the _| shape. - const uint32_t numSamplesX = static_cast((region.GetMax().GetX() - region.GetMin().GetX()) / gridResolution.GetX()); - const uint32_t numSamplesY = static_cast((region.GetMax().GetY() - region.GetMin().GetY()) / gridResolution.GetY()); - sector.m_lineVertices.clear(); - sector.m_lineVertices.reserve(numSamplesX * numSamplesY * 4); + AZStd::vector rowHeights(numSamplesX); // For each terrain height value in the region, create the _| grid lines for that point and cache off the height value // for use with subsequent grid line calculations. @@ -376,21 +376,21 @@ namespace Terrain }; // This set of nested loops will get replaced with a call to ProcessHeightsFromRegion once the API exists. - uint32_t yIndex = 0; - for (float y = region.GetMin().GetY(); y < region.GetMax().GetY(); y += gridResolution.GetY()) + for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) { - uint32_t xIndex = 0; - for (float x = region.GetMin().GetX(); x < region.GetMax().GetX(); x += gridResolution.GetX()) + float y = region.GetMin().GetY() + (gridResolution.GetY() * yIndex); + for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) { + float x = region.GetMin().GetX() + (gridResolution.GetX() * xIndex); + float height = worldMinZ; bool terrainExists = false; AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, &terrainExists); - ProcessHeightValue(xIndex, yIndex, AZ::Vector3(x, y, height), terrainExists); - xIndex++; + ProcessHeightValue( + aznumeric_cast(xIndex), aznumeric_cast(yIndex), AZ::Vector3(x, y, height), terrainExists); } - yIndex++; } } From 60b8292abffb39f0969c9c324e8a3c173b09d72e Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Thu, 6 Jan 2022 10:12:15 -0600 Subject: [PATCH 089/272] Adding Docking and EditMenu tests to Periodic suite for Jenkins testing Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/TestSuite_Periodic.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py index 282276250f..6e7bc413d3 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py @@ -47,10 +47,18 @@ class TestAutomation(TestAutomationBase): from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False) + def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Docking_BasicDockedTools as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform): from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform): + from .EditorScripts import Menus_EditMenuOptions as test_module + self._run_test(request, workspace, editor, test_module, batch_mode=False) + def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform): from .EditorScripts import Menus_FileMenuOptions as test_module self._run_test(request, workspace, editor, test_module, batch_mode=False) From fee88cf5c6499812af04c125fb12b3d93330d1b7 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Thu, 6 Jan 2022 10:12:54 -0600 Subject: [PATCH 090/272] Removed legacy editor DatabaseLibrary code. Signed-off-by: Chris Galvan --- Code/Editor/BaseLibrary.cpp | 232 ----- Code/Editor/BaseLibrary.h | 129 --- Code/Editor/BaseLibraryItem.cpp | 261 ------ Code/Editor/BaseLibraryItem.h | 114 --- Code/Editor/BaseLibraryManager.cpp | 822 ------------------ Code/Editor/BaseLibraryManager.h | 226 ----- Code/Editor/ErrorRecorder.cpp | 1 - Code/Editor/ErrorRecorder.h | 2 + Code/Editor/ErrorReport.cpp | 29 - Code/Editor/ErrorReport.h | 10 +- Code/Editor/ErrorReportDialog.cpp | 4 - Code/Editor/ErrorReportTableModel.cpp | 6 +- Code/Editor/IEditor.h | 9 - Code/Editor/IEditorImpl.cpp | 17 - Code/Editor/IEditorImpl.h | 3 - Code/Editor/Include/IBaseLibraryManager.h | 143 --- Code/Editor/Include/IDataBaseItem.h | 92 -- Code/Editor/Include/IDataBaseLibrary.h | 118 --- Code/Editor/Include/IDataBaseManager.h | 134 --- Code/Editor/Include/IEditorMaterial.h | 20 - Code/Editor/Include/IEditorMaterialManager.h | 21 - Code/Editor/Include/IErrorReport.h | 4 - Code/Editor/Lib/Tests/IEditorMock.h | 3 - .../TrackView/TrackViewSequenceManager.cpp | 14 - .../TrackView/TrackViewSequenceManager.h | 4 - Code/Editor/Viewport.h | 3 - Code/Editor/editor_core_files.cmake | 7 - Code/Editor/editor_lib_files.cmake | 6 - 28 files changed, 4 insertions(+), 2430 deletions(-) delete mode 100644 Code/Editor/BaseLibrary.cpp delete mode 100644 Code/Editor/BaseLibrary.h delete mode 100644 Code/Editor/BaseLibraryItem.cpp delete mode 100644 Code/Editor/BaseLibraryItem.h delete mode 100644 Code/Editor/BaseLibraryManager.cpp delete mode 100644 Code/Editor/BaseLibraryManager.h delete mode 100644 Code/Editor/Include/IBaseLibraryManager.h delete mode 100644 Code/Editor/Include/IDataBaseItem.h delete mode 100644 Code/Editor/Include/IDataBaseLibrary.h delete mode 100644 Code/Editor/Include/IDataBaseManager.h delete mode 100644 Code/Editor/Include/IEditorMaterial.h delete mode 100644 Code/Editor/Include/IEditorMaterialManager.h diff --git a/Code/Editor/BaseLibrary.cpp b/Code/Editor/BaseLibrary.cpp deleted file mode 100644 index 15742bd254..0000000000 --- a/Code/Editor/BaseLibrary.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "BaseLibrary.h" -#include "BaseLibraryItem.h" -#include "Include/IBaseLibraryManager.h" -#include -#include - -////////////////////////////////////////////////////////////////////////// -// CBaseLibrary implementation. -////////////////////////////////////////////////////////////////////////// -CBaseLibrary::CBaseLibrary(IBaseLibraryManager* pManager) - : m_pManager(pManager) - , m_bModified(false) - , m_bLevelLib(false) - , m_bNewLibrary(true) -{ -} - -////////////////////////////////////////////////////////////////////////// -CBaseLibrary::~CBaseLibrary() -{ - m_items.clear(); -} - -////////////////////////////////////////////////////////////////////////// -IBaseLibraryManager* CBaseLibrary::GetManager() -{ - return m_pManager; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibrary::RemoveAllItems() -{ - AddRef(); - for (int i = 0; i < m_items.size(); i++) - { - // Unregister item in case it was registered. It is ok if it wasn't. This is still safe to call. - m_pManager->UnregisterItem(m_items[i]); - // Clear library item. - m_items[i]->m_library = nullptr; - } - m_items.clear(); - Release(); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibrary::SetName(const QString& name) -{ - //the fullname of the items in the library will be changed due to library's name change - //so we need unregistered them and register them after their name changed. - for (int i = 0; i < m_items.size(); i++) - { - m_pManager->UnregisterItem(m_items[i]); - } - - m_name = name; - - for (int i = 0; i < m_items.size(); i++) - { - m_pManager->RegisterItem(m_items[i]); - } - - SetModified(); -} - -////////////////////////////////////////////////////////////////////////// -const QString& CBaseLibrary::GetName() const -{ - return m_name; -} - -////////////////////////////////////////////////////////////////////////// -bool CBaseLibrary::Save() -{ - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CBaseLibrary::Load(const QString& filename) -{ - m_filename = filename; - SetModified(false); - m_bNewLibrary = false; - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibrary::SetModified(bool bModified) -{ - if (bModified != m_bModified) - { - m_bModified = bModified; - emit Modified(bModified); - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibrary::AddItem(IDataBaseItem* item, bool bRegister) -{ - - CBaseLibraryItem* pLibItem = (CBaseLibraryItem*)item; - // Check if item is already assigned to this library. - if (pLibItem->m_library != this) - { - pLibItem->m_library = this; - m_items.push_back(pLibItem); - SetModified(); - if (bRegister) - { - m_pManager->RegisterItem(pLibItem); - } - } -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibrary::GetItem(int index) -{ - assert(index >= 0 && index < m_items.size()); - return m_items[index]; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibrary::RemoveItem(IDataBaseItem* item) -{ - - for (int i = 0; i < m_items.size(); i++) - { - if (m_items[i] == item) - { - // Unregister item in case it was registered. It is ok if it wasn't. This is still safe to call. - m_pManager->UnregisterItem(m_items[i]); - m_items.erase(m_items.begin() + i); - SetModified(); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibrary::FindItem(const QString& name) -{ - for (int i = 0; i < m_items.size(); i++) - { - if (QString::compare(m_items[i]->GetName(), name, Qt::CaseInsensitive) == 0) - { - return m_items[i]; - } - } - return nullptr; -} - -bool CBaseLibrary::AddLibraryToSourceControl(const QString& fullPathName) const -{ - IEditor* pEditor = GetIEditor(); - IFileUtil* pFileUtil = pEditor ? pEditor->GetFileUtil() : nullptr; - if (pFileUtil) - { - return pFileUtil->CheckoutFile(fullPathName.toUtf8().data(), nullptr); - } - - return false; -} - -bool CBaseLibrary::SaveLibrary(const char* name, bool saveEmptyLibrary) -{ - assert(name != nullptr); - if (name == nullptr) - { - CryFatalError("The library you are attempting to save has no name specified."); - return false; - } - - QString fileName(GetFilename()); - if (fileName.isEmpty() && !saveEmptyLibrary) - { - return false; - } - - fileName = Path::GamePathToFullPath(fileName); - - XmlNodeRef root = GetIEditor()->GetSystem()->CreateXmlNode(name); - Serialize(root, false); - bool bRes = XmlHelpers::SaveXmlNode(GetIEditor()->GetFileUtil(), root, fileName.toUtf8().data()); - if (m_bNewLibrary) - { - AddLibraryToSourceControl(fileName); - m_bNewLibrary = false; - } - if (!bRes) - { - QByteArray filenameUtf8 = fileName.toUtf8(); - AZStd::string strMessage = AZStd::string::format("The file %s is read-only and the save of the library couldn't be performed. Try to remove the \"read-only\" flag or check-out the file and then try again.", filenameUtf8.data()); - CryMessageBox(strMessage.c_str(), "Saving Error", MB_OK | MB_ICONWARNING); - } - return bRes; -} - -//CONFETTI BEGIN -void CBaseLibrary::ChangeItemOrder(CBaseLibraryItem* item, unsigned int newLocation) -{ - std::vector<_smart_ptr > temp; - for (unsigned int i = 0; i < m_items.size(); i++) - { - if (i == newLocation) - { - temp.push_back(_smart_ptr(item)); - } - if (m_items[i] != item) - { - temp.push_back(m_items[i]); - } - } - // If newLocation is greater than the original size, append the item to end of the list - if (newLocation >= m_items.size()) - { - temp.push_back(_smart_ptr(item)); - } - m_items = temp; -} -//CONFETTI END - -#include diff --git a/Code/Editor/BaseLibrary.h b/Code/Editor/BaseLibrary.h deleted file mode 100644 index 55079d3fde..0000000000 --- a/Code/Editor/BaseLibrary.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_BASELIBRARY_H -#define CRYINCLUDE_EDITOR_BASELIBRARY_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "Include/IDataBaseLibrary.h" -#include "Include/IBaseLibraryManager.h" -#include "Include/EditorCoreAPI.h" -#include "Util/TRefCountBase.h" - -#include -#endif - -// Ensure we don't try to dllimport when moc includes us -#if defined(Q_MOC_BUILD) && !defined(EDITOR_CORE) -#define EDITOR_CORE -#endif - -/** This a base class for all Libraries used by Editor. -*/ -class EDITOR_CORE_API CBaseLibrary - : public QObject - , public TRefCountBase -{ - Q_OBJECT - -public: - explicit CBaseLibrary(IBaseLibraryManager* pManager); - ~CBaseLibrary(); - - //! Set library name. - virtual void SetName(const QString& name); - //! Get library name. - const QString& GetName() const override; - - //! Set new filename for this library. - virtual bool SetFilename(const QString& filename, [[maybe_unused]] bool checkForUnique = true) { m_filename = filename.toLower(); return true; }; - const QString& GetFilename() const override { return m_filename; }; - - bool Save() override = 0; - bool Load(const QString& filename) override = 0; - void Serialize(XmlNodeRef& node, bool bLoading) override = 0; - - //! Mark library as modified. - void SetModified(bool bModified = true) override; - //! Check if library was modified. - bool IsModified() const override { return m_bModified; }; - - ////////////////////////////////////////////////////////////////////////// - // Working with items. - ////////////////////////////////////////////////////////////////////////// - //! Add a new prototype to library. - void AddItem(IDataBaseItem* item, bool bRegister = true) override; - //! Get number of known prototypes. - int GetItemCount() const override { return static_cast(m_items.size()); } - //! Get prototype by index. - IDataBaseItem* GetItem(int index) override; - - //! Delete item by pointer of item. - void RemoveItem(IDataBaseItem* item) override; - - //! Delete all items from library. - void RemoveAllItems() override; - - //! Find library item by name. - //! Using linear search. - IDataBaseItem* FindItem(const QString& name) override; - - //! Check if this library is local level library. - bool IsLevelLibrary() const override { return m_bLevelLib; }; - - //! Set library to be level library. - void SetLevelLibrary(bool bEnable) override { m_bLevelLib = bEnable; }; - - ////////////////////////////////////////////////////////////////////////// - //! Return manager for this library. - IBaseLibraryManager* GetManager() override; - - // Saves the library with the main tag defined by the parameter name - bool SaveLibrary(const char* name, bool saveEmptyLibrary = false); - - //CONFETTI BEGIN - // Used to change the library item order - void ChangeItemOrder(CBaseLibraryItem* item, unsigned int newLocation) override; - //CONFETTI END - -signals: - void Modified(bool bModified); - -private: - // Add the library to the source control - bool AddLibraryToSourceControl(const QString& fullPathName) const; - -protected: - - //! Name of the library. - QString m_name; - //! Filename of the library. - QString m_filename; - - //! Flag set when library was modified. - bool m_bModified; - - // Flag set when the library is just created and it's not yet saved for the first time. - bool m_bNewLibrary; - - //! Level library is saved within the level .ly file and is local for this level. - bool m_bLevelLib; - - ////////////////////////////////////////////////////////////////////////// - // Manager. - IBaseLibraryManager* m_pManager; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - // Array of all our library items. - std::vector<_smart_ptr > m_items; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -#endif // CRYINCLUDE_EDITOR_BASELIBRARY_H diff --git a/Code/Editor/BaseLibraryItem.cpp b/Code/Editor/BaseLibraryItem.cpp deleted file mode 100644 index e3788bc3e4..0000000000 --- a/Code/Editor/BaseLibraryItem.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "BaseLibraryItem.h" -#include "BaseLibrary.h" -#include "BaseLibraryManager.h" -#include "Undo/IUndoObject.h" - -#include - -//undo object for multi-changes inside library item. such as set all variables to default values. -//For example: change particle emitter shape will lead to multiple variable changes -class CUndoBaseLibraryItem - : public IUndoObject -{ -public: - CUndoBaseLibraryItem(IBaseLibraryManager *libMgr, CBaseLibraryItem* libItem, bool ignoreChild) - : m_libMgr(libMgr) - { - assert(libItem); - assert(libMgr); - - m_itemPath = libItem->GetFullName(); - - //serialize the lib item to undo - m_undoCtx.node = GetIEditor()->GetSystem()->CreateXmlNode("Undo"); - m_undoCtx.bIgnoreChilds = ignoreChild; - m_undoCtx.bLoading = false; //saving - m_undoCtx.bUniqName = false; //don't generate new name - m_undoCtx.bCopyPaste = true; //so it won't override guid - m_undoCtx.bUndo = true; - libItem->Serialize(m_undoCtx); - - //evaluate size - XmlString xmlStr = m_undoCtx.node->getXML(); - m_size = sizeof(CUndoBaseLibraryItem); - m_size += static_cast(xmlStr.GetAllocatedMemory()); - m_size += m_itemPath.length(); - } - - -protected: - int GetSize() override - { - return m_size; - } - - void Undo(bool bUndo) override - { - //find the libItem - IDataBaseItem *libItem = m_libMgr->FindItemByName(m_itemPath); - if (libItem == nullptr) - { - //the undo stack is not reliable any more.. - assert(false); - return; - } - - //save for redo - if (bUndo) - { - m_redoCtx.node = GetIEditor()->GetSystem()->CreateXmlNode("Redo"); - m_redoCtx.bIgnoreChilds = m_undoCtx.bIgnoreChilds; - m_redoCtx.bLoading = false; //saving - m_redoCtx.bUniqName = false; - m_redoCtx.bCopyPaste = true; - m_redoCtx.bUndo = true; - libItem->Serialize(m_redoCtx); - - XmlString xmlStr = m_redoCtx.node->getXML(); - m_size += static_cast(xmlStr.GetAllocatedMemory()); - } - - //load previous saved data - m_undoCtx.bLoading = true; - libItem->Serialize(m_undoCtx); - } - - void Redo() override - { - //find the libItem - IDataBaseItem *libItem = m_libMgr->FindItemByName(m_itemPath); - if (libItem == nullptr || m_redoCtx.node == nullptr) - { - //the undo stack is not reliable any more.. - assert(false); - return; - } - - m_redoCtx.bLoading = true; - libItem->Serialize(m_redoCtx); - } - -private: - QString m_itemPath; - IDataBaseItem::SerializeContext m_undoCtx; //saved before operation - IDataBaseItem::SerializeContext m_redoCtx; //saved after operation so used for redo - IBaseLibraryManager* m_libMgr; - int m_size; -}; - -////////////////////////////////////////////////////////////////////////// -// CBaseLibraryItem implementation. -////////////////////////////////////////////////////////////////////////// -CBaseLibraryItem::CBaseLibraryItem() -{ - m_library = nullptr; - GenerateId(); - m_bModified = false; -} - -CBaseLibraryItem::~CBaseLibraryItem() -{ -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryItem::GetFullName() const -{ - QString name; - if (m_library) - { - name = m_library->GetName() + "."; - } - name += m_name; - return name; -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryItem::GetGroupName() -{ - QString str = GetName(); - int p = str.lastIndexOf('.'); - if (p >= 0) - { - return str.mid(0, p); - } - return ""; -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryItem::GetShortName() -{ - QString str = GetName(); - int p = str.lastIndexOf('.'); - if (p >= 0) - { - return str.mid(p + 1); - } - p = str.lastIndexOf('/'); - if (p >= 0) - { - return str.mid(p + 1); - } - return str; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryItem::SetName(const QString& name) -{ - assert(m_library); - if (name == m_name) - { - return; - } - QString oldName = GetFullName(); - m_name = name; - ((CBaseLibraryManager*)m_library->GetManager())->OnRenameItem(this, oldName); -} - -////////////////////////////////////////////////////////////////////////// -const QString& CBaseLibraryItem::GetName() const -{ - return m_name; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryItem::GenerateId() -{ - GUID guid = AZ::Uuid::CreateRandom(); - SetGUID(guid); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryItem::SetGUID(REFGUID guid) -{ - if (m_library) - { - ((CBaseLibraryManager*)m_library->GetManager())->RegisterItem(this, guid); - } - m_guid = guid; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryItem::Serialize(SerializeContext& ctx) -{ - assert(m_library); - - XmlNodeRef node = ctx.node; - if (ctx.bLoading) - { - QString name = m_name; - // Loading - node->getAttr("Name", name); - - if (!ctx.bUniqName) - { - SetName(name); - } - else - { - SetName(GetLibrary()->GetManager()->MakeUniqueItemName(name)); - } - - if (!ctx.bCopyPaste) - { - GUID guid; - if (node->getAttr("Id", guid)) - { - SetGUID(guid); - } - } - } - else - { - // Saving. - node->setAttr("Name", m_name.toUtf8().data()); - node->setAttr("Id", m_guid); - node->setAttr("Library", GetLibrary()->GetName().toUtf8().data()); - } - m_bModified = false; -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryItem::GetLibrary() const -{ - return m_library; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryItem::SetLibrary(CBaseLibrary* pLibrary) -{ - m_library = pLibrary; -} - -//! Mark library as modified. -void CBaseLibraryItem::SetModified(bool bModified) -{ - m_bModified = bModified; - if (m_bModified && m_library != nullptr) - { - m_library->SetModified(bModified); - } -} diff --git a/Code/Editor/BaseLibraryItem.h b/Code/Editor/BaseLibraryItem.h deleted file mode 100644 index 53cf0add2b..0000000000 --- a/Code/Editor/BaseLibraryItem.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_BASELIBRARYITEM_H -#define CRYINCLUDE_EDITOR_BASELIBRARYITEM_H -#pragma once - -#include "Include/IDataBaseItem.h" -#include "BaseLibrary.h" - -#include - -class CBaseLibrary; - -////////////////////////////////////////////////////////////////////////// -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -/** Base class for all items contained in BaseLibraray. -*/ -class EDITOR_CORE_API CBaseLibraryItem - : public TRefCountBase -{ - AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING -public: - CBaseLibraryItem(); - ~CBaseLibraryItem(); - - //! Set item name. - //! Its virtual, in case you want to override it in derrived item. - virtual void SetName(const QString& name); - //! Get item name. - const QString& GetName() const; - - //! Get full item name, including name of library. - //! Name formed by adding dot after name of library - //! eg. library Pickup and item PickupRL form full item name: "Pickups.PickupRL". - QString GetFullName() const; - - //! Get only nameof group from prototype. - QString GetGroupName(); - //! Get short name of prototype without group. - QString GetShortName(); - - //! Return Library this item are contained in. - //! Item can only be at one library. - IDataBaseLibrary* GetLibrary() const; - void SetLibrary(CBaseLibrary* pLibrary); - - ////////////////////////////////////////////////////////////////////////// - //! Serialize library item to archive. - virtual void Serialize(SerializeContext& ctx); - - ////////////////////////////////////////////////////////////////////////// - //! Generate new unique id for this item. - void GenerateId(); - //! Returns GUID of this material. - const GUID& GetGUID() const { return m_guid; } - - //! Mark library as modified. - void SetModified(bool bModified = true); - //! Check if library was modified. - bool IsModified() const { return m_bModified; }; - - //! Returns true if the item is registered, otherwise false - bool IsRegistered() const { return m_bRegistered; }; - - //! Validate item for errors. - virtual void Validate() {}; - - //! Get number of sub childs. - virtual int GetChildCount() const { return 0; } - //! Get sub child by index. - virtual CBaseLibraryItem* GetChild([[maybe_unused]] int index) const { return nullptr; } - - - ////////////////////////////////////////////////////////////////////////// - //! Gathers resources by this item. - virtual void GatherUsedResources([[maybe_unused]] CUsedResources& resources) {}; - - //! Get if stored item is enabled - virtual bool GetIsEnabled() { return true; }; - - - int IsParticleItem = -1; -protected: - void SetGUID(REFGUID guid); - friend class CBaseLibrary; - friend class CBaseLibraryManager; - // Name of this prototype. - QString m_name; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - //! Reference to prototype library who contains this prototype. - _smart_ptr m_library; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - //! Every base library item have unique id. - GUID m_guid; - // True when item modified by editor. - bool m_bModified; - // True when item registered in manager. - bool m_bRegistered = false; -}; - -Q_DECLARE_METATYPE(CBaseLibraryItem*); - -TYPEDEF_AUTOPTR(CBaseLibraryItem); - - -#endif // CRYINCLUDE_EDITOR_BASELIBRARYITEM_H diff --git a/Code/Editor/BaseLibraryManager.cpp b/Code/Editor/BaseLibraryManager.cpp deleted file mode 100644 index 0e51a5238c..0000000000 --- a/Code/Editor/BaseLibraryManager.cpp +++ /dev/null @@ -1,822 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - - -#include "EditorDefs.h" - -#include "BaseLibraryManager.h" - -// Editor -#include "BaseLibraryItem.h" -#include "ErrorReport.h" -#include "Undo/IUndoObject.h" - -////////////////////////////////////////////////////////////////////////// -// CBaseLibraryManager implementation. -////////////////////////////////////////////////////////////////////////// -CBaseLibraryManager::CBaseLibraryManager() -{ - m_bUniqNameMap = false; - m_bUniqGuidMap = true; - GetIEditor()->RegisterNotifyListener(this); -} - -////////////////////////////////////////////////////////////////////////// -CBaseLibraryManager::~CBaseLibraryManager() -{ - ClearAll(); - GetIEditor()->UnregisterNotifyListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::ClearAll() -{ - // Delete all items from all libraries. - for (int i = 0; i < m_libs.size(); i++) - { - m_libs[i]->RemoveAllItems(); - } - - // if we will not copy maps locally then destructors of the elements of - // the map will operate on the already invalid map object - // see: - // CBaseLibraryManager::UnregisterItem() - // CBaseLibraryManager::DeleteItem() - // CMaterial::~CMaterial() - - ItemsGUIDMap itemsGuidMap; - ItemsNameMap itemsNameMap; - - { - AZStd::lock_guard lock(m_itemsNameMapMutex); - std::swap(itemsGuidMap, m_itemsGuidMap); - std::swap(itemsNameMap, m_itemsNameMap); - - m_libs.clear(); - } -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryManager::FindLibrary(const QString& library) -{ - const int index = FindLibraryIndex(library); - return index == -1 ? nullptr : m_libs[index]; -} - -////////////////////////////////////////////////////////////////////////// -int CBaseLibraryManager::FindLibraryIndex(const QString& library) -{ - QString lib = library; - lib.replace('\\', '/'); - for (int i = 0; i < m_libs.size(); i++) - { - QString _lib = m_libs[i]->GetFilename(); - _lib.replace('\\', '/'); - if (QString::compare(lib, m_libs[i]->GetName(), Qt::CaseInsensitive) == 0 || QString::compare(lib, _lib, Qt::CaseInsensitive) == 0) - { - return i; - } - } - return -1; -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::FindItem(REFGUID guid) const -{ - CBaseLibraryItem* pMtl = stl::find_in_map(m_itemsGuidMap, guid, nullptr); - return pMtl; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::SplitFullItemName(const QString& fullItemName, QString& libraryName, QString& itemName) -{ - int p; - p = fullItemName.indexOf('.'); - if (p < 0 || !QString::compare(fullItemName.mid(p + 1), "mtl", Qt::CaseInsensitive)) - { - libraryName = ""; - itemName = fullItemName; - return; - } - libraryName = fullItemName.mid(0, p); - itemName = fullItemName.mid(p + 1); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::FindItemByName(const QString& fullItemName) -{ - AZStd::lock_guard lock(m_itemsNameMapMutex); - return stl::find_in_map(m_itemsNameMap, fullItemName, nullptr); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::LoadItemByName(const QString& fullItemName) -{ - QString libraryName, itemName; - SplitFullItemName(fullItemName, libraryName, itemName); - - if (!FindLibrary(libraryName)) - { - LoadLibrary(MakeFilename(libraryName)); - } - - return FindItemByName(fullItemName); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::FindItemByName(const char* fullItemName) -{ - return FindItemByName(QString(fullItemName)); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::LoadItemByName(const char* fullItemName) -{ - return LoadItemByName(QString(fullItemName)); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::CreateItem(IDataBaseLibrary* pLibrary) -{ - assert(pLibrary); - - // Add item to this library. - TSmartPtr pItem = MakeNewItem(); - pLibrary->AddItem(pItem); - return pItem; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::DeleteItem(IDataBaseItem* pItem) -{ - assert(pItem); - - UnregisterItem((CBaseLibraryItem*)pItem); - if (pItem->GetLibrary()) - { - pItem->GetLibrary()->RemoveItem(pItem); - } -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryManager::LoadLibrary(const QString& inFilename, [[maybe_unused]] bool bReload) -{ - if (auto lib = FindLibrary(inFilename)) - { - return lib; - } - - TSmartPtr pLib = MakeNewLibrary(); - if (!pLib->Load(MakeFilename(inFilename))) - { - Error(QObject::tr("Failed to Load Item Library: %1").arg(inFilename).toUtf8().data()); - return nullptr; - } - - m_libs.push_back(pLib); - return pLib; -} - -////////////////////////////////////////////////////////////////////////// -int CBaseLibraryManager::GetModifiedLibraryCount() const -{ - int count = 0; - for (int i = 0; i < m_libs.size(); i++) - { - if (m_libs[i]->IsModified()) - { - count++; - } - } - return count; -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryManager::AddLibrary(const QString& library, bool bIsLevelLibrary, bool bIsLoading) -{ - // Make a filename from name of library. - QString filename = library; - - if (filename.indexOf(".xml") == -1) // if its already a filename, we don't do anything - { - filename.replace(' ', '_'); - if (!bIsLevelLibrary) - { - filename = MakeFilename(library); - } - else - { - // if its the level library it gets saved in the level and should not be concatenated with any other file name - filename = filename + ".xml"; - } - } - - IDataBaseLibrary* pBaseLib = FindLibrary(library); //library name - if (!pBaseLib) - { - pBaseLib = FindLibrary(filename); //library file name - } - if (pBaseLib) - { - return pBaseLib; - } - - CBaseLibrary* lib = MakeNewLibrary(); - lib->SetName(library); - lib->SetLevelLibrary(bIsLevelLibrary); - lib->SetFilename(filename, !bIsLoading); - // set modified to true, so even empty particle libraries get saved - lib->SetModified(true); - - m_libs.push_back(lib); - return lib; -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryManager::MakeFilename(const QString& library) -{ - QString filename = library; - filename.replace(' ', '_'); - filename.replace(".xml", ""); - - // make it contain the canonical libs path: - Path::ConvertBackSlashToSlash(filename); - - QString LibsPath(GetLibsPath()); - Path::ConvertBackSlashToSlash(LibsPath); - - if (filename.left(LibsPath.length()).compare(LibsPath, Qt::CaseInsensitive) == 0) - { - filename = filename.mid(LibsPath.length()); - } - - return LibsPath + filename + ".xml"; -} - -////////////////////////////////////////////////////////////////////////// -bool CBaseLibraryManager::IsUniqueFilename(const QString& library) -{ - QString resultPath = MakeFilename(library); - CCryFile xmlFile; - // If we can find a file for the path - return !xmlFile.Open(resultPath.toUtf8().data(), "rb"); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::DeleteLibrary(const QString& library, bool forceDeleteLevel) -{ - for (int i = 0; i < m_libs.size(); i++) - { - if (QString::compare(library, m_libs[i]->GetName(), Qt::CaseInsensitive) == 0) - { - CBaseLibrary* pLibrary = m_libs[i]; - // Check if not level library, they cannot be deleted. - if (!pLibrary->IsLevelLibrary() || forceDeleteLevel) - { - for (int j = 0; j < pLibrary->GetItemCount(); j++) - { - UnregisterItem((CBaseLibraryItem*)pLibrary->GetItem(j)); - } - pLibrary->RemoveAllItems(); - - if (pLibrary->IsLevelLibrary()) - { - m_pLevelLibrary = nullptr; - } - m_libs.erase(m_libs.begin() + i); - } - break; - } - } -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryManager::GetLibrary(int index) const -{ - assert(index >= 0 && index < m_libs.size()); - return m_libs[index]; -}; - -////////////////////////////////////////////////////////////////////////// -IDataBaseLibrary* CBaseLibraryManager::GetLevelLibrary() const -{ - IDataBaseLibrary* pLevelLib = nullptr; - - for (int i = 0; i < GetLibraryCount(); i++) - { - if (GetLibrary(i)->IsLevelLibrary()) - { - pLevelLib = GetLibrary(i); - break; - } - } - - - return pLevelLib; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::SaveAllLibs() -{ - for (int i = 0; i < GetLibraryCount(); i++) - { - // Check if library is modified. - IDataBaseLibrary* pLibrary = GetLibrary(i); - - //Level library is saved when the level is saved - if (pLibrary->IsLevelLibrary()) - { - continue; - } - if (pLibrary->IsModified()) - { - if (pLibrary->Save()) - { - pLibrary->SetModified(false); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::Serialize(XmlNodeRef& node, bool bLoading) -{ - static const char* const LEVEL_LIBRARY_TAG = "LevelLibrary"; - - QString rootNodeName = GetRootNodeName(); - if (bLoading) - { - XmlNodeRef libs = node->findChild(rootNodeName.toUtf8().data()); - if (libs) - { - for (int i = 0; i < libs->getChildCount(); i++) - { - // Load only library name. - XmlNodeRef libNode = libs->getChild(i); - if (strcmp(libNode->getTag(), LEVEL_LIBRARY_TAG) == 0) - { - if (!m_pLevelLibrary) - { - QString libName; - libNode->getAttr("Name", libName); - m_pLevelLibrary = static_cast(AddLibrary(libName, true)); - } - m_pLevelLibrary->Serialize(libNode, bLoading); - } - else - { - QString libName; - if (libNode->getAttr("Name", libName)) - { - // Load this library. - if (!FindLibrary(libName)) - { - LoadLibrary(MakeFilename(libName)); - } - } - } - } - } - } - else - { - // Save all libraries. - XmlNodeRef libs = node->newChild(rootNodeName.toUtf8().data()); - for (int i = 0; i < GetLibraryCount(); i++) - { - IDataBaseLibrary* pLib = GetLibrary(i); - if (pLib->IsLevelLibrary()) - { - // Level libraries are saved in in level. - XmlNodeRef libNode = libs->newChild(LEVEL_LIBRARY_TAG); - pLib->Serialize(libNode, bLoading); - } - else - { - // Save only library name. - XmlNodeRef libNode = libs->newChild("Library"); - libNode->setAttr("Name", pLib->GetName().toUtf8().data()); - } - } - SaveAllLibs(); - } -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QString& libName) -{ - // unlikely we'll ever encounter more than 16 - std::vector possibleDuplicates; - possibleDuplicates.reserve(16); - - // search for strings in the database that might have a similar name (ignore case) - IDataBaseItemEnumerator* pEnum = GetItemEnumerator(); - for (IDataBaseItem* pItem = pEnum->GetFirst(); pItem != nullptr; pItem = pEnum->GetNext()) - { - //Check if the item is in the target library first. - IDataBaseLibrary* itemLibrary = pItem->GetLibrary(); - QString itemLibraryName; - if (itemLibrary) - { - itemLibraryName = itemLibrary->GetName(); - } - - // Item is not in the library so there cannot be a naming conflict. - if (!libName.isEmpty() && !itemLibraryName.isEmpty() && itemLibraryName != libName) - { - continue; - } - - const QString& name = pItem->GetName(); - if (name.startsWith(srcName, Qt::CaseInsensitive)) - { - possibleDuplicates.push_back(AZStd::string(name.toUtf8().data())); - } - } - pEnum->Release(); - - if (possibleDuplicates.empty()) - { - return srcName; - } - - std::sort(possibleDuplicates.begin(), possibleDuplicates.end(), [](const AZStd::string& strOne, const AZStd::string& strTwo) - { - // I can assume size sorting since if the length is different, either one of the two strings doesn't - // closely match the string we are trying to duplicate, or it's a bigger number (X1 vs X10) - if (strOne.size() != strTwo.size()) - { - return strOne.size() < strTwo.size(); - } - else - { - return azstricmp(strOne.c_str(), strTwo.c_str()) < 0; - } - } - ); - - int num = 0; - QString returnValue = srcName; - while (num < possibleDuplicates.size() && QString::compare(possibleDuplicates[num].c_str(), returnValue, Qt::CaseInsensitive) == 0) - { - returnValue = QStringLiteral("%1%2%3").arg(srcName).arg("_").arg(num); - ++num; - } - - return returnValue; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::Validate() -{ - IDataBaseItemEnumerator* pEnum = GetItemEnumerator(); - for (IDataBaseItem* pItem = pEnum->GetFirst(); pItem != nullptr; pItem = pEnum->GetNext()) - { - pItem->Validate(); - } - pEnum->Release(); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::RegisterItem(CBaseLibraryItem* pItem, REFGUID newGuid) -{ - assert(pItem); - - bool bNotify = false; - - if (m_bUniqGuidMap) - { - REFGUID oldGuid = pItem->GetGUID(); - if (!GuidUtil::IsEmpty(oldGuid)) - { - m_itemsGuidMap.erase(oldGuid); - } - if (GuidUtil::IsEmpty(newGuid)) - { - return; - } - CBaseLibraryItem* pOldItem = stl::find_in_map(m_itemsGuidMap, newGuid, nullptr); - if (!pOldItem) - { - pItem->m_guid = newGuid; - m_itemsGuidMap[newGuid] = pItem; - pItem->m_bRegistered = true; - bNotify = true; - } - else - { - if (pOldItem != pItem) - { - ReportDuplicateItem(pItem, pOldItem); - } - } - } - - if (m_bUniqNameMap) - { - QString fullName = pItem->GetFullName(); - if (!pItem->GetName().isEmpty()) - { - CBaseLibraryItem* pOldItem = static_cast(FindItemByName(fullName)); - if (!pOldItem) - { - AZStd::lock_guard lock(m_itemsNameMapMutex); - m_itemsNameMap[fullName] = pItem; - pItem->m_bRegistered = true; - bNotify = true; - } - else - { - if (pOldItem != pItem) - { - ReportDuplicateItem(pItem, pOldItem); - } - } - } - } - - // Notify listeners. - if (bNotify) - { - NotifyItemEvent(pItem, EDB_ITEM_EVENT_ADD); - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::RegisterItem(CBaseLibraryItem* pItem) -{ - assert(pItem); - - bool bNotify = false; - - if (m_bUniqGuidMap) - { - if (GuidUtil::IsEmpty(pItem->GetGUID())) - { - return; - } - CBaseLibraryItem* pOldItem = stl::find_in_map(m_itemsGuidMap, pItem->GetGUID(), nullptr); - if (!pOldItem) - { - m_itemsGuidMap[pItem->GetGUID()] = pItem; - pItem->m_bRegistered = true; - bNotify = true; - } - else - { - if (pOldItem != pItem) - { - ReportDuplicateItem(pItem, pOldItem); - } - } - } - - if (m_bUniqNameMap) - { - QString fullName = pItem->GetFullName(); - if (!fullName.isEmpty()) - { - CBaseLibraryItem* pOldItem = static_cast(FindItemByName(fullName)); - if (!pOldItem) - { - AZStd::lock_guard lock(m_itemsNameMapMutex); - m_itemsNameMap[fullName] = pItem; - pItem->m_bRegistered = true; - bNotify = true; - } - else - { - if (pOldItem != pItem) - { - ReportDuplicateItem(pItem, pOldItem); - } - } - } - } - - // Notify listeners. - if (bNotify) - { - NotifyItemEvent(pItem, EDB_ITEM_EVENT_ADD); - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::SetRegisteredFlag(CBaseLibraryItem* pItem, bool bFlag) -{ - pItem->m_bRegistered = bFlag; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::ReportDuplicateItem(CBaseLibraryItem* pItem, CBaseLibraryItem* pOldItem) -{ - QString sLibName; - if (pOldItem->GetLibrary()) - { - sLibName = pOldItem->GetLibrary()->GetName(); - } - CErrorRecord err; - err.pItem = pItem; - err.error = QStringLiteral("Item %1 with duplicate GUID to loaded item %2 ignored").arg(pItem->GetFullName(), pOldItem->GetFullName()); - GetIEditor()->GetErrorReport()->ReportError(err); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::UnregisterItem(CBaseLibraryItem* pItem) -{ - // Notify listeners. - NotifyItemEvent(pItem, EDB_ITEM_EVENT_DELETE); - - if (!pItem) - { - return; - } - - if (m_bUniqGuidMap) - { - m_itemsGuidMap.erase(pItem->GetGUID()); - } - if (m_bUniqNameMap && !pItem->GetFullName().isEmpty()) - { - AZStd::lock_guard lock(m_itemsNameMapMutex); - auto findIter = m_itemsNameMap.find(pItem->GetFullName()); - if (findIter != m_itemsNameMap.end()) - { - _smart_ptr item = findIter->second; - m_itemsNameMap.erase(findIter); - } - } - - pItem->m_bRegistered = false; -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseLibraryManager::MakeFullItemName(IDataBaseLibrary* pLibrary, const QString& group, const QString& itemName) -{ - assert(pLibrary); - QString name = pLibrary->GetName() + "."; - if (!group.isEmpty()) - { - name += group + "."; - } - name += itemName; - return name; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::GatherUsedResources(CUsedResources& resources) -{ - IDataBaseItemEnumerator* pEnum = GetItemEnumerator(); - for (IDataBaseItem* pItem = pEnum->GetFirst(); pItem != nullptr; pItem = pEnum->GetNext()) - { - pItem->GatherUsedResources(resources); - } - pEnum->Release(); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItemEnumerator* CBaseLibraryManager::GetItemEnumerator() -{ - if (m_bUniqNameMap) - { - return new CDataBaseItemEnumerator(&m_itemsNameMap); - } - else - { - return new CDataBaseItemEnumerator(&m_itemsGuidMap); - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::OnEditorNotifyEvent(EEditorNotifyEvent event) -{ - switch (event) - { - case eNotify_OnBeginNewScene: - SetSelectedItem(nullptr); - ClearAll(); - break; - case eNotify_OnBeginSceneOpen: - SetSelectedItem(nullptr); - ClearAll(); - break; - case eNotify_OnCloseScene: - SetSelectedItem(nullptr); - ClearAll(); - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::OnRenameItem(CBaseLibraryItem* pItem, const QString& oldName) -{ - m_itemsNameMapMutex.lock(); - if (!oldName.isEmpty()) - { - m_itemsNameMap.erase(oldName); - } - if (!pItem->GetFullName().isEmpty()) - { - m_itemsNameMap[pItem->GetFullName()] = pItem; - } - m_itemsNameMapMutex.unlock(); - - OnItemChanged(pItem); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::AddListener(IDataBaseManagerListener* pListener) -{ - stl::push_back_unique(m_listeners, pListener); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::RemoveListener(IDataBaseManagerListener* pListener) -{ - stl::find_and_erase(m_listeners, pListener); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::NotifyItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event) -{ - // Notify listeners. - if (!m_listeners.empty()) - { - for (int i = 0; i < m_listeners.size(); i++) - { - m_listeners[i]->OnDataBaseItemEvent(pItem, event); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::OnItemChanged(IDataBaseItem* pItem) -{ - NotifyItemEvent(pItem, EDB_ITEM_EVENT_CHANGED); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::OnUpdateProperties(IDataBaseItem* pItem, bool bRefresh) -{ - NotifyItemEvent(pItem, bRefresh ? EDB_ITEM_EVENT_UPDATE_PROPERTIES - : EDB_ITEM_EVENT_UPDATE_PROPERTIES_NO_EDITOR_REFRESH); -} - -////////////////////////////////////////////////////////////////////////// -void CBaseLibraryManager::SetSelectedItem(IDataBaseItem* pItem) -{ - if (m_pSelectedItem == pItem) - { - return; - } - m_pSelectedItem = (CBaseLibraryItem*)pItem; - NotifyItemEvent(m_pSelectedItem, EDB_ITEM_EVENT_SELECTED); -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::GetSelectedItem() const -{ - return m_pSelectedItem; -} - -////////////////////////////////////////////////////////////////////////// -IDataBaseItem* CBaseLibraryManager::GetSelectedParentItem() const -{ - return m_pSelectedParent; -} - -void CBaseLibraryManager::ChangeLibraryOrder(IDataBaseLibrary* lib, unsigned int newLocation) -{ - if (!lib || newLocation >= m_libs.size() || lib == m_libs[newLocation]) - { - return; - } - - for (int i = 0; i < m_libs.size(); i++) - { - if (lib == m_libs[i]) - { - _smart_ptr curLib = m_libs[i]; - m_libs.erase(m_libs.begin() + i); - m_libs.insert(m_libs.begin() + newLocation, curLib); - return; - } - } -} - -bool CBaseLibraryManager::SetLibraryName(CBaseLibrary* lib, const QString& name) -{ - // SetFilename will validate if the name is duplicate with exist libraries. - if (lib->SetFilename(MakeFilename(name))) - { - lib->SetName(name); - return true; - } - return false; -} diff --git a/Code/Editor/BaseLibraryManager.h b/Code/Editor/BaseLibraryManager.h deleted file mode 100644 index 118c7ef1f0..0000000000 --- a/Code/Editor/BaseLibraryManager.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - - -#ifndef CRYINCLUDE_EDITOR_BASELIBRARYMANAGER_H -#define CRYINCLUDE_EDITOR_BASELIBRARYMANAGER_H -#pragma once - -#include "Include/IBaseLibraryManager.h" -#include "Include/IDataBaseItem.h" -#include "Include/IDataBaseLibrary.h" -#include "Include/IDataBaseManager.h" -#include "Util/TRefCountBase.h" -#include "Util/GuidUtil.h" -#include "BaseLibrary.h" -#include "Util/smartptr.h" -#include -#include - -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -/** Manages all Libraries and Items. -*/ -class SANDBOX_API CBaseLibraryManager - : public IBaseLibraryManager -{ -AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING -public: - CBaseLibraryManager(); - ~CBaseLibraryManager(); - - //! Clear all libraries. - void ClearAll() override; - - ////////////////////////////////////////////////////////////////////////// - // IDocListener implementation. - ////////////////////////////////////////////////////////////////////////// - void OnEditorNotifyEvent(EEditorNotifyEvent event) override; - - ////////////////////////////////////////////////////////////////////////// - // Library items. - ////////////////////////////////////////////////////////////////////////// - //! Make a new item in specified library. - IDataBaseItem* CreateItem(IDataBaseLibrary* pLibrary) override; - //! Delete item from library and manager. - void DeleteItem(IDataBaseItem* pItem) override; - - //! Find Item by its GUID. - IDataBaseItem* FindItem(REFGUID guid) const override; - IDataBaseItem* FindItemByName(const QString& fullItemName) override; - IDataBaseItem* LoadItemByName(const QString& fullItemName) override; - virtual IDataBaseItem* FindItemByName(const char* fullItemName); - virtual IDataBaseItem* LoadItemByName(const char* fullItemName); - - IDataBaseItemEnumerator* GetItemEnumerator() override; - - ////////////////////////////////////////////////////////////////////////// - // Set item currently selected. - void SetSelectedItem(IDataBaseItem* pItem) override; - // Get currently selected item. - IDataBaseItem* GetSelectedItem() const override; - IDataBaseItem* GetSelectedParentItem() const override; - - ////////////////////////////////////////////////////////////////////////// - // Libraries. - ////////////////////////////////////////////////////////////////////////// - //! Add Item library. - IDataBaseLibrary* AddLibrary(const QString& library, bool bIsLevelLibrary = false, bool bIsLoading = true) override; - void DeleteLibrary(const QString& library, bool forceDeleteLevel = false) override; - //! Get number of libraries. - int GetLibraryCount() const override { return static_cast(m_libs.size()); }; - //! Get number of modified libraries. - int GetModifiedLibraryCount() const override; - - //! Get Item library by index. - IDataBaseLibrary* GetLibrary(int index) const override; - - //! Get Level Item library. - IDataBaseLibrary* GetLevelLibrary() const override; - - //! Find Items Library by name. - IDataBaseLibrary* FindLibrary(const QString& library) override; - - //! Find Items Library's index by name. - int FindLibraryIndex(const QString& library) override; - - //! Load Items library. - IDataBaseLibrary* LoadLibrary(const QString& filename, bool bReload = false) override; - - //! Save all modified libraries. - void SaveAllLibs() override; - - //! Serialize property manager. - void Serialize(XmlNodeRef& node, bool bLoading) override; - - //! Export items to game. - void Export([[maybe_unused]] XmlNodeRef& node) override {}; - - //! Returns unique name base on input name. - QString MakeUniqueItemName(const QString& name, const QString& libName = "") override; - QString MakeFullItemName(IDataBaseLibrary* pLibrary, const QString& group, const QString& itemName) override; - - //! Root node where this library will be saved. - QString GetRootNodeName() override = 0; - //! Path to libraries in this manager. - QString GetLibsPath() override = 0; - - ////////////////////////////////////////////////////////////////////////// - //! Validate library items for errors. - void Validate() override; - - ////////////////////////////////////////////////////////////////////////// - void GatherUsedResources(CUsedResources& resources) override; - - void AddListener(IDataBaseManagerListener* pListener) override; - void RemoveListener(IDataBaseManagerListener* pListener) override; - - ////////////////////////////////////////////////////////////////////////// - void RegisterItem(CBaseLibraryItem* pItem, REFGUID newGuid) override; - void RegisterItem(CBaseLibraryItem* pItem) override; - void UnregisterItem(CBaseLibraryItem* pItem) override; - - // Only Used internally. - void OnRenameItem(CBaseLibraryItem* pItem, const QString& oldName) override; - - // Called by items to indicated that they have been modified. - // Sends item changed event to listeners. - void OnItemChanged(IDataBaseItem* pItem) override; - void OnUpdateProperties(IDataBaseItem* pItem, bool bRefresh) override; - - QString MakeFilename(const QString& library); - bool IsUniqueFilename(const QString& library) override; - - //CONFETTI BEGIN - // Used to change the library item order - void ChangeLibraryOrder(IDataBaseLibrary* lib, unsigned int newLocation) override; - - bool SetLibraryName(CBaseLibrary* lib, const QString& name) override; - -protected: - void SplitFullItemName(const QString& fullItemName, QString& libraryName, QString& itemName); - void NotifyItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event); - void SetRegisteredFlag(CBaseLibraryItem* pItem, bool bFlag); - - ////////////////////////////////////////////////////////////////////////// - // Must be overriden. - //! Makes a new Item. - virtual CBaseLibraryItem* MakeNewItem() = 0; - virtual CBaseLibrary* MakeNewLibrary() = 0; - ////////////////////////////////////////////////////////////////////////// - - virtual void ReportDuplicateItem(CBaseLibraryItem* pItem, CBaseLibraryItem* pOldItem); - -protected: - bool m_bUniqGuidMap; - bool m_bUniqNameMap; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - //! Array of all loaded entity items libraries. - std::vector<_smart_ptr > m_libs; - - // There is always one current level library. - TSmartPtr m_pLevelLibrary; - - // GUID to item map. - typedef std::map, guid_less_predicate> ItemsGUIDMap; - ItemsGUIDMap m_itemsGuidMap; - - // Case insensitive name to items map. - typedef std::map, stl::less_stricmp> ItemsNameMap; - ItemsNameMap m_itemsNameMap; - AZStd::mutex m_itemsNameMapMutex; - - std::vector m_listeners; - - // Currently selected item. - _smart_ptr m_pSelectedItem; - _smart_ptr m_pSelectedParent; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -////////////////////////////////////////////////////////////////////////// -template -class CDataBaseItemEnumerator - : public IDataBaseItemEnumerator -{ - TMap* m_pMap; - typename TMap::iterator m_iterator; - -public: - CDataBaseItemEnumerator(TMap* pMap) - { - assert(pMap); - m_pMap = pMap; - m_iterator = m_pMap->begin(); - } - void Release() override { delete this; }; - IDataBaseItem* GetFirst() override - { - m_iterator = m_pMap->begin(); - if (m_iterator == m_pMap->end()) - { - return 0; - } - return m_iterator->second; - } - IDataBaseItem* GetNext() override - { - if (m_iterator != m_pMap->end()) - { - m_iterator++; - } - if (m_iterator == m_pMap->end()) - { - return 0; - } - return m_iterator->second; - } -}; - -#endif // CRYINCLUDE_EDITOR_BASELIBRARYMANAGER_H diff --git a/Code/Editor/ErrorRecorder.cpp b/Code/Editor/ErrorRecorder.cpp index 999dab323c..253e103527 100644 --- a/Code/Editor/ErrorRecorder.cpp +++ b/Code/Editor/ErrorRecorder.cpp @@ -7,7 +7,6 @@ */ #include "EditorDefs.h" #include "ErrorRecorder.h" -#include "BaseLibraryItem.h" #include "Include/IErrorReport.h" diff --git a/Code/Editor/ErrorRecorder.h b/Code/Editor/ErrorRecorder.h index e4b3706a16..beacc3f0e5 100644 --- a/Code/Editor/ErrorRecorder.h +++ b/Code/Editor/ErrorRecorder.h @@ -14,6 +14,8 @@ #define CRYINCLUDE_EDITOR_CORE_ERRORRECORDER_H #pragma once +#include "Include/EditorCoreAPI.h" + ////////////////////////////////////////////////////////////////////////// //! Automatic class to record and display error. class EDITOR_CORE_API CErrorsRecorder diff --git a/Code/Editor/ErrorReport.cpp b/Code/Editor/ErrorReport.cpp index 4fd7d41a96..f93ea7606d 100644 --- a/Code/Editor/ErrorReport.cpp +++ b/Code/Editor/ErrorReport.cpp @@ -67,24 +67,6 @@ QString CErrorRecord::GetErrorText() const { str += QString("\t "); } - if (pItem) - { - switch (pItem->GetType()) - { - case EDB_TYPE_MATERIAL: - str += QString("\t Material=\""); - break; - case EDB_TYPE_PARTICLE: - str += QString("\t Particle=\""); - break; - case EDB_TYPE_MUSIC: - str += QString("\t Music=\""); - break; - default: - str += QString("\t Item=\""); - } - str += pItem->GetFullName() + "\""; - } if (pObject) { str += QString("\t Object=\"") + pObject->GetName() + "\""; @@ -101,7 +83,6 @@ CErrorReport::CErrorReport() m_bImmediateMode = true; m_bShowErrors = true; m_pObject = nullptr; - m_pItem = nullptr; m_pParticle = nullptr; } @@ -140,10 +121,6 @@ void CErrorReport::ReportError(CErrorRecord& err) { err.pObject = m_pObject; } - else if (err.pItem == nullptr && m_pItem != nullptr) - { - err.pItem = m_pItem; - } m_errors.push_back(err); } bNoRecurse = false; @@ -255,12 +232,6 @@ void CErrorReport::SetCurrentValidatorObject(CBaseObject* pObject) m_pObject = pObject; } -////////////////////////////////////////////////////////////////////////// -void CErrorReport::SetCurrentValidatorItem(CBaseLibraryItem* pItem) -{ - m_pItem = pItem; -} - ////////////////////////////////////////////////////////////////////////// void CErrorReport::SetCurrentFile(const QString& file) { diff --git a/Code/Editor/ErrorReport.h b/Code/Editor/ErrorReport.h index 3b9a860301..7e2a57a421 100644 --- a/Code/Editor/ErrorReport.h +++ b/Code/Editor/ErrorReport.h @@ -17,7 +17,6 @@ // forward declarations. class CParticleItem; -#include "BaseLibraryItem.h" #include "Objects/BaseObject.h" #include "Include/IErrorReport.h" #include "ErrorRecorder.h" @@ -56,16 +55,13 @@ public: int count; //! Object that caused this error. _smart_ptr pObject; - //! Library Item that caused this error. - _smart_ptr pItem; int flags; CErrorRecord(CBaseObject* object, ESeverity _severity, const QString& _error, int _flags = 0, int _count = 0, - CBaseLibraryItem* item = 0, EValidatorModule _module = VALIDATOR_MODULE_EDITOR) + EValidatorModule _module = VALIDATOR_MODULE_EDITOR) : severity(_severity) , module(_module) , pObject(object) - , pItem(item) , flags(_flags) , count(_count) , error(_error) @@ -77,7 +73,6 @@ public: severity = ESEVERITY_WARNING; module = VALIDATOR_MODULE_EDITOR; pObject = 0; - pItem = 0; flags = 0; count = 0; } @@ -116,8 +111,6 @@ public: //! Assign current Object to which new reported warnings are assigned. void SetCurrentValidatorObject(CBaseObject* pObject); - //! Assign current Item to which new reported warnings are assigned. - void SetCurrentValidatorItem(CBaseLibraryItem* pItem); //! Assign current filename. void SetCurrentFile(const QString& file); @@ -127,7 +120,6 @@ private: bool m_bImmediateMode; bool m_bShowErrors; _smart_ptr m_pObject; - _smart_ptr m_pItem; CParticleItem* m_pParticle; QString m_currentFilename; }; diff --git a/Code/Editor/ErrorReportDialog.cpp b/Code/Editor/ErrorReportDialog.cpp index 2d551d6c8b..bbeede79ef 100644 --- a/Code/Editor/ErrorReportDialog.cpp +++ b/Code/Editor/ErrorReportDialog.cpp @@ -362,10 +362,6 @@ void CErrorReportDialog::CopyToClipboard() { str += QString::fromLatin1(" [Object: %1]").arg(pRecord->pObject->GetName()); } - if (pRecord->pItem) - { - str += QString::fromLatin1(" [Material: %1]").arg(pRecord->pItem->GetName()); - } str += QString::fromLatin1("\r\n"); } } diff --git a/Code/Editor/ErrorReportTableModel.cpp b/Code/Editor/ErrorReportTableModel.cpp index f5dce1a86d..923991bb62 100644 --- a/Code/Editor/ErrorReportTableModel.cpp +++ b/Code/Editor/ErrorReportTableModel.cpp @@ -149,11 +149,7 @@ QVariant CErrorReportTableModel::data(const CErrorRecord& record, int column, in case ColumnFile: return record.file; case ColumnObject: - if (record.pItem) - { - return record.pItem->GetFullName(); - } - else if (record.pObject) + if (record.pObject) { return record.pObject->GetName(); } diff --git a/Code/Editor/IEditor.h b/Code/Editor/IEditor.h index d2d4998187..c91ca62c5e 100644 --- a/Code/Editor/IEditor.h +++ b/Code/Editor/IEditor.h @@ -44,7 +44,6 @@ class CMusicManager; struct IEditorParticleManager; class CEAXPresetManager; class CErrorReport; -class CBaseLibraryItem; class ICommandManager; class CEditorCommandManager; class CHyperGraphManager; @@ -52,9 +51,7 @@ class CConsoleSynchronization; class CUIEnumsDatabase; struct ISourceControl; struct IEditorClassFactory; -struct IDataBaseItem; struct ITransformManipulator; -struct IDataBaseManager; class IFacialEditor; class CDialog; #if defined(AZ_PLATFORM_WINDOWS) @@ -82,8 +79,6 @@ struct IEventLoopHook; struct IErrorReport; // Vladimir@conffx struct IFileUtil; // Vladimir@conffx struct IEditorLog; // Vladimir@conffx -struct IEditorMaterialManager; // Vladimir@conffx -struct IBaseLibraryManager; // Vladimir@conffx struct IImageUtil; // Vladimir@conffx struct IEditorParticleUtils; // Leroy@conffx struct ILogFile; // Vladimir@conffx @@ -519,10 +514,6 @@ struct IEditor //! Get access to object manager. virtual struct IObjectManager* GetObjectManager() = 0; virtual CSettingsManager* GetSettingsManager() = 0; - //! Get DB manager that own items of specified type. - virtual IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType) = 0; - virtual IBaseLibraryManager* GetMaterialManagerLibrary() = 0; // Vladimir@conffx - virtual IEditorMaterialManager* GetIEditorMaterialManager() = 0; // Vladimir@Conffx //! Returns IconManager. virtual IIconManager* GetIconManager() = 0; //! Get Music Manager. diff --git a/Code/Editor/IEditorImpl.cpp b/Code/Editor/IEditorImpl.cpp index 0846cf8a9e..38006c6fca 100644 --- a/Code/Editor/IEditorImpl.cpp +++ b/Code/Editor/IEditorImpl.cpp @@ -892,11 +892,6 @@ void CEditorImpl::CloseView(const GUID& classId) } } -IDataBaseManager* CEditorImpl::GetDBItemManager([[maybe_unused]] EDataBaseItemType itemType) -{ - return nullptr; -} - bool CEditorImpl::SelectColor(QColor& color, QWidget* parent) { const AZ::Color c = AzQtComponents::fromQColor(color); @@ -1624,18 +1619,6 @@ SEditorSettings* CEditorImpl::GetEditorSettings() return &gSettings; } -// Vladimir@Conffx -IBaseLibraryManager* CEditorImpl::GetMaterialManagerLibrary() -{ - return nullptr; -} - -// Vladimir@Conffx -IEditorMaterialManager* CEditorImpl::GetIEditorMaterialManager() -{ - return nullptr; -} - IImageUtil* CEditorImpl::GetImageUtil() { return m_pImageUtil; diff --git a/Code/Editor/IEditorImpl.h b/Code/Editor/IEditorImpl.h index d99b8ae802..7867912941 100644 --- a/Code/Editor/IEditorImpl.h +++ b/Code/Editor/IEditorImpl.h @@ -157,7 +157,6 @@ public: void LockSelection(bool bLock) override; bool IsSelectionLocked() override; - IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType) override; CMusicManager* GetMusicManager() override { return m_pMusicManager; }; IEditorFileMonitor* GetFileMonitor() override; @@ -294,8 +293,6 @@ public: void RegisterObjectContextMenuExtension(TContextMenuExtensionFunc func) override; SSystemGlobalEnvironment* GetEnv() override; - IBaseLibraryManager* GetMaterialManagerLibrary() override; // Vladimir@Conffx - IEditorMaterialManager* GetIEditorMaterialManager() override; // Vladimir@Conffx IImageUtil* GetImageUtil() override; // Vladimir@conffx SEditorSettings* GetEditorSettings() override; ILogFile* GetLogFile() override { return m_pLogFile; } diff --git a/Code/Editor/Include/IBaseLibraryManager.h b/Code/Editor/Include/IBaseLibraryManager.h deleted file mode 100644 index 4116b573fa..0000000000 --- a/Code/Editor/Include/IBaseLibraryManager.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IBASELIBRARYMANAGER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IBASELIBRARYMANAGER_H -#pragma once - -#include -#include "Include/IDataBaseItem.h" -#include "Include/IDataBaseLibrary.h" -#include "Include/IDataBaseManager.h" -#include "Util/TRefCountBase.h" - -class CBaseLibraryItem; -class CBaseLibrary; - -struct IBaseLibraryManager - : public TRefCountBase - , public IEditorNotifyListener -{ - //! Clear all libraries. - virtual void ClearAll() = 0; - - ////////////////////////////////////////////////////////////////////////// - // IDocListener implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnEditorNotifyEvent(EEditorNotifyEvent event) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Library items. - ////////////////////////////////////////////////////////////////////////// - //! Make a new item in specified library. - virtual IDataBaseItem* CreateItem(IDataBaseLibrary* pLibrary) = 0; - //! Delete item from library and manager. - virtual void DeleteItem(IDataBaseItem* pItem) = 0; - - //! Find Item by its GUID. - virtual IDataBaseItem* FindItem(REFGUID guid) const = 0; - virtual IDataBaseItem* FindItemByName(const QString& fullItemName) = 0; - virtual IDataBaseItem* LoadItemByName(const QString& fullItemName) = 0; - - virtual IDataBaseItemEnumerator* GetItemEnumerator() = 0; - - ////////////////////////////////////////////////////////////////////////// - // Set item currently selected. - virtual void SetSelectedItem(IDataBaseItem* pItem) = 0; - // Get currently selected item. - virtual IDataBaseItem* GetSelectedItem() const = 0; - virtual IDataBaseItem* GetSelectedParentItem() const = 0; - - ////////////////////////////////////////////////////////////////////////// - // Libraries. - ////////////////////////////////////////////////////////////////////////// - //! Add Item library. - virtual IDataBaseLibrary* AddLibrary(const QString& library, bool isLevelLibrary = false, bool bIsLoading = true) = 0; - virtual void DeleteLibrary(const QString& library, bool forceDeleteLevel = false) = 0; - //! Get number of libraries. - virtual int GetLibraryCount() const = 0; - //! Get number of modified libraries. - virtual int GetModifiedLibraryCount() const = 0; - - //! Get Item library by index. - virtual IDataBaseLibrary* GetLibrary(int index) const = 0; - - //! Get Level Item library. - virtual IDataBaseLibrary* GetLevelLibrary() const = 0; - - //! Find Items Library by name. - virtual IDataBaseLibrary* FindLibrary(const QString& library) = 0; - - //! Find the Library's index by name. - virtual int FindLibraryIndex(const QString& library) = 0; - - //! Load Items library. -#ifdef LoadLibrary -#undef LoadLibrary -#endif - virtual IDataBaseLibrary* LoadLibrary(const QString& filename, bool bReload = false) = 0; - - //! Save all modified libraries. - virtual void SaveAllLibs() = 0; - - //! Serialize property manager. - virtual void Serialize(XmlNodeRef& node, bool bLoading) = 0; - - //! Export items to game. - virtual void Export(XmlNodeRef& node) = 0; - - //! Returns unique name base on input name. - // Vera@conffx, add LibName parameter so we could make an unique name depends on input library. - // Arguments: - // - name: name of the item - // - libName: The library of the item. Given the library name, the function will return a unique name in the library - // Default value "": The function will ignore the library name and return a unique name in the manager - virtual QString MakeUniqueItemName(const QString& name, const QString& libName = "") = 0; - virtual QString MakeFullItemName(IDataBaseLibrary* pLibrary, const QString& group, const QString& itemName) = 0; - - //! Root node where this library will be saved. - virtual QString GetRootNodeName() = 0; - //! Path to libraries in this manager. - virtual QString GetLibsPath() = 0; - - ////////////////////////////////////////////////////////////////////////// - //! Validate library items for errors. - virtual void Validate() = 0; - - ////////////////////////////////////////////////////////////////////////// - virtual void GatherUsedResources(CUsedResources& resources) = 0; - - virtual void AddListener(IDataBaseManagerListener* pListener) = 0; - virtual void RemoveListener(IDataBaseManagerListener* pListener) = 0; - - ////////////////////////////////////////////////////////////////////////// - virtual void RegisterItem(CBaseLibraryItem* pItem, REFGUID newGuid) = 0; - virtual void RegisterItem(CBaseLibraryItem* pItem) = 0; - virtual void UnregisterItem(CBaseLibraryItem* pItem) = 0; - - // Only Used internally. - virtual void OnRenameItem(CBaseLibraryItem* pItem, const QString& oldName) = 0; - - // Called by items to indicated that they have been modified. - // Sends item changed event to listeners. - virtual void OnItemChanged(IDataBaseItem* pItem) = 0; - virtual void OnUpdateProperties(IDataBaseItem* pItem, bool bRefresh) = 0; - - //CONFETTI BEGIN - // Used to change the library item order - virtual void ChangeLibraryOrder(IDataBaseLibrary* lib, unsigned int newLocation) = 0; - // simplifies the library renaming process - virtual bool SetLibraryName(CBaseLibrary* lib, const QString& name) = 0; - - - //Check if the file name is unique. - //Params: library: library name. NOT the file path. - virtual bool IsUniqueFilename(const QString& library) = 0; - //CONFETTI END -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IBASELIBRARYMANAGER_H diff --git a/Code/Editor/Include/IDataBaseItem.h b/Code/Editor/Include/IDataBaseItem.h deleted file mode 100644 index 6be5f49c2d..0000000000 --- a/Code/Editor/Include/IDataBaseItem.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IDATABASEITEM_H -#define CRYINCLUDE_EDITOR_INCLUDE_IDATABASEITEM_H -#pragma once - -#include -#include - -struct IDataBaseLibrary; -class CUsedResources; - -////////////////////////////////////////////////////////////////////////// -/** Base class for all items contained in BaseLibraray. -*/ -struct IDataBaseItem -{ - struct SerializeContext - { - XmlNodeRef node; - bool bUndo; - bool bLoading; - bool bCopyPaste; - bool bIgnoreChilds; - bool bUniqName; - SerializeContext() - : node(0) - , bLoading(false) - , bCopyPaste(false) - , bIgnoreChilds(false) - , bUniqName(false) - , bUndo(false) {}; - SerializeContext(XmlNodeRef _node, bool bLoad) - : node(_node) - , bLoading(bLoad) - , bCopyPaste(false) - , bIgnoreChilds(false) - , bUniqName(false) - , bUndo(false) {}; - SerializeContext(const SerializeContext& ctx) - : node(ctx.node) - , bLoading(ctx.bLoading) - , bCopyPaste(ctx.bCopyPaste) - , bIgnoreChilds(ctx.bIgnoreChilds) - , bUniqName(ctx.bUniqName) - , bUndo(ctx.bUndo) {}; - }; - - virtual EDataBaseItemType GetType() const = 0; - - //! Return Library this item are contained in. - //! Item can only be at one library. - virtual IDataBaseLibrary* GetLibrary() const = 0; - - //! Change item name. - virtual void SetName(const QString& name) = 0; - //! Get item name. - virtual const QString& GetName() const = 0; - - //! Get full item name, including name of library. - //! Name formed by adding dot after name of library - //! eg. library Pickup and item PickupRL form full item name: "Pickups.PickupRL". - virtual QString GetFullName() const = 0; - - //! Get only nameof group from prototype. - virtual QString GetGroupName() = 0; - //! Get short name of prototype without group. - virtual QString GetShortName() = 0; - - //! Serialize library item to archive. - virtual void Serialize(SerializeContext& ctx) = 0; - - //! Generate new unique id for this item. - virtual void GenerateId() = 0; - //! Returns GUID of this material. - virtual const GUID& GetGUID() const = 0; - - //! Validate item for errors. - virtual void Validate() {}; - - //! Gathers resources by this item. - virtual void GatherUsedResources([[maybe_unused]] CUsedResources& resources) {}; -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IDATABASEITEM_H diff --git a/Code/Editor/Include/IDataBaseLibrary.h b/Code/Editor/Include/IDataBaseLibrary.h deleted file mode 100644 index 75437d93e2..0000000000 --- a/Code/Editor/Include/IDataBaseLibrary.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IDATABASELIBRARY_H -#define CRYINCLUDE_EDITOR_INCLUDE_IDATABASELIBRARY_H -#pragma once - - -struct IDataBaseManager; -struct IDataBaseItem; - -class QString; -class XmlNodeRef; - -////////////////////////////////////////////////////////////////////////// -// Description: -// Interface to access specific library of editor data base. -// Ex. Archetype library, Material Library. -// See Also: -// IDataBaseItem,IDataBaseManager -////////////////////////////////////////////////////////////////////////// -struct IDataBaseLibrary -{ - // Description: - // Return IDataBaseManager interface to the manager for items stored in this library. - virtual IDataBaseManager* GetManager() = 0; - - // Description: - // Return library name. - virtual const QString& GetName() const = 0; - - // Description: - // Return filename where this library is stored. - virtual const QString& GetFilename() const = 0; - - // Description: - // Save contents of library to file. - virtual bool Save() = 0; - - // Description: - // Load library from file. - // Arguments: - // filename - Full specified library filename (relative to root game folder). - virtual bool Load(const QString& filename) = 0; - - // Description: - // Serialize library parameters and items to/from XML node. - virtual void Serialize(XmlNodeRef& node, bool bLoading) = 0; - - // Description: - // Marks library as modified, indicates that some item in library was modified. - virtual void SetModified(bool bModified = true) = 0; - - // Description: - // Check if library parameters or any items where modified. - // If any item was modified library may need saving before closing editor. - virtual bool IsModified() const = 0; - - // Description: - // Check if this library is not shared and internal to current level. - virtual bool IsLevelLibrary() const = 0; - - // Description: - // Make this library accessible only from current Level. (not shared) - virtual void SetLevelLibrary(bool bEnable) = 0; - - // Description: - // Associate a new item with the library. - // Watch out if item was already in another library. - virtual void AddItem(IDataBaseItem* pItem, bool bRegister = true) = 0; - - // Description: - // Return number of items in library. - virtual int GetItemCount() const = 0; - - // Description: - // Get item by index. - // See Also: - // GetItemCount - // Arguments: - // index - Index from 0 to GetItemCount() - virtual IDataBaseItem* GetItem(int index) = 0; - - // Description: - // Remove item from library, does not destroy item, - // only unliks it from this library, to delete item use IDataBaseManager. - // See Also: - // AddItem - virtual void RemoveItem(IDataBaseItem* item) = 0; - - // Description: - // Remove all items from library, does not destroy items, - // only unliks them from this library, to delete item use IDataBaseManager. - // See Also: - // RemoveItem,AddItem - virtual void RemoveAllItems() = 0; - - // Description: - // Find item in library by name. - // This function usually uses linear search so it is not particularry fast. - // See Also: - // GetItem - virtual IDataBaseItem* FindItem(const QString& name) = 0; - - - //CONFETTI BEGIN - // Used to change the library item order - virtual void ChangeItemOrder(CBaseLibraryItem* item, unsigned int newLocation) = 0; - //CONFETTI END -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IDATABASELIBRARY_H diff --git a/Code/Editor/Include/IDataBaseManager.h b/Code/Editor/Include/IDataBaseManager.h deleted file mode 100644 index 3d701d51fc..0000000000 --- a/Code/Editor/Include/IDataBaseManager.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IDATABASEMANAGER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IDATABASEMANAGER_H -#pragma once - -#include - -struct IDataBaseItem; -struct IDataBaseLibrary; -class CUsedResources; - -enum EDataBaseItemEvent -{ - EDB_ITEM_EVENT_ADD, - EDB_ITEM_EVENT_DELETE, - EDB_ITEM_EVENT_CHANGED, - EDB_ITEM_EVENT_SELECTED, - EDB_ITEM_EVENT_UPDATE_PROPERTIES, - EDB_ITEM_EVENT_UPDATE_PROPERTIES_NO_EDITOR_REFRESH -}; - -////////////////////////////////////////////////////////////////////////// -// Description: -// Callback class to intercept item creation and deletion events. -////////////////////////////////////////////////////////////////////////// -struct IDataBaseManagerListener -{ - virtual void OnDataBaseItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event) = 0; -}; - -////////////////////////////////////////////////////////////////////////// -// Description: -// his interface is used to enumerate al items registered to the database manager. -////////////////////////////////////////////////////////////////////////// -struct IDataBaseItemEnumerator -{ - virtual ~IDataBaseItemEnumerator() = default; - - virtual void Release() = 0; - virtual IDataBaseItem* GetFirst() = 0; - virtual IDataBaseItem* GetNext() = 0; -}; - -////////////////////////////////////////////////////////////////////////// -// -// Interface to the collection of all items or specific type -// in data base libraries. -// -////////////////////////////////////////////////////////////////////////// -struct IDataBaseManager -{ - //! Clear all libraries. - virtual void ClearAll() = 0; - - ////////////////////////////////////////////////////////////////////////// - // Library items. - ////////////////////////////////////////////////////////////////////////// - //! Make a new item in specified library. - virtual IDataBaseItem* CreateItem(IDataBaseLibrary* pLibrary) = 0; - //! Delete item from library and manager. - virtual void DeleteItem(IDataBaseItem* pItem) = 0; - - //! Find Item by its GUID. - virtual IDataBaseItem* FindItem(REFGUID guid) const = 0; - virtual IDataBaseItem* FindItemByName(const QString& fullItemName) = 0; - - virtual IDataBaseItemEnumerator* GetItemEnumerator() = 0; - - // Select one item in DB. - virtual void SetSelectedItem(IDataBaseItem* pItem) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Libraries. - ////////////////////////////////////////////////////////////////////////// - //! Add Item library. Set isLevelLibrary to true if its the "level" library which gets saved inside the level - virtual IDataBaseLibrary* AddLibrary(const QString& library, bool isLevelLibrary = false, bool bIsLoading = true) = 0; - virtual void DeleteLibrary(const QString& library, bool forceDeleteLibrary = false) = 0; - //! Get number of libraries. - virtual int GetLibraryCount() const = 0; - //! Get Item library by index. - virtual IDataBaseLibrary* GetLibrary(int index) const = 0; - - //! Find Items Library by name. - virtual IDataBaseLibrary* FindLibrary(const QString& library) = 0; - - //! Load Items library. -#ifdef LoadLibrary -#undef LoadLibrary -#endif - virtual IDataBaseLibrary* LoadLibrary(const QString& filename, bool bReload = false) = 0; - - //! Save all modified libraries. - virtual void SaveAllLibs() = 0; - - //! Serialize property manager. - virtual void Serialize(XmlNodeRef& node, bool bLoading) = 0; - - //! Export items to game. - virtual void Export([[maybe_unused]] XmlNodeRef& node) {}; - - //! Returns unique name base on input name. - virtual QString MakeUniqueItemName(const QString& name, const QString& libName = "") = 0; - virtual QString MakeFullItemName(IDataBaseLibrary* pLibrary, const QString& group, const QString& itemName) = 0; - - //! Root node where this library will be saved. - virtual QString GetRootNodeName() = 0; - //! Path to libraries in this manager. - virtual QString GetLibsPath() = 0; - - ////////////////////////////////////////////////////////////////////////// - //! Validate library items for errors. - virtual void Validate() = 0; - - // Description: - // Collects names of all resource files used by managed items. - // Arguments: - // resources - Structure where all filenames are collected. - virtual void GatherUsedResources(CUsedResources& resources) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Register listeners. - virtual void AddListener(IDataBaseManagerListener* pListener) = 0; - virtual void RemoveListener(IDataBaseManagerListener* pListener) = 0; -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IDATABASEMANAGER_H diff --git a/Code/Editor/Include/IEditorMaterial.h b/Code/Editor/Include/IEditorMaterial.h deleted file mode 100644 index 329b0ae53f..0000000000 --- a/Code/Editor/Include/IEditorMaterial.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - - -#include "BaseLibraryItem.h" -#include - -struct IEditorMaterial - : public CBaseLibraryItem -{ - virtual int GetFlags() const = 0; - virtual IMaterial* GetMatInfo(bool bUseExistingEngineMaterial = false) = 0; - virtual void DisableHighlightForFrame() = 0; -}; diff --git a/Code/Editor/Include/IEditorMaterialManager.h b/Code/Editor/Include/IEditorMaterialManager.h deleted file mode 100644 index 6f71c5ddd1..0000000000 --- a/Code/Editor/Include/IEditorMaterialManager.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#ifndef CRYINCLUDE_EDITOR_MATERIAL_IEDITORMATERIALMANAGER_H -#define CRYINCLUDE_EDITOR_MATERIAL_IEDITORMATERIALMANAGER_H -#pragma once - -#include -#include - - -struct IEditorMaterialManager -{ - virtual void GotoMaterial(IMaterial* pMaterial) = 0; -}; - -#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H diff --git a/Code/Editor/Include/IErrorReport.h b/Code/Editor/Include/IErrorReport.h index 7bf00d6973..c409dbc7dd 100644 --- a/Code/Editor/Include/IErrorReport.h +++ b/Code/Editor/Include/IErrorReport.h @@ -14,7 +14,6 @@ // forward declarations. class CParticleItem; class CBaseObject; -class CBaseLibraryItem; class CErrorRecord; class QString; @@ -52,9 +51,6 @@ struct IErrorReport //! Assign current Object to which new reported warnings are assigned. virtual void SetCurrentValidatorObject(CBaseObject* pObject) = 0; - //! Assign current Item to which new reported warnings are assigned. - virtual void SetCurrentValidatorItem(CBaseLibraryItem* pItem) = 0; - //! Assign current filename. virtual void SetCurrentFile(const QString& file) = 0; }; diff --git a/Code/Editor/Lib/Tests/IEditorMock.h b/Code/Editor/Lib/Tests/IEditorMock.h index 590f98e6d7..aaee34c2c6 100644 --- a/Code/Editor/Lib/Tests/IEditorMock.h +++ b/Code/Editor/Lib/Tests/IEditorMock.h @@ -85,9 +85,6 @@ public: MOCK_METHOD0(IsSelectionLocked, bool()); MOCK_METHOD0(GetObjectManager, struct IObjectManager* ()); MOCK_METHOD0(GetSettingsManager, CSettingsManager* ()); - MOCK_METHOD1(GetDBItemManager, IDataBaseManager* (EDataBaseItemType)); - MOCK_METHOD0(GetMaterialManagerLibrary, IBaseLibraryManager* ()); - MOCK_METHOD0(GetIEditorMaterialManager, IEditorMaterialManager* ()); MOCK_METHOD0(GetIconManager, IIconManager* ()); MOCK_METHOD0(GetMusicManager, CMusicManager* ()); MOCK_METHOD2(GetTerrainElevation, float(float , float )); diff --git a/Code/Editor/TrackView/TrackViewSequenceManager.cpp b/Code/Editor/TrackView/TrackViewSequenceManager.cpp index d7c1e3c709..515af4df38 100644 --- a/Code/Editor/TrackView/TrackViewSequenceManager.cpp +++ b/Code/Editor/TrackView/TrackViewSequenceManager.cpp @@ -408,20 +408,6 @@ void CTrackViewSequenceManager::OnSequenceRemoved(CTrackViewSequence* sequence) } } -//////////////////////////////////////////////////////////////////////////// -void CTrackViewSequenceManager::OnDataBaseItemEvent([[maybe_unused]] IDataBaseItem* pItem, EDataBaseItemEvent event) -{ - if (event != EDataBaseItemEvent::EDB_ITEM_EVENT_ADD) - { - const size_t numSequences = m_sequences.size(); - - for (size_t i = 0; i < numSequences; ++i) - { - m_sequences[i]->UpdateDynamicParams(); - } - } -} - //////////////////////////////////////////////////////////////////////////// CTrackViewAnimNodeBundle CTrackViewSequenceManager::GetAllRelatedAnimNodes(const AZ::EntityId entityId) const { diff --git a/Code/Editor/TrackView/TrackViewSequenceManager.h b/Code/Editor/TrackView/TrackViewSequenceManager.h index 1474323dc6..6c65a7f1a9 100644 --- a/Code/Editor/TrackView/TrackViewSequenceManager.h +++ b/Code/Editor/TrackView/TrackViewSequenceManager.h @@ -13,13 +13,11 @@ #include "TrackViewSequence.h" -#include "IDataBaseManager.h" #include class CTrackViewSequenceManager : public IEditorNotifyListener - , public IDataBaseManagerListener , public ITrackViewSequenceManager , public AZ::EntitySystemBus::Handler { @@ -65,8 +63,6 @@ private: void OnSequenceAdded(CTrackViewSequence* pSequence); void OnSequenceRemoved(CTrackViewSequence* pSequence); - void OnDataBaseItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event) override; - // AZ::EntitySystemBus void OnEntityNameChanged(const AZ::EntityId& entityId, const AZStd::string& name) override; void OnEntityDestruction(const AZ::EntityId& entityId) override; diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h index a71df6a9cd..1b0e5a4d93 100644 --- a/Code/Editor/Viewport.h +++ b/Code/Editor/Viewport.h @@ -46,7 +46,6 @@ struct HitContext; struct IRenderListener; class CImageEx; class QMenu; -struct IDataBaseItem; /** Type of viewport. */ @@ -230,8 +229,6 @@ public: // Drag and drop support on viewports. // To be overrided in derived classes. ////////////////////////////////////////////////////////////////////////// - virtual bool CanDrop([[maybe_unused]] const QPoint& point, [[maybe_unused]] IDataBaseItem* pItem) { return false; }; - virtual void Drop([[maybe_unused]] const QPoint& point, [[maybe_unused]] IDataBaseItem* pItem) {}; virtual void SetGlobalDropCallback(DropCallback dropCallback, void* dropCallbackCustom) { m_dropCallback = dropCallback; diff --git a/Code/Editor/editor_core_files.cmake b/Code/Editor/editor_core_files.cmake index 53dd8d79a5..1f0a5a3618 100644 --- a/Code/Editor/editor_core_files.cmake +++ b/Code/Editor/editor_core_files.cmake @@ -7,17 +7,12 @@ # set(FILES - BaseLibrary.h - BaseLibraryItem.h UsedResources.h UIEnumsDatabase.h Include/EditorCoreAPI.cpp Include/IErrorReport.h - Include/IBaseLibraryManager.h Include/IFileUtil.h Include/EditorCoreAPI.h - Include/IEditorMaterial.h - Include/IEditorMaterialManager.h Include/IImageUtil.h Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.qrc Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp @@ -35,8 +30,6 @@ set(FILES Controls/QBitmapPreviewDialogImp.h Controls/QToolTipWidget.h Controls/QToolTipWidget.cpp - BaseLibraryItem.cpp - BaseLibrary.cpp UsedResources.cpp UIEnumsDatabase.cpp LyViewPaneNames.h diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index c81a326aff..59a1a91647 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -271,9 +271,6 @@ set(FILES Include/HitContext.h Include/ICommandManager.h Include/IConsoleConnectivity.h - Include/IDataBaseItem.h - Include/IDataBaseLibrary.h - Include/IDataBaseManager.h Include/IDisplayViewport.h Include/IEditorClassFactory.h Include/IEventLoopHook.h @@ -369,9 +366,6 @@ set(FILES ActionManager.h ShortcutDispatcher.cpp ShortcutDispatcher.h - BaseLibraryManager.cpp - BaseLibraryItem.h - BaseLibraryManager.h CheckOutDialog.cpp CheckOutDialog.h CheckOutDialog.ui From 353d4bb2bb7515c2ee4e05b175626abb2c16cbaf Mon Sep 17 00:00:00 2001 From: Allen Jackson <23512001+jackalbe@users.noreply.github.com> Date: Thu, 6 Jan 2022 11:47:04 -0600 Subject: [PATCH 091/272] {lyn8938} looks into the asset database to detect products (#6709) Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com> --- .../PythonAssetBuilder/AssetBuilder_test.py | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py index 45e633a979..cb2c445246 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py @@ -12,12 +12,36 @@ import sys import os import pytest import logging +import sqlite3 pytest.importorskip('ly_test_tools') import ly_test_tools.environment.file_system as file_system import ly_test_tools.log.log_monitor import ly_test_tools.environment.waiter as waiter +def detect_product(sql_connection, platform, target): + cur = sql_connection.cursor() + product_target = f'{platform}/{target}' + print(f'Detecting {product_target} in assetdb.sqlite') + hits = 0 + for row in cur.execute(f'select ProductID from Products where ProductName is "{product_target}"'): + hits = hits + 1 + assert hits == 1 + + +def find_products(cache_folder, platform): + con = sqlite3.connect(os.path.join(cache_folder, 'assetdb.sqlite')) + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel') + detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel') + con.close() + + @pytest.mark.SUITE_periodic @pytest.mark.parametrize('launcher_platform', ['windows_editor']) @pytest.mark.parametrize('project', ['AutomatedTesting']) @@ -25,16 +49,7 @@ import ly_test_tools.environment.waiter as waiter class TestPythonAssetProcessing(object): def test_DetectPythonCreatedAsset(self, request, editor, level, launcher_platform): unexpected_lines = [] - expected_lines = [ - 'Mock asset exists', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found', - 'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found' - ] + expected_lines = [] timeout = 180 halt_on_unexpected = False test_directory = os.path.join(os.path.dirname(__file__)) @@ -50,3 +65,9 @@ class TestPythonAssetProcessing(object): exc=("Log file '{}' was never opened by another process.".format(editorlog_file)), interval=1) log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout) + + cache_folder = editor.workspace.paths.cache() + platform = editor.workspace.asset_processor_platform + if platform == 'windows': + platform = 'pc' + find_products(cache_folder, platform) From e5c2d574fc06a377a6015b7d49f34dbc9806ffc9 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Thu, 6 Jan 2022 12:51:10 -0600 Subject: [PATCH 092/272] Added a missing include and forward declare Signed-off-by: Chris Galvan --- Code/Editor/Objects/EntityObject.h | 1 + Code/Editor/TrackView/TrackViewSequence.h | 1 + 2 files changed, 2 insertions(+) diff --git a/Code/Editor/Objects/EntityObject.h b/Code/Editor/Objects/EntityObject.h index c3e379bccc..c6b7e4ce2d 100644 --- a/Code/Editor/Objects/EntityObject.h +++ b/Code/Editor/Objects/EntityObject.h @@ -27,6 +27,7 @@ #define CLASS_ENVIRONMENT_LIGHT "EnvironmentLight" class CEntityObject; +class CSelectionGroup; class QMenu; /*! diff --git a/Code/Editor/TrackView/TrackViewSequence.h b/Code/Editor/TrackView/TrackViewSequence.h index a392ad00f9..8f686af0cb 100644 --- a/Code/Editor/TrackView/TrackViewSequence.h +++ b/Code/Editor/TrackView/TrackViewSequence.h @@ -11,6 +11,7 @@ #define CRYINCLUDE_EDITOR_TRACKVIEW_TRACKVIEWSEQUENCE_H #pragma once +#include #include "IMovieSystem.h" #include From 603967d61f62b09688d5f30c87edd86074452519 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 6 Jan 2022 11:04:54 -0800 Subject: [PATCH 093/272] Fixed build issues with Spawnable Entity Aliases. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> --- Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp | 5 ++++- Gems/Prefab/PrefabBuilder/PrefabBuilderTests.cpp | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp b/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp index 42a817987e..aef13fbfe2 100644 --- a/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp +++ b/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp @@ -57,6 +57,7 @@ namespace UnitTest TEST_F(PrefabProcessingTestFixture, NetworkPrefabProcessor_ProcessPrefabTwoEntities_NetEntityGoesToNetSpawnable) { using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext; + using AzToolsFramework::Prefab::PrefabConversionUtils::PrefabDocument; AZStd::vector entities; @@ -74,7 +75,9 @@ namespace UnitTest // Add the prefab into the Prefab Processor Context const AZStd::string prefabName = "testPrefab"; PrefabProcessorContext prefabProcessorContext{AZ::Uuid::CreateRandom()}; - prefabProcessorContext.AddPrefab(prefabName, AZStd::move(prefabDom)); + PrefabDocument document(prefabName); + ASSERT_TRUE(document.SetPrefabDom(AZStd::move(prefabDom))); + prefabProcessorContext.AddPrefab(AZStd::move(document)); // Request NetworkPrefabProcessor to process the prefab Multiplayer::NetworkPrefabProcessor processor; diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderTests.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderTests.cpp index 2ed05b4dfe..5ee23a9e3c 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderTests.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderTests.cpp @@ -106,7 +106,8 @@ namespace UnitTest AzToolsFramework::Prefab::PrefabDom prefabDom; prefabDom.CopyFrom(prefabSystemComponentInterface->FindTemplateDom(parentInstance->GetTemplateId()), prefabDom.GetAllocator(), false); - ASSERT_TRUE(prefabBuilderComponent.ProcessPrefab({AZ::Crc32("pc")}, "parent.prefab", "unused", AZ::Uuid(), prefabDom, jobProducts)); + ASSERT_TRUE(prefabBuilderComponent.ProcessPrefab( + { AZ::Crc32("pc") }, "parent.prefab", "unused", AZ::Uuid(), AZStd::move(prefabDom), jobProducts)); ASSERT_EQ(jobProducts.size(), 1); ASSERT_EQ(jobProducts[0].m_dependencies.size(), 1); From 7b172667cfe321982b7594bc70fe530bf60604a9 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Thu, 6 Jan 2022 13:13:00 -0600 Subject: [PATCH 094/272] Adding info lines for debugging File Menu tests and waits during drag and drop operations in Docking test Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../editor/EditorScripts/Docking_BasicDockedTools.py | 9 ++++++--- .../editor/EditorScripts/Menus_EditMenuOptions.py | 1 + .../editor/EditorScripts/Menus_FileMenuOptions.py | 1 + .../editor/EditorScripts/Menus_ViewMenuOptions.py | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py index d83db7d90c..8734769225 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py @@ -85,22 +85,25 @@ def Docking_BasicDockedTools(): # We drag/drop it over the viewport since it doesn't allow docking, so this will undock it render_overlay = editor_window.findChild(QtWidgets.QWidget, "renderOverlay") pyside_utils.drag_and_drop(entity_outliner, render_overlay) - + general.idle_wait(0.5) + # We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved - # to the floating window, its parent changes so the wrapped intance we had becomes invalid + # to the floating window, its parent changes so the wrapped instance we had becomes invalid entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") # Dock the Entity Inspector tabbed with the floating Entity Outliner entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") pyside_utils.drag_and_drop(entity_inspector, entity_outliner) + general.idle_wait(0.5) # We need to grab a new reference to the Entity Inspector QDockWidget because when it gets moved - # to the floating window, its parent changes so the wrapped intance we had becomes invalid + # to the floating window, its parent changes so the wrapped instance we had becomes invalid entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") # Dock the Console tabbed with the floating Entity Inspector console = editor_window.findChild(QtWidgets.QDockWidget, "Console") pyside_utils.drag_and_drop(console, entity_inspector) + general.idle_wait(0.5) # Check to ensure all the tools are parented to the same QStackedWidget def check_all_panes_tabbed(): diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index 7d72d76776..0536575893 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -64,6 +64,7 @@ def Menus_EditMenuOptions_Work(): for option in edit_menu_options: try: action = pyside_utils.get_action_for_menu_path(editor_window, "Edit", *option) + Report.info(f"Triggering {action.iconText()}") action.trigger() action_triggered = True except Exception as e: diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index cade2125e2..a4e702cbd1 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -53,6 +53,7 @@ def Menus_FileMenuOptions_Work(): for option in file_menu_options: try: action = pyside_utils.get_action_for_menu_path(editor_window, "File", *option) + Report.info(f"Triggering {action.iconText()}") action.trigger() action_triggered = True except Exception as e: diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py index 2d92fdb97c..e2ee3e2a55 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py @@ -52,6 +52,7 @@ def Menus_ViewMenuOptions_Work(): for option in view_menu_options: try: action = pyside_utils.get_action_for_menu_path(editor_window, "View", *option) + Report.info(f"Triggering {action.iconText()}") action.trigger() action_triggered = True except Exception as e: From 53e6f0f99f44430ccdc7bde0518fc3f8e11a4cd8 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Thu, 6 Jan 2022 13:27:44 -0600 Subject: [PATCH 095/272] Added another missing include Signed-off-by: Chris Galvan --- Code/Editor/ErrorReport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Editor/ErrorReport.h b/Code/Editor/ErrorReport.h index 7e2a57a421..a80bb36404 100644 --- a/Code/Editor/ErrorReport.h +++ b/Code/Editor/ErrorReport.h @@ -18,6 +18,7 @@ class CParticleItem; #include "Objects/BaseObject.h" +#include "Include/EditorCoreAPI.h" #include "Include/IErrorReport.h" #include "ErrorRecorder.h" From d3b36f18148744d477d751c628e647f11a3efd59 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Thu, 6 Jan 2022 13:55:52 -0600 Subject: [PATCH 096/272] Added a couple more missing includes Signed-off-by: Chris Galvan --- Code/Editor/ErrorReport.h | 3 +++ Code/Editor/Objects/ObjectLoader.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Code/Editor/ErrorReport.h b/Code/Editor/ErrorReport.h index a80bb36404..98d230e383 100644 --- a/Code/Editor/ErrorReport.h +++ b/Code/Editor/ErrorReport.h @@ -17,6 +17,9 @@ // forward declarations. class CParticleItem; +#include +#include + #include "Objects/BaseObject.h" #include "Include/EditorCoreAPI.h" #include "Include/IErrorReport.h" diff --git a/Code/Editor/Objects/ObjectLoader.h b/Code/Editor/Objects/ObjectLoader.h index fc1014ad03..fa576fa983 100644 --- a/Code/Editor/Objects/ObjectLoader.h +++ b/Code/Editor/Objects/ObjectLoader.h @@ -13,6 +13,8 @@ #include "ErrorReport.h" #include +#include + class CErrorRecord; struct IObjectManager; From 741a9059f6540f44c252edeb5780c592efe18c9c Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 6 Jan 2022 12:13:23 -0800 Subject: [PATCH 097/272] More packaging cleanup (#6728) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../build/Platform/Android/build_config.json | 10 ---------- scripts/build/Platform/Android/pipeline.json | 3 --- scripts/build/Platform/Linux/pipeline.json | 3 --- scripts/build/Platform/Mac/build_config.json | 10 ---------- scripts/build/Platform/Mac/pipeline.json | 3 --- .../build/Platform/Windows/build_config.json | 20 ------------------- scripts/build/Platform/Windows/pipeline.json | 3 --- scripts/build/Platform/iOS/pipeline.json | 3 --- 8 files changed, 55 deletions(-) diff --git a/scripts/build/Platform/Android/build_config.json b/scripts/build/Platform/Android/build_config.json index 06fa1ffb5f..7a7e90c0b0 100644 --- a/scripts/build/Platform/Android/build_config.json +++ b/scripts/build/Platform/Android/build_config.json @@ -41,16 +41,6 @@ "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" } }, - "android_packaging_all": { - "TAGS": [ - "packaging" - ], - "COMMAND": "../Windows/python_windows.cmd", - "PARAMETERS": { - "SCRIPT_PATH": "scripts/build/package/package.py", - "SCRIPT_PARAMETERS": "--platform Android --type all" - } - }, "profile": { "TAGS":[ "weekly-build-metrics", diff --git a/scripts/build/Platform/Android/pipeline.json b/scripts/build/Platform/Android/pipeline.json index 230d5d3477..f0292f4501 100644 --- a/scripts/build/Platform/Android/pipeline.json +++ b/scripts/build/Platform/Android/pipeline.json @@ -12,9 +12,6 @@ "daily-pipeline-metrics": { "CLEAN_WORKSPACE": true }, - "packaging": { - "CLEAN_WORKSPACE": true - }, "nightly-clean": { "CLEAN_WORKSPACE": true } diff --git a/scripts/build/Platform/Linux/pipeline.json b/scripts/build/Platform/Linux/pipeline.json index d10e2886f2..e9667d312d 100644 --- a/scripts/build/Platform/Linux/pipeline.json +++ b/scripts/build/Platform/Linux/pipeline.json @@ -10,9 +10,6 @@ "daily-pipeline-metrics": { "CLEAN_WORKSPACE": true }, - "packaging": { - "CLEAN_WORKSPACE": true - }, "nightly-clean": { "CLEAN_WORKSPACE": true } diff --git a/scripts/build/Platform/Mac/build_config.json b/scripts/build/Platform/Mac/build_config.json index fb960a96fa..6ba264cdb2 100644 --- a/scripts/build/Platform/Mac/build_config.json +++ b/scripts/build/Platform/Mac/build_config.json @@ -153,16 +153,6 @@ "CMAKE_TARGET": "ALL_BUILD" } }, - "mac_packaging_all": { - "TAGS": [ - "packaging" - ], - "COMMAND": "python_mac.sh", - "PARAMETERS": { - "SCRIPT_PATH": "scripts/build/package/package.py", - "SCRIPT_PARAMETERS": "--platform Mac --type all" - } - }, "install_profile": { "TAGS": [], "COMMAND": "build_mac.sh", diff --git a/scripts/build/Platform/Mac/pipeline.json b/scripts/build/Platform/Mac/pipeline.json index e8cea0f06d..24f42a0c69 100644 --- a/scripts/build/Platform/Mac/pipeline.json +++ b/scripts/build/Platform/Mac/pipeline.json @@ -10,9 +10,6 @@ "daily-pipeline-metrics": { "CLEAN_WORKSPACE": true }, - "packaging": { - "CLEAN_WORKSPACE": true - }, "nightly-clean": { "CLEAN_WORKSPACE": true } diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index c591ca0eac..e3d5a4a3fc 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -59,26 +59,6 @@ "SCRIPT_PARAMETERS": "--platform=Windows --repository=%REPOSITORY_NAME% --jobname=%JOB_NAME% --jobnumber=%BUILD_NUMBER% --jobnode=%NODE_LABEL% --changelist=%CHANGE_ID%" } }, - "windows_packaging_all": { - "TAGS": [ - "packaging" - ], - "COMMAND": "python_windows.cmd", - "PARAMETERS": { - "SCRIPT_PATH": "scripts/build/package/package.py", - "SCRIPT_PARAMETERS": "--platform Windows --type all" - } - }, - "3rdParty_all": { - "TAGS": [ - "packaging" - ], - "COMMAND": "python_windows.cmd", - "PARAMETERS": { - "SCRIPT_PATH": "scripts/build/package/package.py", - "SCRIPT_PARAMETERS": "--platform 3rdParty --type 3rdParty_all" - } - }, "test_impact_analysis_profile": { "TAGS": [ ], diff --git a/scripts/build/Platform/Windows/pipeline.json b/scripts/build/Platform/Windows/pipeline.json index b18a1e8c63..28d8437408 100644 --- a/scripts/build/Platform/Windows/pipeline.json +++ b/scripts/build/Platform/Windows/pipeline.json @@ -10,9 +10,6 @@ "daily-pipeline-metrics": { "CLEAN_WORKSPACE": true }, - "packaging": { - "CLEAN_WORKSPACE": true - }, "nightly-clean": { "CLEAN_WORKSPACE": true } diff --git a/scripts/build/Platform/iOS/pipeline.json b/scripts/build/Platform/iOS/pipeline.json index a5e2ff710e..369152a7a4 100644 --- a/scripts/build/Platform/iOS/pipeline.json +++ b/scripts/build/Platform/iOS/pipeline.json @@ -10,9 +10,6 @@ "daily-pipeline-metrics": { "CLEAN_WORKSPACE": true }, - "packaging": { - "CLEAN_WORKSPACE": true - }, "nightly-clean": { "CLEAN_WORKSPACE": true } From ad9bcba6e283d0d935473dea04fe2894689b4001 Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Thu, 6 Jan 2022 13:17:48 -0800 Subject: [PATCH 098/272] [Linux] Update to use AWSNativeSDK 1.9.50 (#6715) --- Gems/AWSCore/Code/Platform/Linux/AWSCore_Traits_Linux.h | 2 +- cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/AWSCore/Code/Platform/Linux/AWSCore_Traits_Linux.h b/Gems/AWSCore/Code/Platform/Linux/AWSCore_Traits_Linux.h index d7b1f32461..2cacfb0d34 100644 --- a/Gems/AWSCore/Code/Platform/Linux/AWSCore_Traits_Linux.h +++ b/Gems/AWSCore/Code/Platform/Linux/AWSCore_Traits_Linux.h @@ -7,4 +7,4 @@ */ #pragma once -#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 0 +#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 1 diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index 109ae75f38..f7bc2721ae 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -24,7 +24,7 @@ ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform ly_associate_package(PACKAGE_NAME AWSGameLiftServerSDK-3.4.1-rev1-linux TARGETS AWSGameLiftServerSDK PACKAGE_HASH a8149a95bd100384af6ade97e2b21a56173740d921e6c3da8188cd51554d39af) ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-linux TARGETS TIFF PACKAGE_HASH 2377f48b2ebc2d1628d9f65186c881544c92891312abe478a20d10b85877409a) ly_associate_package(PACKAGE_NAME freetype-2.10.4.16-linux TARGETS freetype PACKAGE_HASH 3f10c703d9001ecd2bb51a3bd003d3237c02d8f947ad0161c0252fdc54cbcf97) -ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev6-linux TARGETS AWSNativeSDK PACKAGE_HASH 490291e4c8057975c3ab86feb971b8a38871c58bac5e5d86abdd1aeb7141eec4) +ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.9.50-rev1-linux TARGETS AWSNativeSDK PACKAGE_HASH f30b6969c6732a7c1a23a59d205a150633a7f219dcb60d837b543888d2c63ea1) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-linux TARGETS Lua PACKAGE_HASH 1adc812abe3dd0dbb2ca9756f81d8f0e0ba45779ac85bf1d8455b25c531a38b0) ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev5-linux TARGETS PhysX PACKAGE_HASH fa72365df409376aef02d1763194dc91d255bdfcb4e8febcfbb64d23a3e50b96) ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.2-rev1-linux TARGETS mcpp PACKAGE_HASH df7a998d0bc3fedf44b5bdebaf69ddad6033355b71a590e8642445ec77bc6c41) From f1c8fbe7c07fadb288466909877f8a445b04e469 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Thu, 6 Jan 2022 13:45:54 -0800 Subject: [PATCH 099/272] remove std and replace with az Signed-off-by: mrieggeramzn --- .../Tests/PropertyIntCtrlCommonTests.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h index 1bd6f72a19..6710d4b7cd 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h @@ -113,19 +113,17 @@ namespace UnitTest auto& widget = m_widget; auto& handler = m_handler; QString tooltip; - std::stringstream expected; // Retrieve the tooltip string for this widget auto success = handler->ModifyTooltip(widget, tooltip); const QString minString = QLocale().toString(widget->minimum()); const QString maxString = QLocale().toString(widget->maximum()); - - expected << "[" << minString.toStdString() << ", " << maxString.toStdString() << "]"; + const AZStd::string expected = AZStd::string::format("[%d, %d]", minString.toStdString().c_str(), maxString.toStdString().c_str()); // Expect the operation to be successful and a valid limit tooltip string generated EXPECT_TRUE(success); - EXPECT_STREQ(tooltip.toStdString().c_str(), expected.str().c_str()); + EXPECT_STREQ(tooltip.toStdString().c_str(), expected.c_str()); } void HandlerMinMaxLessLimit_ModifyHandler_ExpectSuccessAndValidLessLimitToolTipString() @@ -134,7 +132,6 @@ namespace UnitTest auto& widget = m_widget; auto& handler = m_handler; QString tooltip; - std::stringstream expected; // That is not at the extremeties of the type range limit SetWidgetRangeToNonExtremeties(widget); @@ -145,11 +142,11 @@ namespace UnitTest const QString minString = QLocale().toString(widget->minimum()); const QString maxString = QLocale().toString(widget->maximum()); - expected << "[" << minString.toStdString() << ", " << maxString.toStdString() << "]"; + const AZStd::string expected = AZStd::string::format("[%d, %d]", minString.toStdString().c_str(), maxString.toStdString().c_str()); // Expect the operation to be successful and a valid less than limit tooltip string generated EXPECT_TRUE(success); - EXPECT_STREQ(tooltip.toStdString().c_str(), expected.str().c_str()); + EXPECT_STREQ(tooltip.toStdString().c_str(), expected.c_str()); } void EmitWidgetValueChanged() From 273d6e225aaf76436566cdfb56f53a6f1000e15b Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Thu, 6 Jan 2022 14:00:33 -0800 Subject: [PATCH 100/272] Previous commit wasnt correct. Should be using a string not a int Signed-off-by: mrieggeramzn --- .../AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h index 6710d4b7cd..b73e9e0a26 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h @@ -119,7 +119,7 @@ namespace UnitTest const QString minString = QLocale().toString(widget->minimum()); const QString maxString = QLocale().toString(widget->maximum()); - const AZStd::string expected = AZStd::string::format("[%d, %d]", minString.toStdString().c_str(), maxString.toStdString().c_str()); + const AZStd::string expected = AZStd::string::format("[%s, %s]", minString.toStdString().c_str(), maxString.toStdString().c_str()); // Expect the operation to be successful and a valid limit tooltip string generated EXPECT_TRUE(success); @@ -142,7 +142,7 @@ namespace UnitTest const QString minString = QLocale().toString(widget->minimum()); const QString maxString = QLocale().toString(widget->maximum()); - const AZStd::string expected = AZStd::string::format("[%d, %d]", minString.toStdString().c_str(), maxString.toStdString().c_str()); + const AZStd::string expected = AZStd::string::format("[%s, %s]", minString.toStdString().c_str(), maxString.toStdString().c_str()); // Expect the operation to be successful and a valid less than limit tooltip string generated EXPECT_TRUE(success); From 39edcd06e4cee7ad222e518a1a103c7e87e1608f Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Thu, 6 Jan 2022 16:51:40 -0700 Subject: [PATCH 101/272] Add missing `precise` attribute to depth prepass output Commit 67689d48cc0f142eccd4856b0686277b49ca42d0 enforced precision in many vertex position outputs. This adds the attribute to the output of the z-prepass, needed to ensure proper depth testing in the forward passes. Signed-off-by: Jeremy Ong --- .../Feature/Common/Assets/Shaders/Depth/DepthPassCommon.azsli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Depth/DepthPassCommon.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/Depth/DepthPassCommon.azsli index f658dd13da..ba06dada74 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Depth/DepthPassCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Depth/DepthPassCommon.azsli @@ -17,7 +17,7 @@ struct VSInput struct VSDepthOutput { - float4 m_position : SV_Position; + precise float4 m_position : SV_Position; }; VSDepthOutput DepthPassVS(VSInput IN) From 54e0b8b7b5d7ad8a7c888ac82297e1284d883518 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 6 Jan 2022 16:16:48 -0800 Subject: [PATCH 102/272] Enabling mac tests (#6716) * Adds mac test job Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Points to sysctl properly to handle zsh Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fixes some macos differences with Linux when reading the CTEST_RUN_FLAGS parameters Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * adding the test job to the profile pipe Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Disables some tests in Mac that are not passing Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * passes config to cli_test_driver and sets the right trait for the test (pytest instead of lytesttools) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Set proper traits for AtomRHI Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Corrected AZ_TRAIT_UNIT_TEST_PERLINE_GRADIANT_GOLDEN_VALUES_7878 values for Mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Disables EMotionFX tests in Mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Removes debugging prints Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Removes filters that were meant just for Linux Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * quotes are re-quoted in the test_mac.sh script Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../AzTest/Platform/Mac/AzTest_Traits_Mac.h | 11 +++++---- .../Mac/ProjectManager_Test_Traits_Mac.h | 2 +- .../Mac/AtomRHITests_traits_mac.cmake | 2 +- scripts/build/Platform/Mac/build_config.json | 23 +++++++++++++++--- scripts/build/Platform/Mac/build_mac.sh | 4 ++-- scripts/build/Platform/Mac/test_mac.sh | 5 ++-- scripts/ctest/CMakeLists.txt | 24 +++++++++---------- scripts/ctest/ctest_driver_test.py | 9 ++++--- 8 files changed, 52 insertions(+), 28 deletions(-) diff --git a/Code/Framework/AzTest/AzTest/Platform/Mac/AzTest_Traits_Mac.h b/Code/Framework/AzTest/AzTest/Platform/Mac/AzTest_Traits_Mac.h index 4915fb9cab..23ea87cd1c 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Mac/AzTest_Traits_Mac.h +++ b/Code/Framework/AzTest/AzTest/Platform/Mac/AzTest_Traits_Mac.h @@ -16,9 +16,12 @@ #define AZ_TRAIT_DISABLE_ASSET_JOB_PARALLEL_TESTS true #define AZ_TRAIT_DISABLE_ASSET_MANAGER_FLOOD_TEST true #define AZ_TRAIT_DISABLE_ASSETCONTAINERDISABLETEST true +#define AZ_TRAIT_DISABLE_FAILED_DLL_TESTS true +#define AZ_TRAIT_DISABLE_FAILED_MODULE_TESTS true +#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true // Golden perline gradiant values for random seed 7878 for this platform -#define AZ_TRAIT_UNIT_TEST_PERLINE_GRADIANT_GOLDEN_VALUES_7878 0.5000f, 0.5456f, 0.5138f, 0.4801f, \ - 0.4174f, 0.4942f, 0.5493f, 0.5431f, \ - 0.4984f, 0.5204f, 0.5526f, 0.5840f, \ - 0.5251f, 0.5029f, 0.6153f, 0.5802f, +#define AZ_TRAIT_UNIT_TEST_PERLINE_GRADIANT_GOLDEN_VALUES_7878 0.5000f, 0.5276f, 0.5341f, 0.4801f, \ + 0.5220f, 0.5162f, 0.4828f, 0.5431f, \ + 0.4799f, 0.4486f, 0.5054f, 0.4129f, \ + 0.6023f, 0.5029f, 0.4529f, 0.4428f, diff --git a/Code/Tools/ProjectManager/Platform/Mac/ProjectManager_Test_Traits_Mac.h b/Code/Tools/ProjectManager/Platform/Mac/ProjectManager_Test_Traits_Mac.h index 8d7fe068c2..3ebe7d8e44 100644 --- a/Code/Tools/ProjectManager/Platform/Mac/ProjectManager_Test_Traits_Mac.h +++ b/Code/Tools/ProjectManager/Platform/Mac/ProjectManager_Test_Traits_Mac.h @@ -8,4 +8,4 @@ #pragma once -#define AZ_TRAIT_DISABLE_FAILED_PROJECT_MANAGER_TESTS false +#define AZ_TRAIT_DISABLE_FAILED_PROJECT_MANAGER_TESTS true diff --git a/Gems/Atom/RHI/Code/Platform/Mac/AtomRHITests_traits_mac.cmake b/Gems/Atom/RHI/Code/Platform/Mac/AtomRHITests_traits_mac.cmake index 419331db3b..4645eb9444 100644 --- a/Gems/Atom/RHI/Code/Platform/Mac/AtomRHITests_traits_mac.cmake +++ b/Gems/Atom/RHI/Code/Platform/Mac/AtomRHITests_traits_mac.cmake @@ -6,6 +6,6 @@ # # -set(ATOM_RHI_TRAIT_BUILD_SUPPORTS_TEST TRUE) +set(ATOM_RHI_TRAIT_BUILD_SUPPORTS_TEST FALSE) set(ATOM_RHI_TRAIT_BUILD_SUPPORTS_EDIT TRUE) set(PAL_TRAIT_BUILD_RENDERDOC_SUPPORTED FALSE) diff --git a/scripts/build/Platform/Mac/build_config.json b/scripts/build/Platform/Mac/build_config.json index 6ba264cdb2..6147f70f0c 100644 --- a/scripts/build/Platform/Mac/build_config.json +++ b/scripts/build/Platform/Mac/build_config.json @@ -14,7 +14,8 @@ ], "steps": [ "profile", - "asset_profile" + "asset_profile", + "test_profile" ] }, "metrics": { @@ -89,6 +90,22 @@ "ASSET_PROCESSOR_PLATFORMS": "mac" } }, + "test_profile": { + "TAGS": [ + "daily-pipeline-metrics", + "weekly-build-metrics" + ], + "COMMAND": "build_test_mac.sh", + "PARAMETERS": { + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build/mac", + "CMAKE_OPTIONS": "-G Xcode", + "CMAKE_LY_PROJECTS": "AutomatedTesting", + "CMAKE_TARGET": "ALL_BUILD", + "CTEST_OPTIONS": "-L (SUITE_smoke|SUITE_main) -LE (REQUIRES_gpu) --no-tests=error", + "TEST_RESULTS": "False" + } + }, "periodic_test_profile": { "TAGS": [ "nightly-incremental", @@ -102,7 +119,7 @@ "CMAKE_OPTIONS": "-G Xcode", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_periodic", - "CTEST_OPTIONS": "-L \"(SUITE_periodic)\"", + "CTEST_OPTIONS": "-L (SUITE_periodic)", "TEST_RESULTS": "False" } }, @@ -119,7 +136,7 @@ "CMAKE_OPTIONS": "-G Xcode", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_benchmark", - "CTEST_OPTIONS": "-L \"(SUITE_benchmark)\"", + "CTEST_OPTIONS": "-L (SUITE_benchmark)", "TEST_RESULTS": "False" } }, diff --git a/scripts/build/Platform/Mac/build_mac.sh b/scripts/build/Platform/Mac/build_mac.sh index 2ea5eeab8a..d6a66fc6c6 100755 --- a/scripts/build/Platform/Mac/build_mac.sh +++ b/scripts/build/Platform/Mac/build_mac.sh @@ -48,7 +48,7 @@ if [[ ! -z "$RUN_CONFIGURE" ]]; then echo "${CONFIGURE_CMD}" > ${LAST_CONFIGURE_CMD_FILE} fi -echo [ci_build] cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS} -cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS} +echo [ci_build] cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(/usr/sbin/sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS} +cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(/usr/sbin/sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS} popd diff --git a/scripts/build/Platform/Mac/test_mac.sh b/scripts/build/Platform/Mac/test_mac.sh index e398de3061..46dffab84d 100755 --- a/scripts/build/Platform/Mac/test_mac.sh +++ b/scripts/build/Platform/Mac/test_mac.sh @@ -19,8 +19,9 @@ fi pushd $OUTPUT_DIRECTORY # Find the CTEST_RUN_FLAGS from the CMakeCache.txt file, then replace the $ with the current configuration -IFS='=' read -ra CTEST_RUN_FLAGS <<< $(cmake -N -LA . | grep "CTEST_RUN_FLAGS:STRING") -CTEST_RUN_FLAGS=${CTEST_RUN_FLAGS[1]/$/${CONFIGURATION}} +CTEST_RUN_FLAGS=$(cmake -N -LA . | grep "CTEST_RUN_FLAGS:STRING") +CTEST_RUN_FLAGS=${CTEST_RUN_FLAGS/CTEST_RUN_FLAGS:STRING=/} +CTEST_RUN_FLAGS=${CTEST_RUN_FLAGS/$/${CONFIGURATION}} # Run ctest echo [ci_build] ctest ${CTEST_RUN_FLAGS} ${CTEST_OPTIONS} diff --git a/scripts/ctest/CMakeLists.txt b/scripts/ctest/CMakeLists.txt index 98ea21e938..064d27a9cf 100644 --- a/scripts/ctest/CMakeLists.txt +++ b/scripts/ctest/CMakeLists.txt @@ -17,7 +17,7 @@ endif() # Tests ################################################################################ -if(PAL_TRAIT_TEST_LYTESTTOOLS_SUPPORTED) +if(PAL_TRAIT_TEST_PYTEST_SUPPORTED) foreach(suite_name ${LY_TEST_GLOBAL_KNOWN_SUITE_NAMES}) ly_add_pytest( NAME pytest_sanity_${suite_name}_no_gpu @@ -32,16 +32,16 @@ if(PAL_TRAIT_TEST_LYTESTTOOLS_SUPPORTED) TEST_REQUIRES gpu ) endforeach() -endif() -# add a custom test which makes sure that the test filtering works! - -ly_add_test( - NAME cli_test_driver - EXCLUDE_TEST_RUN_TARGET_FROM_IDE - TEST_COMMAND ${LY_PYTHON_CMD} ${CMAKE_CURRENT_LIST_DIR}/ctest_driver_test.py - -x ${CMAKE_CTEST_COMMAND} - --build-path ${CMAKE_BINARY_DIR} - TEST_LIBRARY pytest -) + # add a custom test which makes sure that the test filtering works! + ly_add_test( + NAME cli_test_driver + EXCLUDE_TEST_RUN_TARGET_FROM_IDE + TEST_COMMAND ${LY_PYTHON_CMD} ${CMAKE_CURRENT_LIST_DIR}/ctest_driver_test.py + -x ${CMAKE_CTEST_COMMAND} + --build-path ${CMAKE_BINARY_DIR} + --config $ + TEST_LIBRARY pytest + ) +endif() \ No newline at end of file diff --git a/scripts/ctest/ctest_driver_test.py b/scripts/ctest/ctest_driver_test.py index 82d92ce098..b9a7283b25 100755 --- a/scripts/ctest/ctest_driver_test.py +++ b/scripts/ctest/ctest_driver_test.py @@ -15,10 +15,10 @@ import sys import argparse from ctest_driver import SUITES_AND_DESCRIPTIONS -def main(build_path, ctest_executable): +def main(build_path, ctest_executable, config): script_folder = os.path.dirname(__file__) # -N prevents tests from running, just lists them: - base_args = [sys.executable, os.path.join(script_folder,'ctest_driver.py'), "--build-path", build_path, '-N'] + base_args = [sys.executable, os.path.join(script_folder,'ctest_driver.py'), "--build-path", build_path, "--config", config, '-N'] if ctest_executable: base_args.append("--ctest-executable") base_args.append(ctest_executable) @@ -77,7 +77,10 @@ if __name__ == '__main__': parser.add_argument('-b', '--build-path', required=True, help="Path to a CMake build folder (generated by running cmake)") + parser.add_argument('-c', '--config', + required=True, + help="Configuration to run") args = parser.parse_args() - sys.exit(main(args.build_path, args.ctest_executable)) + sys.exit(main(args.build_path, args.ctest_executable, args.config)) From 7f4fe67f773f0e2508631f947f60a2e7cd9ee8a2 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Thu, 6 Jan 2022 16:35:36 -0800 Subject: [PATCH 103/272] Fix issues caused by SC editor component holding onto a live graph (#6734) Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../Code/Builder/ScriptCanvasBuilder.cpp | 10 ++++ .../Code/Builder/ScriptCanvasBuilder.h | 2 + .../EditorScriptCanvasComponent.cpp | 47 ++++++------------- .../Components/EditorScriptCanvasComponent.h | 2 +- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index d62ebb9c3a..fbacfd8c32 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -246,6 +246,16 @@ namespace ScriptCanvasBuilder } } + void BuildVariableOverrides::SetHandlesToDescription() + { + m_source = m_source.Describe(); + + for (auto& dependency : m_dependencies) + { + dependency.SetHandlesToDescription(); + } + } + ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& buildOverrides) { ScriptCanvas::RuntimeDataOverrides runtimeOverrides; diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h index 6e8e176145..1770e48dfa 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h @@ -38,6 +38,8 @@ namespace ScriptCanvasBuilder // use this to initialize the new data, and make sure they have a editor graph variable for proper editor display void PopulateFromParsedResults(ScriptCanvas::Grammar::AbstractCodeModelConstPtr abstractCodeModel, const ScriptCanvas::VariableData& variables); + void SetHandlesToDescription(); + // #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one. ScriptCanvasEditor::SourceHandle m_source; diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp index 750097b428..f8f867d7e3 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp @@ -245,13 +245,13 @@ namespace ScriptCanvasEditor void EditorScriptCanvasComponent::OpenEditor([[maybe_unused]] const AZ::Data::AssetId& assetId, const AZ::Data::AssetType&) { AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas); - + AZ::Outcome openOutcome = AZ::Failure(AZStd::string()); - + if (m_sourceHandle.IsDescriptionValid()) { GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1); - + if (!openOutcome) { AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data()); @@ -261,7 +261,7 @@ namespace ScriptCanvasEditor { AzToolsFramework::EntityIdList selectedEntityIds; AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities); - + // Going to bypass the multiple selected entities flow for right now. if (selectedEntityIds.size() == 1) { @@ -279,7 +279,7 @@ namespace ScriptCanvasEditor void EditorScriptCanvasComponent::InitializeSource(const SourceHandle& sourceHandle) { - m_sourceHandle = sourceHandle; + m_sourceHandle = sourceHandle.Describe(); } //========================================================================= @@ -345,6 +345,7 @@ namespace ScriptCanvasEditor } m_variableOverrides = parseOutcome.TakeValue(); + m_variableOverrides.SetHandlesToDescription(); m_runtimeDataIsValid = true; } @@ -373,13 +374,7 @@ namespace ScriptCanvasEditor void EditorScriptCanvasComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId) { m_sourceHandle = SourceHandle(nullptr, assetId.m_guid, {}); - - auto completeAsset = CompleteDescription(m_sourceHandle); - if (completeAsset) - { - m_sourceHandle = *completeAsset; - } - + CompleteDescriptionInPlace(m_sourceHandle); OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged); SetName(m_sourceHandle.Path().Filename().Native()); AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues); @@ -399,7 +394,7 @@ namespace ScriptCanvasEditor OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged); return AZ::Edit::PropertyRefreshLevels::EntireTree; } - + void EditorScriptCanvasComponent::OnScriptCanvasAssetChanged(SourceChangeDescription changeDescription) { ScriptCanvas::GraphIdentifier newIdentifier = GetGraphIdentifier(); @@ -417,20 +412,11 @@ namespace ScriptCanvasEditor ClearVariables(); } + m_sourceHandle = m_previousHandle; + if (m_sourceHandle.IsDescriptionValid()) { - if (!m_sourceHandle.Get()) - { - if (auto loaded = LoadFromFile(m_sourceHandle.Path().c_str()); loaded.IsSuccess()) - { - m_sourceHandle = SourceHandle(loaded.TakeValue(), m_sourceHandle.Id(), m_sourceHandle.Path().c_str()); - } - } - - if (m_sourceHandle.Get()) - { - UpdatePropertyDisplay(m_sourceHandle); - } + UpdatePropertyDisplay(); } AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); @@ -492,14 +478,11 @@ namespace ScriptCanvasEditor return ScriptCanvas::GraphIdentifier(m_sourceHandle.Id(), 0); } - void EditorScriptCanvasComponent::UpdatePropertyDisplay(const SourceHandle& sourceHandle) + void EditorScriptCanvasComponent::UpdatePropertyDisplay() { - if (sourceHandle.IsGraphValid()) - { - BuildGameEntityData(); - UpdateName(); - AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); - } + BuildGameEntityData(); + UpdateName(); + AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); } void EditorScriptCanvasComponent::ClearVariables() diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h index ca381445ea..b86df2d9c2 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h @@ -121,7 +121,7 @@ namespace ScriptCanvasEditor void UpdateName(); //===================================================================== - void UpdatePropertyDisplay(const SourceHandle& sourceHandle); + void UpdatePropertyDisplay(); //===================================================================== void BuildGameEntityData(); From 6a171d17697b8c6415967ca86a62e2d28fc2c308 Mon Sep 17 00:00:00 2001 From: Mike Chang Date: Thu, 6 Jan 2022 16:41:35 -0800 Subject: [PATCH 104/272] Windows installer build tag date fix (#6735) Makes the % string replacement optional in the palSh function Signed-off-by: Mike Chang --- scripts/build/Jenkins/Jenkinsfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index 570c553444..51f89d7829 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -38,7 +38,7 @@ def pipelineParameters = [ booleanParam(defaultValue: false, description: 'Recreates the volume used for the workspace. The volume will be created out of a snapshot taken from main.', name: 'RECREATE_VOLUME') ] -def palSh(cmd, lbl = '', winSlashReplacement = true) { +def palSh(cmd, lbl = '', winSlashReplacement = true, winCharReplacement = true) { if (env.IS_UNIX) { sh label: lbl, script: cmd @@ -46,7 +46,9 @@ def palSh(cmd, lbl = '', winSlashReplacement = true) { if (winSlashReplacement) { cmd = cmd.replace('/','\\') } - cmd = cmd.replace('%', '%%') + if (winCharReplacement) { + cmd = cmd.replace('%', '%%') + } bat label: lbl, script: cmd } @@ -262,7 +264,7 @@ def CheckoutRepo(boolean disableSubmodules = false) { commitDateFmt = '%%cI' if (env.IS_UNIX) commitDateFmt = '%cI' - palSh("git show -s --format=${commitDateFmt} ${env.CHANGE_ID} > commitdate", 'Getting commit date') + palSh("git show -s --format=${commitDateFmt} ${env.CHANGE_ID} > commitdate", 'Getting commit date', winSlashReplacement=true, winCharReplacement=false) env.CHANGE_DATE = readFile file: 'commitdate' env.CHANGE_DATE = env.CHANGE_DATE.trim() palRm('commitdate') From e7f573d22a37321ecdd6de0578d527f0186115a6 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 6 Jan 2022 16:48:07 -0800 Subject: [PATCH 105/272] Make Value ctor explicit Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 30 ------------ Code/Framework/AzCore/AzCore/DOM/DomValue.h | 49 +++++++++---------- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 8 +-- .../AzCore/Tests/DOM/DomValueTests.cpp | 33 +++++++------ 4 files changed, 44 insertions(+), 76 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 824b38e47b..f48586709d 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -969,16 +969,6 @@ namespace AZ::Dom m_value = value; } - int32_t Value::GetInt32() const - { - return aznumeric_cast(GetInt64()); - } - - void Value::SetInt32(int32_t value) - { - m_value = aznumeric_cast(value); - } - uint64_t Value::GetUint64() const { switch (m_value.index()) @@ -999,16 +989,6 @@ namespace AZ::Dom m_value = value; } - uint32_t Value::GetUint32() const - { - return aznumeric_cast(GetUint64()); - } - - void Value::SetUint32(uint32_t value) - { - m_value = aznumeric_cast(value); - } - bool Value::GetBool() const { if (IsBool()) @@ -1044,16 +1024,6 @@ namespace AZ::Dom m_value = value; } - float Value::GetFloat() const - { - return aznumeric_cast(GetDouble()); - } - - void Value::SetFloat(float value) - { - m_value = aznumeric_cast(value); - } - void Value::SetString(SharedStringType sharedString) { m_value = sharedString; diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index a6990fcbce..fa496e8dfc 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -198,28 +198,39 @@ namespace AZ::Dom Value(const Value&); Value(Value&&) noexcept; Value(AZStd::string_view stringView, bool copy); - Value(SharedStringType sharedString); + explicit Value(const ValueType&); + explicit Value(ValueType&&); + explicit Value(SharedStringType sharedString); - Value(int8_t value); - Value(uint8_t value); - Value(int16_t value); - Value(uint16_t value); - Value(int32_t value); - Value(uint32_t value); - Value(int64_t value); - Value(uint64_t value); - Value(float value); - Value(double value); - Value(bool value); + explicit Value(int8_t value); + explicit Value(uint8_t value); + explicit Value(int16_t value); + explicit Value(uint16_t value); + explicit Value(int32_t value); + explicit Value(uint32_t value); + explicit Value(int64_t value); + explicit Value(uint64_t value); + explicit Value(float value); + explicit Value(double value); + explicit Value(bool value); explicit Value(Type type); + template + explicit Value(T, AZStd::enable_if_t>* enabled = 0) = delete; + static Value FromOpaqueValue(const AZStd::any& value); // Equality / comparison / swap... Value& operator=(const Value&); Value& operator=(Value&&) noexcept; + template + Value& operator=(T value) + { + return operator=(Value(value)); + } + bool operator==(const Value& rhs) const; bool operator!=(const Value& rhs) const; @@ -330,22 +341,10 @@ namespace AZ::Dom // int API... int64_t GetInt64() const; void SetInt64(int64_t); - int32_t GetInt32() const; - void SetInt32(int32_t); - int16_t GetInt16() const; - void SetInt16(int16_t); - int8_t GetInt8() const; - void SetInt8(int8_t); // uint API... uint64_t GetUint64() const; void SetUint64(uint64_t); - uint32_t GetUint32() const; - void SetUint32(uint32_t); - uint16_t GetUint16() const; - void SetUint16(uint16_t); - uint8_t GetUint8() const; - void SetUint8(uint8_t); // bool API... bool GetBool() const; @@ -354,8 +353,6 @@ namespace AZ::Dom // double API... double GetDouble() const; void SetDouble(double); - float GetFloat() const; - void SetFloat(float); // String API... AZStd::string_view GetString() const; diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index b20091b232..40b96e148b 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -66,9 +66,9 @@ namespace AZ::Dom::Benchmark { Value entry(Type::Object); entry.AddMember("string", createString(n)); - entry.AddMember("int", n); - entry.AddMember("double", static_cast(n) * 0.5); - entry.AddMember("bool", n % 2 == 0); + entry.AddMember("int", Value(n)); + entry.AddMember("double", Value(static_cast(n) * 0.5)); + entry.AddMember("bool", Value(n % 2 == 0)); entry.AddMember("null", Value(Type::Null)); return entry; }; @@ -153,7 +153,7 @@ namespace AZ::Dom::Benchmark for (auto _ : state) { Value copy = original; - copy["entries"]["Key0"].ArrayPushBack(42); + copy["entries"]["Key0"].ArrayPushBack(Value(42)); TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); } diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index a98eb307a2..10e9f29a44 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -68,7 +68,7 @@ namespace AZ::Dom::Tests { m_value.ArrayPushBack(Value(i)); EXPECT_EQ(m_value.ArraySize(), i + 1); - EXPECT_EQ(m_value[i].GetInt32(), i); + EXPECT_EQ(m_value[i].GetInt64(), i); } PerformValueChecks(); @@ -76,6 +76,7 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, NestedArrays) { + Value x(5); m_value.SetArray(); for (int j = 0; j < 5; ++j) { @@ -93,7 +94,7 @@ namespace AZ::Dom::Tests EXPECT_EQ(m_value[i].ArraySize(), 5); for (int j = 0; j < 5; ++j) { - EXPECT_EQ(m_value[i][j].GetInt32(), j); + EXPECT_EQ(m_value[i][j].GetInt64(), j); } } @@ -116,7 +117,7 @@ namespace AZ::Dom::Tests AZStd::string key = AZStd::string::format("Key%i", i); m_value.AddMember(key, Value(i)); EXPECT_EQ(m_value.MemberCount(), i + 1); - EXPECT_EQ(m_value[key].GetInt32(), i); + EXPECT_EQ(m_value[key].GetInt64(), i); } PerformValueChecks(); @@ -142,7 +143,7 @@ namespace AZ::Dom::Tests EXPECT_EQ(nestedObject.MemberCount(), 5); for (int i = 0; i < 5; ++i) { - EXPECT_EQ(nestedObject[AZStd::string::format("Key%i", i)].GetInt32(), i); + EXPECT_EQ(nestedObject[AZStd::string::format("Key%i", i)].GetInt64(), i); } } @@ -167,14 +168,14 @@ namespace AZ::Dom::Tests { m_value.ArrayPushBack(Value(i)); EXPECT_EQ(m_value.ArraySize(), i + 1); - EXPECT_EQ(m_value[i].GetInt32(), i); + EXPECT_EQ(m_value[i].GetInt64(), i); if (i < 5) { AZ::Name key = AZ::Name(AZStd::string::format("TwoTimes%i", i)); m_value.AddMember(key, Value(i * 2)); EXPECT_EQ(m_value.MemberCount(), i + 1); - EXPECT_EQ(m_value[key].GetInt32(), i * 2); + EXPECT_EQ(m_value[key].GetInt64(), i * 2); } } @@ -191,9 +192,9 @@ namespace AZ::Dom::Tests { Value childNode(Type::Node); childNode.SetNodeName(childNodeName); - childNode.SetNodeValue(i); + childNode.SetNodeValue(Value(i)); - childNode.AddMember("foo", i); + childNode.AddMember("foo", Value(i)); childNode.AddMember("bar", Value("test", false)); m_value.ArrayPushBack(childNode); @@ -204,8 +205,8 @@ namespace AZ::Dom::Tests { const Value& childNode = m_value[i]; EXPECT_EQ(childNode.GetNodeName(), childNodeName); - EXPECT_EQ(childNode.GetNodeValue().GetInt32(), i); - EXPECT_EQ(childNode["foo"].GetInt32(), i); + EXPECT_EQ(childNode.GetNodeValue().GetInt64(), i); + EXPECT_EQ(childNode["foo"].GetInt64(), i); EXPECT_EQ(childNode["bar"].GetString(), "test"); } @@ -334,8 +335,8 @@ namespace AZ::Dom::Tests TEST_F(DomValueTests, CopyOnWrite_Array) { Value v1(Type::Array); - v1.ArrayPushBack(1); - v1.ArrayPushBack(2); + v1.ArrayPushBack(Value(1)); + v1.ArrayPushBack(Value(2)); Value nestedArray(Type::Array); v1.ArrayPushBack(nestedArray); @@ -349,7 +350,7 @@ namespace AZ::Dom::Tests EXPECT_NE(&v1.GetArray(), &v2.GetArray()); EXPECT_EQ(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); - v2[2].ArrayPushBack(42); + v2[2].ArrayPushBack(Value(42)); EXPECT_NE(&v1.GetArray(), &v2.GetArray()); EXPECT_NE(&v1.ArrayAt(2).GetArray(), &v2.ArrayAt(2).GetArray()); @@ -365,8 +366,8 @@ namespace AZ::Dom::Tests Value v1; v1.SetNode("TopLevel"); - v1.ArrayPushBack(1); - v1.ArrayPushBack(2); + v1.ArrayPushBack(Value(1)); + v1.ArrayPushBack(Value(2)); v1["obj"].SetNode("Nested"); Value v2 = v1; @@ -378,7 +379,7 @@ namespace AZ::Dom::Tests EXPECT_NE(&v1.GetNode(), &v2.GetNode()); EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode()); - v2["obj"].ArrayPushBack(42); + v2["obj"].ArrayPushBack(Value(42)); EXPECT_NE(&v1.GetNode(), &v2.GetNode()); EXPECT_NE(&v1["obj"].GetNode(), &v2["obj"].GetNode()); From 25924c3d384452e67775b2a4c11a84df09cf99d4 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 6 Jan 2022 16:54:57 -0800 Subject: [PATCH 106/272] Use more explicit operator= override Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index fa496e8dfc..23f4bd570f 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -225,10 +225,12 @@ namespace AZ::Dom Value& operator=(const Value&); Value& operator=(Value&&) noexcept; - template - Value& operator=(T value) + //! Assignment operator to allow forwarding types constructible via Value(T) to be assigned + template + auto operator=(T&& arg) + -> AZStd::enable_if_t, Value> && AZStd::is_constructible_v, Value&> { - return operator=(Value(value)); + return operator=(Value(AZStd::forward(arg))); } bool operator==(const Value& rhs) const; From 839bbd734aea320ebf383c6b390cf52a6d867f54 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 6 Jan 2022 16:55:24 -0800 Subject: [PATCH 107/272] Make operator== avoid implicit comparisons Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index f48586709d..6d944c9f45 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -262,21 +262,6 @@ namespace AZ::Dom { return GetString() == rhs.GetString(); } - else if (IsNumber() && rhs.IsNumber()) - { - if (IsInt()) - { - return GetInt64() == rhs.GetInt64(); - } - else if (IsUint()) - { - return GetUint64() == rhs.GetUint64(); - } - else - { - return GetDouble() == rhs.GetDouble(); - } - } else { return m_value == rhs.m_value; From 8668fac564d38fec00b142bc309ab405106257d7 Mon Sep 17 00:00:00 2001 From: Mikhail Naumov <82239319+AMZN-mnaumov@users.noreply.github.com> Date: Thu, 6 Jan 2022 19:09:27 -0600 Subject: [PATCH 108/272] Fixing character controller triggering collision on creation (#6546) * Fixing character controller triggering collision on creation Signed-off-by: Mikhail Naumov * PR feedback Signed-off-by: Mikhail Naumov --- Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterUtils.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterUtils.cpp index f4cdd01889..1151c0ffff 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterUtils.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterUtils.cpp @@ -73,6 +73,7 @@ namespace PhysX::Utils::Characters physx::PxMaterial* pxMaterial = static_cast(materials.front()->GetNativePointer()); controllerDesc.material = pxMaterial; + controllerDesc.position = PxMathConvertExtended(characterConfig.m_position); controllerDesc.slopeLimit = cosf(AZ::DegToRad(characterConfig.m_maximumSlopeAngle)); controllerDesc.stepOffset = characterConfig.m_stepHeight; controllerDesc.upDirection = characterConfig.m_upDirection.IsZero() From 2492c0a4f4db175268742fe9dcf4191d4ad44bea Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 6 Jan 2022 17:56:00 -0800 Subject: [PATCH 109/272] enum must be dereferenced with .value also added get_outcome.GetError() to pull more information from any get_container_item failures Signed-off-by: Scott Murray --- .../editor_python_test_tools/editor_entity_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index d354c4ece6..bf27ec06e0 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -174,7 +174,9 @@ class EditorComponent: get_outcome = self.property_tree_editor.get_container_item(component_property_path, key) assert ( get_outcome.IsSuccess() - ), f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]" + ), ( + f"Failure: could not get a value for {self.get_component_name()}: '{component_property_path}' [{key}]. " + f"Error returned by get_container_item: {get_outcome.GetError()}") return get_outcome.GetValue() def remove_container_item(self, component_property_path: str, key: any): @@ -277,7 +279,7 @@ class EditorComponent: :return: List of type ids of given components. Type id is a UUID as provided by the ebus call """ type_ids = editor.EditorComponentAPIBus( - bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, entity_type) + bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, entity_type.value) return type_ids From 9cb7d05e6b105aef2467dbfdd1854a138224ddb3 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Thu, 6 Jan 2022 22:50:16 -0600 Subject: [PATCH 110/272] Adding a temporarily exclusion for terrain gem materials and shaders when building on mac (#6739) * Adding a temporarily exclusion for terrain gem materials and shaders when building on mac. This is a short term fix until either: - there's a generic way to exclude assets based on platform - materialtype assets can directly exclude certain platforms (or ignore excluded shaders) - shader compiling for mac supports unbounded texture arrays. Signed-off-by: Ken Pruiksma * moving setreg to gem and contraining to the exact files that are problematic Signed-off-by: Ken Pruiksma --- .../Mac/AssetProcessorPlatformConfig.setreg | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Gems/Terrain/Registry/Platform/Mac/AssetProcessorPlatformConfig.setreg diff --git a/Gems/Terrain/Registry/Platform/Mac/AssetProcessorPlatformConfig.setreg b/Gems/Terrain/Registry/Platform/Mac/AssetProcessorPlatformConfig.setreg new file mode 100644 index 0000000000..ac0c854b19 --- /dev/null +++ b/Gems/Terrain/Registry/Platform/Mac/AssetProcessorPlatformConfig.setreg @@ -0,0 +1,16 @@ +{ + "Amazon": { + "AssetProcessor": { + "Settings": { + // The terrain shader doesn't work on mac due to unbounded arrays, so disable problematic materials and material types + // in the terrain gem to prevent dependencies from failing. + "Exclude Terrain DefaultPbrTerrain.material": { + "pattern": "^Materials/Terrain/DefaultPbrTerrain.material" + }, + "Exclude Terrain PbrTerrain.materialtype": { + "pattern": "^Materials/Terrain/PbrTerrain.materialtype" + } + } + } + } +} From 1a8b7aeb4891f103300cb770fe1537612f4adadb Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Fri, 7 Jan 2022 09:37:33 +0000 Subject: [PATCH 111/272] Small workaround and fix to ensure line fade (alpha) displays correctly (#6733) Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- .../Manipulators/ManipulatorSnapping.cpp | 4 ++++ .../Code/Source/AtomDebugDisplayViewportInterface.cpp | 9 +-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp index 5bea383630..3b2f78ef2d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp @@ -184,6 +184,10 @@ namespace AzToolsFramework const float halfGridSquareCount = float(gridSquareCount) * 0.5f; const float halfGridSize = halfGridSquareCount * squareSize; const float fadeLineLength = cl_viewportFadeLineDistanceScale * squareSize; + + // ensure AuxGeomDraw::OpacityType::Translucent render state is set + debugDisplay.SetAlpha(0.5f); + for (size_t lineIndex = 0; lineIndex <= gridSquareCount; ++lineIndex) { const float lineOffset = -halfGridSize + (lineIndex * squareSize); diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp index af91615283..352ffb6486 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp @@ -348,14 +348,7 @@ namespace AZ::AtomBridge void AtomDebugDisplayViewportInterface::SetAlpha(float a) { m_rendState.m_color.SetA(a); - if (a < 1.0f) - { - m_rendState.m_opacityType = AZ::RPI::AuxGeomDraw::OpacityType::Opaque; - } - else - { - m_rendState.m_opacityType = AZ::RPI::AuxGeomDraw::OpacityType::Translucent; - } + m_rendState.m_opacityType = a < 1.0f ? AZ::RPI::AuxGeomDraw::OpacityType::Translucent : AZ::RPI::AuxGeomDraw::OpacityType::Opaque; } void AtomDebugDisplayViewportInterface::DrawQuad( From 042ed3b877d373b7a54dbc2c66b22380faece137 Mon Sep 17 00:00:00 2001 From: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> Date: Fri, 7 Jan 2022 12:29:32 +0000 Subject: [PATCH 112/272] AssetBrowser SearchFilteringTest: Added delay when inserting a string to the search file. (#6036) * Added delay when inserting a string to the search file. Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Added explanatory comment Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../editor/EditorScripts/AssetBrowser_SearchFiltering.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py index 7366faafdc..b18bf65312 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/AssetBrowser_SearchFiltering.py @@ -98,7 +98,13 @@ def AssetBrowser_SearchFiltering(): # 3) Type the name of an asset in the search bar and make sure it is filtered to and selectable asset_browser = editor_window.findChild(QtWidgets.QDockWidget, "Asset Browser") search_bar = asset_browser.findChild(QtWidgets.QLineEdit, "textSearch") - search_bar.setText("cedar.fbx") + + # Add a small pause when typing in the search bar in order to check that the entries are updated properly + search_bar.setText("Cedar.f") + general.idle_wait(0.5) + search_bar.setText("Cedar.fbx") + general.idle_wait(0.5) + asset_browser_tree = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget") asset_browser_table = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTableViewWidget") found = await pyside_utils.wait_for_condition(lambda: pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx"), 5.0) From 8503915cddcdfab7a0cc11325f15888472b8fa22 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Fri, 7 Jan 2022 06:43:34 -0800 Subject: [PATCH 113/272] bugfix: correct mouseMove under AzToolsFrameworkHelper (#6493) * bugfix: correct mouseMove under AzToolsFrameworkHelper REF: https://github.com/o3de/o3de/issues/6481 Signed-off-by: Michael Pollind * chore: added unit test Signed-off-by: Michael Pollind * chore: address comments Signed-off-by: Michael Pollind * chore: correct fixture Signed-off-by: Michael Pollind * chore: tweak mouse move logic Signed-off-by: Michael Pollind * updates to track mouse/cursor position via events instead of using QCursor::pos() Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * rename AzToolFrameworkTestHelperTest.cpp to AzToolsFrameworkTestHelpersTest.cpp Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Co-authored-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- .../UnitTest/AzToolsFrameworkTestHelpers.cpp | 29 ++++-- .../UnitTest/AzToolsFrameworkTestHelpers.h | 21 ++++- .../Tests/AzToolsFrameworkTestHelpersTest.cpp | 88 +++++++++++++++++++ .../Tests/aztoolsframeworktests_files.cmake | 1 + 4 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/Tests/AzToolsFrameworkTestHelpersTest.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp index 4f952a3edc..7f877facb6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp @@ -30,8 +30,7 @@ namespace UnitTest void MousePressAndMove( QWidget* widget, const QPoint& initialPositionWidget, const QPoint& mouseDelta, const Qt::MouseButton mouseButton) { - QPoint position = widget->mapToGlobal(initialPositionWidget); - QTest::mousePress(widget, mouseButton, Qt::NoModifier, position); + QTest::mousePress(widget, mouseButton, Qt::NoModifier, initialPositionWidget); MouseMove(widget, initialPositionWidget, mouseDelta, mouseButton); } @@ -45,14 +44,15 @@ namespace UnitTest // - https://lists.qt-project.org/pipermail/development/2019-July/036873.html void MouseMove(QWidget* widget, const QPoint& initialPositionWidget, const QPoint& mouseDelta, const Qt::MouseButton mouseButton) { - QPoint nextPosition = widget->mapToGlobal(initialPositionWidget + mouseDelta); + const QPoint nextLocalPosition = initialPositionWidget + mouseDelta; + const QPoint nextGlobalPosition = widget->mapToGlobal(nextLocalPosition); // ^1 To ensure a mouse move event is fired we must call the test mouse move function // and also send a mouse move event that matches. Each on their own do not appear to // work - please see the links above for more context. - QTest::mouseMove(widget, nextPosition); + QTest::mouseMove(widget, nextLocalPosition); QMouseEvent mouseMoveEvent( - QEvent::MouseMove, QPointF(nextPosition), QPointF(nextPosition), Qt::NoButton, mouseButton, Qt::NoModifier); + QEvent::MouseMove, QPointF(nextLocalPosition), QPointF(nextGlobalPosition), Qt::NoButton, mouseButton, Qt::NoModifier); QApplication::sendEvent(widget, &mouseMoveEvent); } @@ -157,6 +157,23 @@ namespace UnitTest return QWidget::event(event); } + MouseMoveDetector::MouseMoveDetector(QWidget* parent) + : QObject(parent) + { + } + + bool MouseMoveDetector::eventFilter(QObject* watched, QEvent* event) + { + if (const auto eventType = event->type(); eventType == QEvent::Type::MouseMove) + { + auto mouseEvent = static_cast(event); + m_mouseGlobalPosition = mouseEvent->globalPos(); + m_mouseLocalPosition = mouseEvent->pos(); + } + + return QObject::eventFilter(watched, event); + } + void TestEditorActions::Connect() { using AzToolsFramework::GetEntityContextId; @@ -571,3 +588,5 @@ namespace UnitTest sliceAssets.clear(); } } // namespace UnitTest + +#include diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h index 79a87391b4..2c60ca914c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h @@ -111,10 +111,29 @@ namespace UnitTest { Q_OBJECT public: - FocusInteractionWidget(QWidget* parent = nullptr) : QWidget(parent) {} + FocusInteractionWidget(QWidget* parent = nullptr) + : QWidget(parent) + { + } + bool event(QEvent* event) override; }; + /// Records mouse move events and stores the local and global position of the cursor. + /// @note To use, install as an event filter for the widget being interacted with + /// e.g. m_testWidget->installEventFilter(&m_mouseMoveDetector); + class MouseMoveDetector : public QObject + { + Q_OBJECT + public: + MouseMoveDetector(QWidget* parent = nullptr); + + bool eventFilter([[maybe_unused]] QObject* watched, QEvent* event) override; + + QPoint m_mouseGlobalPosition; + QPoint m_mouseLocalPosition; + }; + /// Stores actions registered for either normal mode (regular viewport) editing and /// component mode editing. class TestEditorActions diff --git a/Code/Framework/AzToolsFramework/Tests/AzToolsFrameworkTestHelpersTest.cpp b/Code/Framework/AzToolsFramework/Tests/AzToolsFrameworkTestHelpersTest.cpp new file mode 100644 index 0000000000..2a1254f2e9 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/AzToolsFrameworkTestHelpersTest.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include + +namespace UnitTest +{ + class AzToolsFrameworkTestHelpersFixture : public AllocatorsTestFixture + { + public: + void SetUp() override + { + AllocatorsTestFixture::SetUp(); + + m_rootWidget = AZStd::make_unique(); + m_rootWidget->setFixedSize(0, 0); + m_rootWidget->setMouseTracking(true); + m_rootWidget->move(0, 0); // explicitly set the widget to be in the upper left corner + + m_mouseMoveDetector = AZStd::make_unique(); + m_rootWidget->installEventFilter(m_mouseMoveDetector.get()); + } + + void TearDown() override + { + m_rootWidget->removeEventFilter(m_mouseMoveDetector.get()); + m_rootWidget.reset(); + m_mouseMoveDetector.reset(); + + AllocatorsTestFixture::TearDown(); + } + + AZStd::unique_ptr m_rootWidget; + AZStd::unique_ptr m_mouseMoveDetector; + }; + + struct MouseMoveParams + { + QSize m_widgetSize; + QPoint m_widgetPosition; + QPoint m_localCursorPosition; + QPoint m_cursorDelta; + }; + + class MouseMoveAzToolsFrameworkTestHelperFixture + : public AzToolsFrameworkTestHelpersFixture + , public ::testing::WithParamInterface + { + }; + + TEST_P(MouseMoveAzToolsFrameworkTestHelperFixture, MouseMoveCorrectlyTransformsCursorPositionInGlobalAndLocalSpace) + { + // given + const MouseMoveParams mouseMoveParams = GetParam(); + m_rootWidget->move(mouseMoveParams.m_widgetPosition); + m_rootWidget->setFixedSize(mouseMoveParams.m_widgetSize); + + // when + MouseMove(m_rootWidget.get(), mouseMoveParams.m_localCursorPosition, mouseMoveParams.m_cursorDelta); + + // then + const QPoint mouseLocalPosition = m_mouseMoveDetector->m_mouseLocalPosition; + const QPoint mouseLocalPositionFromGlobal = m_rootWidget->mapFromGlobal(m_mouseMoveDetector->m_mouseGlobalPosition); + const QPoint expectedPosition = mouseMoveParams.m_localCursorPosition + mouseMoveParams.m_cursorDelta; + + using ::testing::Eq; + EXPECT_THAT(mouseLocalPosition.x(), Eq(expectedPosition.x())); + EXPECT_THAT(mouseLocalPosition.y(), Eq(expectedPosition.y())); + EXPECT_THAT(mouseLocalPositionFromGlobal.x(), Eq(expectedPosition.x())); + EXPECT_THAT(mouseLocalPositionFromGlobal.y(), Eq(expectedPosition.y())); + } + + INSTANTIATE_TEST_CASE_P( + All, + MouseMoveAzToolsFrameworkTestHelperFixture, + testing::Values( + MouseMoveParams{ QSize(100, 100), QPoint(0, 0), QPoint(0, 0), QPoint(10, 10) }, + MouseMoveParams{ QSize(100, 100), QPoint(100, 100), QPoint(0, 0), QPoint(10, 10) }, + MouseMoveParams{ QSize(100, 100), QPoint(20, 20), QPoint(50, 50), QPoint(20, 20) })); +} // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 9a1f61ab56..2631a84325 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -12,6 +12,7 @@ set(FILES AssetFileInfoListComparison.cpp AssetSeedManager.cpp AssetSystemMocks.h + AzToolsFrameworkTestHelpersTest.cpp BoundsTestComponent.cpp BoundsTestComponent.h ComponentAdapterTests.cpp From f8734d7d067e12ca0755e4fd4f50798964ca58f5 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Fri, 7 Jan 2022 09:44:43 -0600 Subject: [PATCH 114/272] Finalizing update of Editor tests to utilize prefab system Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/CMakeLists.txt | 32 +------ .../EditorScripts/Docking_BasicDockedTools.py | 5 +- .../EditorScripts/Menus_EditMenuOptions.py | 5 +- .../EditorScripts/Menus_FileMenuOptions.py | 2 +- .../EditorScripts/Menus_ViewMenuOptions.py | 2 + .../Gem/PythonTests/editor/TestSuite_Main.py | 87 +++++++++++++------ .../editor/TestSuite_Main_Optimized.py | 83 ------------------ .../PythonTests/editor/TestSuite_Periodic.py | 68 --------------- .../PythonTests/editor/TestSuite_Sandbox.py | 27 ------ .../editor/TestSuite_Sandbox_Optimized.py | 26 ------ 10 files changed, 69 insertions(+), 268 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py delete mode 100644 AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py delete mode 100644 AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py delete mode 100644 AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index a43b3647f9..b3f0d2da8e 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -9,10 +9,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED) ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main_Optimized + NAME AutomatedTesting::EditorTests_Main TEST_SUITE main TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py PYTEST_MARKS "not REQUIRES_gpu" RUNTIME_DEPENDENCIES Legacy::Editor @@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE main TEST_SERIAL TEST_REQUIRES gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py PYTEST_MARKS "REQUIRES_gpu" RUNTIME_DEPENDENCIES Legacy::Editor @@ -37,30 +37,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ Editor ) - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Sandbox_Optimized - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox_Optimized.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Periodic - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - endif() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py index 8734769225..a5a94f06a5 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py @@ -85,8 +85,7 @@ def Docking_BasicDockedTools(): # We drag/drop it over the viewport since it doesn't allow docking, so this will undock it render_overlay = editor_window.findChild(QtWidgets.QWidget, "renderOverlay") pyside_utils.drag_and_drop(entity_outliner, render_overlay) - general.idle_wait(0.5) - + # We need to grab a new reference to the Entity Outliner QDockWidget because when it gets moved # to the floating window, its parent changes so the wrapped instance we had becomes invalid entity_outliner = editor_window.findChild(QtWidgets.QDockWidget, "Entity Outliner") @@ -94,7 +93,6 @@ def Docking_BasicDockedTools(): # Dock the Entity Inspector tabbed with the floating Entity Outliner entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector") pyside_utils.drag_and_drop(entity_inspector, entity_outliner) - general.idle_wait(0.5) # We need to grab a new reference to the Entity Inspector QDockWidget because when it gets moved # to the floating window, its parent changes so the wrapped instance we had becomes invalid @@ -103,7 +101,6 @@ def Docking_BasicDockedTools(): # Dock the Console tabbed with the floating Entity Inspector console = editor_window.findChild(QtWidgets.QDockWidget, "Console") pyside_utils.drag_and_drop(console, entity_inspector) - general.idle_wait(0.5) # Check to ensure all the tools are parented to the same QStackedWidget def check_all_panes_tabbed(): diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index 0536575893..ce85cf223f 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -52,8 +52,9 @@ def Menus_EditMenuOptions_Work(): ("Editor Settings", "Global Preferences"), ("Editor Settings", "Editor Settings Manager"), ("Editor Settings", "Keyboard Customization", "Customize Keyboard"), - ("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"), - ("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"), + # The following menu options are temporarily disabled due to https://github.com/o3de/o3de/issues/6746 + #("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"), + #("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"), ] # 1) Open an existing simple level diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py index a4e702cbd1..4fcdc371e7 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_FileMenuOptions.py @@ -33,7 +33,7 @@ def Menus_FileMenuOptions_Work(): file_menu_options = [ ("New Level",), #("Open Level",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 - ("Import",), + #("Import",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6746 ("Save",), #("Save As",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6605 ("Save Level Statistics",), diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py index e2ee3e2a55..bb9ff15082 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py @@ -33,6 +33,8 @@ def Menus_ViewMenuOptions_Work(): view_menu_options = [ ("Center on Selection",), ("Show Quick Access Bar",), + ("Layouts", "Component Entity Layout",), + ("Layouts", "Save Layout",), ("Viewport", "Configure Layout"), ("Viewport", "Go to Position"), ("Viewport", "Center on Selection"), diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py index 949aab140d..3805ef15dd 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py @@ -7,46 +7,77 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import os import pytest -import sys import ly_test_tools.environment.file_system as file_system - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') -from base import TestAutomationBase - - -@pytest.fixture -def remove_test_level(request, workspace, project): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) - - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) - - request.addfinalizer(teardown) +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): +class TestAutomationNoAutoTestMode(EditorTestSuite): - def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, - remove_test_level): + # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests + # interact with modal dialogs + global_extra_cmdline_args = [] + + class test_AssetPicker_UI_UX(EditorSharedTest): + from .EditorScripts import AssetPicker_UI_UX as test_module + + class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest): + from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module + + class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest): + # Custom teardown to remove level created during test + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) @pytest.mark.REQUIRES_gpu - def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform, - remove_test_level): + class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest): + # Disable null renderer + use_null_renderer = False + + # Custom teardown to remove level created during test + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, - use_null_renderer=False) - def test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(self, request, workspace, editor, - launcher_platform): - from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) + class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest): + from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module - def test_EntityOutliner_EntityOrdering(self, request, workspace, editor, launcher_platform): + +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomationAutoTestMode(EditorTestSuite): + + # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions + global_extra_cmdline_args = ["-autotest_mode"] + + class test_AssetBrowser_SearchFiltering(EditorSharedTest): + from .EditorScripts import AssetBrowser_SearchFiltering as test_module + + class test_AssetBrowser_TreeNavigation(EditorSharedTest): + from .EditorScripts import AssetBrowser_TreeNavigation as test_module + + class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest): + from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module + + @pytest.mark.skip("Passes locally/fails on Jenkins. https://github.com/o3de/o3de/issues/6747") + class test_Docking_BasicDockedTools(EditorSharedTest): + from .EditorScripts import Docking_BasicDockedTools as test_module + + class test_EntityOutliner_EntityOrdering(EditorSharedTest): from .EditorScripts import EntityOutliner_EntityOrdering as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) + + class test_Menus_EditMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_EditMenuOptions as test_module + + class test_Menus_FileMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_FileMenuOptions as test_module + + class test_Menus_ViewMenuOptions_Work(EditorSharedTest): + from .EditorScripts import Menus_ViewMenuOptions as test_module diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py deleted file mode 100644 index 7e07d125fd..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest - -import ly_test_tools.environment.file_system as file_system -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomationNoAutoTestMode(EditorTestSuite): - - # Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests - # interact with modal dialogs - global_extra_cmdline_args = [] - - class test_AssetPicker_UI_UX(EditorSharedTest): - from .EditorScripts import AssetPicker_UI_UX as test_module - - class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest): - from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module - - class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest): - # Custom teardown to remove level created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) - from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module - - @pytest.mark.REQUIRES_gpu - class test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(EditorSingleTest): - # Disable null renderer - use_null_renderer = False - - # Custom teardown to remove level created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) - from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module - - class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest): - from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomationAutoTestMode(EditorTestSuite): - - # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions - global_extra_cmdline_args = ["-autotest_mode"] - - class test_AssetBrowser_SearchFiltering(EditorSharedTest): - from .EditorScripts import AssetBrowser_SearchFiltering as test_module - - class test_AssetBrowser_TreeNavigation(EditorSharedTest): - from .EditorScripts import AssetBrowser_TreeNavigation as test_module - - class test_ComponentCRUD_Add_Delete_Components(EditorSharedTest): - from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module - - @pytest.mark.skip("Passes locally, fails on Jenkins") - class test_Docking_BasicDockedTools(EditorSharedTest): - from .EditorScripts import Docking_BasicDockedTools as test_module - - class test_EntityOutliner_EntityOrdering(EditorSharedTest): - from .EditorScripts import EntityOutliner_EntityOrdering as test_module - - class test_Menus_EditMenuOptions_Work(EditorSharedTest): - from .EditorScripts import Menus_EditMenuOptions as test_module - - class test_Menus_FileMenuOptions_Work(EditorSharedTest): - from .EditorScripts import Menus_FileMenuOptions as test_module - - class test_Menus_ViewMenuOptions_Work(EditorSharedTest): - from .EditorScripts import Menus_ViewMenuOptions as test_module \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py deleted file mode 100644 index 6e7bc413d3..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest -import sys - -import ly_test_tools.environment.file_system as file_system -import ly_test_tools.environment.process_utils as process_utils - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') -from base import TestAutomationBase - - -@pytest.fixture -def remove_test_level(request, workspace, project): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) - - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", "tmp_level")], True, True) - - request.addfinalizer(teardown) - - -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): - - def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetBrowser_SearchFiltering as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, use_null_renderer=False) - - def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetBrowser_TreeNavigation as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform): - from .EditorScripts import AssetPicker_UI_UX as test_module - self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False) - - def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform): - from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Docking_BasicDockedTools as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform): - from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False) - - def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Menus_EditMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Menus_FileMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Menus_ViewMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py deleted file mode 100644 index 98a6620d9c..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest -import sys - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') -from base import TestAutomationBase - - -@pytest.mark.SUITE_sandbox -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): - - def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Menus_EditMenuOptions as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) - - def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform): - from .EditorScripts import Docking_BasicDockedTools as test_module - self._run_test(request, workspace, editor, test_module, batch_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py deleted file mode 100644 index 4a472095ae..0000000000 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import pytest - -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite - - -@pytest.mark.SUITE_sandbox -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomationAutoTestMode(EditorTestSuite): - - # Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions - global_extra_cmdline_args = ["-autotest_mode"] - - class test_Docking_BasicDockedTools(EditorSharedTest): - from .EditorScripts import Docking_BasicDockedTools as test_module - - class test_Menus_EditMenuOptions_Work(EditorSharedTest): - from .EditorScripts import Menus_EditMenuOptions as test_module From 8b9e3d2175bb7766e0e9e81f0bba310cafd14a90 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 7 Jan 2022 09:53:14 -0800 Subject: [PATCH 115/272] Simplify disabling Value ctor for pointer types Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index 23f4bd570f..ecf8326525 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -216,8 +216,9 @@ namespace AZ::Dom explicit Value(Type type); + // Disable accidental calls to Value(bool) with pointer types template - explicit Value(T, AZStd::enable_if_t>* enabled = 0) = delete; + explicit Value(T*) = delete; static Value FromOpaqueValue(const AZStd::any& value); From 7123ed18beed40fbf91f5b0fc8a2cbbe0b86d9a7 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Fri, 7 Jan 2022 12:12:09 -0600 Subject: [PATCH 116/272] Naive GetValues() implementation. (#6741) * Naive GetValues() implementation. Added the method itself, and the benchmarks which show that even the naive version is currently 10-50% faster than calling GetValue() for multiple values. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added comments documenting why the const_cast is there. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed link errors by creating new Shared.Tests lib. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Addressed PR feedback. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed incorrect comparison. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- Gems/GradientSignal/Code/CMakeLists.txt | 22 +++ .../Ebuses/GradientRequestBus.h | 32 ++++ .../Include/GradientSignal/GradientSampler.h | 90 ++++++++++ .../Code/Tests/GradientSignalBenchmarks.cpp | 169 +++++++++++++----- .../Code/Tests/GradientSignalTestFixtures.cpp | 156 +++++++++++++++- .../Code/Tests/GradientSignalTestFixtures.h | 10 +- .../Code/Tests/GradientSignalTestMocks.cpp | 40 +++-- .../Code/Tests/GradientSignalTestMocks.h | 6 +- .../gradientsignal_editor_tests_files.cmake | 1 - .../gradientsignal_shared_tests_files.cmake | 14 ++ .../Code/gradientsignal_tests_files.cmake | 4 - 11 files changed, 466 insertions(+), 78 deletions(-) create mode 100644 Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake diff --git a/Gems/GradientSignal/Code/CMakeLists.txt b/Gems/GradientSignal/Code/CMakeLists.txt index d1ac8cdacf..657a88db47 100644 --- a/Gems/GradientSignal/Code/CMakeLists.txt +++ b/Gems/GradientSignal/Code/CMakeLists.txt @@ -124,6 +124,26 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Mocks ) + ly_add_target( + NAME GradientSignal.Tests.Static STATIC + NAMESPACE Gem + FILES_CMAKE + gradientsignal_shared_tests_files.cmake + INCLUDE_DIRECTORIES + PUBLIC + Tests + PRIVATE + . + Source + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + AZ::AzTestShared + Gem::GradientSignal.Static + Gem::LmbrCentral + Gem::GradientSignal.Mocks + ) + ly_add_target( NAME GradientSignal.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE Gem @@ -137,6 +157,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTest AZ::AzTestShared + Gem::GradientSignal.Tests.Static Gem::GradientSignal.Static Gem::LmbrCentral Gem::GradientSignal.Mocks @@ -165,6 +186,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTest AZ::AzTestShared + Gem::GradientSignal.Tests.Static Gem::GradientSignal.Static Gem::GradientSignal.Editor.Static Gem::LmbrCentral.Editor diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h index 1782972acf..d0fcabf746 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h @@ -11,6 +11,8 @@ #include #include +#include + namespace GradientSignal { struct GradientSampleParams final @@ -49,6 +51,36 @@ namespace GradientSignal */ virtual float GetValue(const GradientSampleParams& sampleParams) const = 0; + /** + * Given a list of positions, generate values. Implementations of this need to be thread-safe without using locks, + * as it can get called from multiple threads simultaneously and has the potential to cause lock inversion deadlocks. + * \param positions The input list of positions to query. + * \param outValues The output list of values. This list is expected to be the same size as the positions list. + */ + virtual void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + // Reference implementation of GetValues for any gradients that don't have their own optimized implementations. + // This is 10%-60% faster than calling GetValue via EBus many times due to the per-call EBus overhead. + + AZ_Assert( + positions.size() == outValues.size(), "input and output lists are different sizes (%zu vs %zu).", + positions.size(), outValues.size()); + + if (positions.size() == outValues.size()) + { + GradientSampleParams sampleParams; + for (size_t index = 0; index < positions.size(); index++) + { + sampleParams.m_position = positions[index]; + + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + outValue = GetValue(sampleParams); + } + } + } + /** * Call to check the hierarchy to see if a given entityId exists in the gradient signal chain */ diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h index 1dd7d44376..454be938a5 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h @@ -33,6 +33,7 @@ namespace GradientSignal static void Reflect(AZ::ReflectContext* context); inline float GetValue(const GradientSampleParams& sampleParams) const; + inline void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const; @@ -145,4 +146,93 @@ namespace GradientSignal return output * m_opacity; } + + inline void GradientSampler::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + auto ClearOutputValues = [](AZStd::array_view outValues) + { + // If we don't have a valid gradient (or it is fully transparent), clear out all the output values. + for (size_t index = 0; index < outValues.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + outValue = 0.0f; + } + }; + + if (m_opacity <= 0.0f || !m_gradientId.IsValid()) + { + ClearOutputValues(outValues); + return; + } + + AZStd::vector transformedPositions; + bool useTransformedPositions = false; + + // apply transform if set + if (m_enableTransform && GradientSamplerUtil::AreTransformParamsSet(*this)) + { + AZ::Matrix3x4 matrix3x4; + matrix3x4.SetFromEulerDegrees(m_rotate); + matrix3x4.MultiplyByScale(m_scale); + matrix3x4.SetTranslation(m_translate); + + useTransformedPositions = true; + transformedPositions.resize(positions.size()); + for (size_t index = 0; index < positions.size(); index++) + { + transformedPositions[index] = matrix3x4 * positions[index]; + } + } + + { + // Block other threads from accessing the surface data bus while we are in GetValue (which may call into the SurfaceData bus). + // We lock our surface data mutex *before* checking / setting "isRequestInProgress" so that we prevent race conditions + // that create false detection of cyclic dependencies when multiple requests occur on different threads simultaneously. + // (One case where this was previously able to occur was in rapid updating of the Preview widget on the + // GradientSurfaceDataComponent in the Editor when moving the threshold sliders back and forth rapidly) + auto& surfaceDataContext = SurfaceData::SurfaceDataSystemRequestBus::GetOrCreateContext(false); + typename SurfaceData::SurfaceDataSystemRequestBus::Context::DispatchLockGuard scopeLock(surfaceDataContext.m_contextMutex); + + if (m_isRequestInProgress) + { + AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependences with gradient entity references"); + ClearOutputValues(outValues); + return; + } + else + { + m_isRequestInProgress = true; + + GradientRequestBus::Event( + m_gradientId, &GradientRequestBus::Events::GetValues, useTransformedPositions ? transformedPositions : positions, + outValues); + + m_isRequestInProgress = false; + } + } + + // Perform any post-fetch transformations on the gradient values (invert, levels, opacity). + for (size_t index = 0; index < outValues.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + + if (m_invertInput) + { + outValue = 1.0f - outValue; + } + + // apply levels if set + if (m_enableLevels && GradientSamplerUtil::AreLevelParamsSet(*this)) + { + outValue = GetLevels(outValue, m_inputMid, m_inputMin, m_inputMax, m_outputMin, m_outputMax); + } + + outValue = outValue * m_opacity; + } + } + } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp index dd179bd253..6383b627c1 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp @@ -23,74 +23,145 @@ namespace UnitTest { - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue)(benchmark::State& state) { - // Create the Image Gradient Component with some default sizes and parameters. - GradientSignal::ImageGradientConfig config; - const uint32_t imageSize = 4096; - const int32_t imageSeed = 12345; - config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed); - config.m_tilingX = 1.0f; - config.m_tilingY = 1.0f; - CreateComponent(m_testEntity.get(), config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(m_testEntity.get(), gradientTransformConfig); - - // Run the benchmark - RunGetValueBenchmark(state); + CreateTestImageGradient(m_testEntity.get()); + RunEBusGetValueBenchmark(state); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientGetValue) + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue) ->Args({ 1024, 1024 }) ->Args({ 2048, 2048 }) ->Args({ 4096, 4096 }) ->Unit(::benchmark::kMillisecond); - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues)(benchmark::State& state) { - // Create the Perlin Gradient Component with some default sizes and parameters. - GradientSignal::PerlinGradientConfig config; - config.m_amplitude = 1.0f; - config.m_frequency = 1.1f; - config.m_octave = 4; - config.m_randomSeed = 12345; - CreateComponent(m_testEntity.get(), config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(m_testEntity.get(), gradientTransformConfig); - - // Run the benchmark - RunGetValueBenchmark(state); + CreateTestImageGradient(m_testEntity.get()); + RunEBusGetValuesBenchmark(state); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientGetValue) + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues) ->Args({ 1024, 1024 }) ->Args({ 2048, 2048 }) ->Args({ 4096, 4096 }) ->Unit(::benchmark::kMillisecond); - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue)(benchmark::State& state) { - // Create the Random Gradient Component with some default parameters. - GradientSignal::RandomGradientConfig config; - config.m_randomSeed = 12345; - CreateComponent(m_testEntity.get(), config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(m_testEntity.get(), gradientTransformConfig); - - // Run the benchmark - RunGetValueBenchmark(state); + CreateTestImageGradient(m_testEntity.get()); + RunSamplerGetValueBenchmark(state); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientGetValue) + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues)(benchmark::State& state) + { + CreateTestImageGradient(m_testEntity.get()); + RunSamplerGetValuesBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue)(benchmark::State& state) + { + CreateTestPerlinGradient(m_testEntity.get()); + RunEBusGetValueBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues)(benchmark::State& state) + { + CreateTestPerlinGradient(m_testEntity.get()); + RunEBusGetValuesBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue)(benchmark::State& state) + { + CreateTestPerlinGradient(m_testEntity.get()); + RunSamplerGetValueBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues)(benchmark::State& state) + { + CreateTestPerlinGradient(m_testEntity.get()); + RunSamplerGetValuesBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue)(benchmark::State& state) + { + CreateTestRandomGradient(m_testEntity.get()); + RunEBusGetValueBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues)(benchmark::State& state) + { + CreateTestRandomGradient(m_testEntity.get()); + RunEBusGetValuesBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue)(benchmark::State& state) + { + CreateTestRandomGradient(m_testEntity.get()); + RunSamplerGetValueBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue) + ->Args({ 1024, 1024 }) + ->Args({ 2048, 2048 }) + ->Args({ 4096, 4096 }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues)(benchmark::State& state) + { + CreateTestRandomGradient(m_testEntity.get()); + RunSamplerGetValuesBenchmark(state); + } + + BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues) ->Args({ 1024, 1024 }) ->Args({ 2048, 2048 }) ->Args({ 4096, 4096 }) diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp index bc9b39aae8..77568d3321 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp @@ -9,6 +9,11 @@ #include +#include +#include +#include +#include + namespace UnitTest { void GradientSignalBaseFixture::SetupCoreSystems() @@ -86,8 +91,56 @@ namespace UnitTest m_testEntity.reset(); } - void GradientSignalBenchmarkFixture::RunGetValueBenchmark(benchmark::State& state) + void GradientSignalBenchmarkFixture::CreateTestImageGradient(AZ::Entity* entity) { + // Create the Image Gradient Component with some default sizes and parameters. + GradientSignal::ImageGradientConfig config; + const uint32_t imageSize = 4096; + const int32_t imageSeed = 12345; + config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed); + config.m_tilingX = 1.0f; + config.m_tilingY = 1.0f; + CreateComponent(entity, config); + + // Create the Gradient Transform Component with some default parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity, gradientTransformConfig); + } + + void GradientSignalBenchmarkFixture::CreateTestPerlinGradient(AZ::Entity* entity) + { + // Create the Perlin Gradient Component with some default sizes and parameters. + GradientSignal::PerlinGradientConfig config; + config.m_amplitude = 1.0f; + config.m_frequency = 1.1f; + config.m_octave = 4; + config.m_randomSeed = 12345; + CreateComponent(entity, config); + + // Create the Gradient Transform Component with some default parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity, gradientTransformConfig); + } + + void GradientSignalBenchmarkFixture::CreateTestRandomGradient(AZ::Entity* entity) + { + // Create the Random Gradient Component with some default parameters. + GradientSignal::RandomGradientConfig config; + config.m_randomSeed = 12345; + CreateComponent(entity, config); + + // Create the Gradient Transform Component with some default parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity, gradientTransformConfig); + } + + void GradientSignalBenchmarkFixture::RunSamplerGetValueBenchmark(benchmark::State& state) + { + AZ_PROFILE_FUNCTION(Entity); + // All components are created, so activate the entity ActivateEntity(m_testEntity.get()); @@ -115,6 +168,107 @@ namespace UnitTest } } + void GradientSignalBenchmarkFixture::RunSamplerGetValuesBenchmark(benchmark::State& state) + { + AZ_PROFILE_FUNCTION(Entity); + + // All components are created, so activate the entity + ActivateEntity(m_testEntity.get()); + + // Create a gradient sampler and run through a series of points to see if they match expectations. + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = m_testEntity->GetId(); + + // Get the height and width ranges for querying from our benchmark parameters + float height = aznumeric_cast(state.range(0)); + float width = aznumeric_cast(state.range(1)); + int64_t totalQueryPoints = state.range(0) * state.range(1); + + // Call GetValues() for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. + AZStd::vector positions(totalQueryPoints); + size_t index = 0; + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + gradientSampler.GetValues(positions, results); + } + } + + void GradientSignalBenchmarkFixture::RunEBusGetValueBenchmark(benchmark::State& state) + { + AZ_PROFILE_FUNCTION(Entity); + + // All components are created, so activate the entity + ActivateEntity(m_testEntity.get()); + + GradientSignal::GradientSampleParams params; + + // Get the height and width ranges for querying from our benchmark parameters + float height = aznumeric_cast(state.range(0)); + float width = aznumeric_cast(state.range(1)); + + // Call GetValue() for every height and width in our ranges. + for (auto _ : state) + { + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + float value = 0.0f; + params.m_position = AZ::Vector3(x, y, 0.0f); + GradientSignal::GradientRequestBus::EventResult( + value, m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params); + benchmark::DoNotOptimize(value); + } + } + } + } + + void GradientSignalBenchmarkFixture::RunEBusGetValuesBenchmark(benchmark::State& state) + { + AZ_PROFILE_FUNCTION(Entity); + + // All components are created, so activate the entity + ActivateEntity(m_testEntity.get()); + + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = m_testEntity->GetId(); + + // Get the height and width ranges for querying from our benchmark parameters + float height = aznumeric_cast(state.range(0)); + float width = aznumeric_cast(state.range(1)); + int64_t totalQueryPoints = state.range(0) * state.range(1); + + // Call GetValues() for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. + AZStd::vector positions(totalQueryPoints); + size_t index = 0; + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + GradientSignal::GradientRequestBus::Event( + m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); + } + } #endif } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h index 5e05cba374..13ff69c82d 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h @@ -97,7 +97,15 @@ namespace UnitTest void CreateTestEntity(float shapeHalfBounds); void DestroyTestEntity(); - void RunGetValueBenchmark(benchmark::State& state); + void CreateTestImageGradient(AZ::Entity* entity); + void CreateTestPerlinGradient(AZ::Entity* entity); + void CreateTestRandomGradient(AZ::Entity* entity); + + void RunSamplerGetValueBenchmark(benchmark::State& state); + void RunSamplerGetValuesBenchmark(benchmark::State& state); + + void RunEBusGetValueBenchmark(benchmark::State& state); + void RunEBusGetValuesBenchmark(benchmark::State& state); protected: void SetUp(const benchmark::State& state) override diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.cpp index ccbe17dee8..7ac6ef1ecc 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.cpp @@ -13,13 +13,14 @@ namespace UnitTest { AZ::Data::Asset ImageAssetMockAssetHandler::CreateImageAsset(AZ::u32 width, AZ::u32 height, AZ::s32 seed) { - GradientSignal::ImageAsset* imageData = - aznew GradientSignal::ImageAsset(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetData::AssetStatus::Ready); - imageData->m_imageWidth = width; - imageData->m_imageHeight = height; - imageData->m_bytesPerPixel = 1; - imageData->m_imageFormat = ImageProcessingAtom::EPixelFormat::ePixelFormat_R8; - imageData->m_imageData.reserve(width * height); + auto imageAsset = AZ::Data::AssetManager::Instance().CreateAsset( + AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetLoadBehavior::Default); + + imageAsset->m_imageWidth = width; + imageAsset->m_imageHeight = height; + imageAsset->m_bytesPerPixel = 1; + imageAsset->m_imageFormat = ImageProcessingAtom::EPixelFormat::ePixelFormat_R8; + imageAsset->m_imageData.reserve(width * height); size_t value = 0; AZStd::hash_combine(value, seed); @@ -30,23 +31,24 @@ namespace UnitTest { AZStd::hash_combine(value, x); AZStd::hash_combine(value, y); - imageData->m_imageData.push_back(static_cast(value)); + imageAsset->m_imageData.push_back(static_cast(value)); } } - return AZ::Data::Asset(imageData, AZ::Data::AssetLoadBehavior::Default); + return imageAsset; } AZ::Data::Asset ImageAssetMockAssetHandler::CreateSpecificPixelImageAsset( AZ::u32 width, AZ::u32 height, AZ::u32 pixelX, AZ::u32 pixelY) { - GradientSignal::ImageAsset* imageData = - aznew GradientSignal::ImageAsset(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetData::AssetStatus::Ready); - imageData->m_imageWidth = width; - imageData->m_imageHeight = height; - imageData->m_bytesPerPixel = 1; - imageData->m_imageFormat = ImageProcessingAtom::EPixelFormat::ePixelFormat_R8; - imageData->m_imageData.reserve(width * height); + auto imageAsset = AZ::Data::AssetManager::Instance().CreateAsset( + AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetLoadBehavior::Default); + + imageAsset->m_imageWidth = width; + imageAsset->m_imageHeight = height; + imageAsset->m_bytesPerPixel = 1; + imageAsset->m_imageFormat = ImageProcessingAtom::EPixelFormat::ePixelFormat_R8; + imageAsset->m_imageData.reserve(width * height); const AZ::u8 pixelValue = 255; @@ -57,16 +59,16 @@ namespace UnitTest { if ((x == static_cast(pixelX)) && (y == static_cast(pixelY))) { - imageData->m_imageData.push_back(pixelValue); + imageAsset->m_imageData.push_back(pixelValue); } else { - imageData->m_imageData.push_back(0); + imageAsset->m_imageData.push_back(0); } } } - return AZ::Data::Asset(imageData, AZ::Data::AssetLoadBehavior::Default); + return imageAsset; } } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h index 1d83a5eb55..30f262d9b4 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h @@ -47,10 +47,10 @@ namespace UnitTest static AZ::Data::Asset CreateSpecificPixelImageAsset( AZ::u32 width, AZ::u32 height, AZ::u32 pixelX, AZ::u32 pixelY); - AZ::Data::AssetPtr CreateAsset( - [[maybe_unused]] const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override + AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override { - return AZ::Data::AssetPtr(); + // For our mock handler, always mark our assets as immediately ready. + return aznew GradientSignal::ImageAsset(id, AZ::Data::AssetData::AssetStatus::Ready); } void DestroyAsset(AZ::Data::AssetPtr ptr) override diff --git a/Gems/GradientSignal/Code/gradientsignal_editor_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_editor_tests_files.cmake index 8172591afa..5a3a75602b 100644 --- a/Gems/GradientSignal/Code/gradientsignal_editor_tests_files.cmake +++ b/Gems/GradientSignal/Code/gradientsignal_editor_tests_files.cmake @@ -7,6 +7,5 @@ # set(FILES - Tests/GradientSignalTestFixtures.cpp Tests/EditorGradientSignalPreviewTests.cpp ) diff --git a/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake new file mode 100644 index 0000000000..7d867b0a33 --- /dev/null +++ b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake @@ -0,0 +1,14 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + Tests/GradientSignalTestFixtures.cpp + Tests/GradientSignalTestFixtures.h + Tests/GradientSignalTestMocks.cpp + Tests/GradientSignalTestMocks.h +) diff --git a/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake index 8e081e5711..eb799811b7 100644 --- a/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake +++ b/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake @@ -13,10 +13,6 @@ set(FILES Tests/GradientSignalServicesTests.cpp Tests/GradientSignalSurfaceTests.cpp Tests/GradientSignalTransformTests.cpp - Tests/GradientSignalTestFixtures.cpp - Tests/GradientSignalTestFixtures.h - Tests/GradientSignalTestMocks.cpp - Tests/GradientSignalTestMocks.h Tests/GradientSignalTest.cpp Tests/ImageAssetTests.cpp ) From 67a89c6cd0c1dc4c581b64ff9a147ea6406fa99d Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Fri, 7 Jan 2022 10:51:08 -0800 Subject: [PATCH 117/272] Fix an issue where npm is not found (#6706) Signed-off-by: Junbo Liang <68558268+junbo75@users.noreply.github.com> --- scripts/build/Platform/Linux/deploy_cdk_applications.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/build/Platform/Linux/deploy_cdk_applications.sh b/scripts/build/Platform/Linux/deploy_cdk_applications.sh index 97668ee70c..9a0a31397e 100755 --- a/scripts/build/Platform/Linux/deploy_cdk_applications.sh +++ b/scripts/build/Platform/Linux/deploy_cdk_applications.sh @@ -7,9 +7,6 @@ # # Deploy the CDK applications for AWS gems (Linux only) -# Prerequisites: -# 1) Node.js is installed -# 2) Node.js version >= 10.13.0, except for versions 13.0.0 - 13.6.0. A version in active long-term support is recommended. SOURCE_DIRECTORY=$(dirname "$0") PATH=$SOURCE_DIRECTORY/python:$PATH @@ -70,12 +67,12 @@ echo [cdk_installation] Install the current version of nodejs nvm install node echo [cdk_installation] Install the latest version of CDK -if ! sudo npm uninstall -g aws-cdk; +if ! npm uninstall -g aws-cdk; then echo [cdk_bootstrap] Failed to uninstall the current version of CDK exit 1 fi -if ! sudo npm install -g aws-cdk@latest; +if ! npm install -g aws-cdk@latest; then echo [cdk_bootstrap] Failed to install the latest version of CDK exit 1 From 641f7be041b0671a12340ae678608cbb757ff7ec Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Fri, 7 Jan 2022 14:24:53 -0600 Subject: [PATCH 118/272] Removed more unused Editor code and images Signed-off-by: Chris Galvan --- Code/Editor/EditorViewportWidget.cpp | 3 - Code/Editor/IEditor.h | 1 - Code/Editor/Include/IConsoleConnectivity.h | 85 ------------------- Code/Editor/Include/IFacialEditor.h | 43 ---------- Code/Editor/Include/IRenderListener.h | 29 ------- Code/Editor/Include/ITextureDatabaseUpdater.h | 38 --------- Code/Editor/MainWindow.qrc | 1 - Code/Editor/Resource.h | 2 - Code/Editor/TimeOfDay/main-00.png | 3 - Code/Editor/TimeOfDay/main-01.png | 3 - Code/Editor/TimeOfDay/main-02.png | 3 - Code/Editor/TimeOfDay/main-03.png | 3 - Code/Editor/TimeOfDay/main-04.png | 3 - Code/Editor/TimeOfDay/main-05.png | 3 - Code/Editor/TimeOfDay/main-06.png | 3 - Code/Editor/TimeOfDay/main-07.png | 3 - Code/Editor/TimeOfDay/main-08.png | 3 - Code/Editor/TimeOfDay/main-09.png | 3 - Code/Editor/TimeOfDay/main-10.png | 3 - Code/Editor/TimeOfDay/main-11.png | 3 - Code/Editor/TimeOfDay/main-12.png | 3 - Code/Editor/Viewport.cpp | 68 --------------- Code/Editor/Viewport.h | 13 --- Code/Editor/editor_lib_files.cmake | 3 - Code/Editor/water.png | 3 - 25 files changed, 328 deletions(-) delete mode 100644 Code/Editor/Include/IConsoleConnectivity.h delete mode 100644 Code/Editor/Include/IFacialEditor.h delete mode 100644 Code/Editor/Include/IRenderListener.h delete mode 100644 Code/Editor/Include/ITextureDatabaseUpdater.h delete mode 100644 Code/Editor/TimeOfDay/main-00.png delete mode 100644 Code/Editor/TimeOfDay/main-01.png delete mode 100644 Code/Editor/TimeOfDay/main-02.png delete mode 100644 Code/Editor/TimeOfDay/main-03.png delete mode 100644 Code/Editor/TimeOfDay/main-04.png delete mode 100644 Code/Editor/TimeOfDay/main-05.png delete mode 100644 Code/Editor/TimeOfDay/main-06.png delete mode 100644 Code/Editor/TimeOfDay/main-07.png delete mode 100644 Code/Editor/TimeOfDay/main-08.png delete mode 100644 Code/Editor/TimeOfDay/main-09.png delete mode 100644 Code/Editor/TimeOfDay/main-10.png delete mode 100644 Code/Editor/TimeOfDay/main-11.png delete mode 100644 Code/Editor/TimeOfDay/main-12.png delete mode 100644 Code/Editor/water.png diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 754ea84544..828812fb7e 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -454,9 +454,6 @@ void EditorViewportWidget::Update() // Render { - // TODO: Move out this logic to a controller and refactor to work with Atom - ProcessRenderLisneters(m_displayContext); - m_displayContext.Flush2D(); // Post Render Callback diff --git a/Code/Editor/IEditor.h b/Code/Editor/IEditor.h index c91ca62c5e..90f1b63f55 100644 --- a/Code/Editor/IEditor.h +++ b/Code/Editor/IEditor.h @@ -52,7 +52,6 @@ class CUIEnumsDatabase; struct ISourceControl; struct IEditorClassFactory; struct ITransformManipulator; -class IFacialEditor; class CDialog; #if defined(AZ_PLATFORM_WINDOWS) class C3DConnexionDriver; diff --git a/Code/Editor/Include/IConsoleConnectivity.h b/Code/Editor/Include/IConsoleConnectivity.h deleted file mode 100644 index 0f5e9bf35c..0000000000 --- a/Code/Editor/Include/IConsoleConnectivity.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Standard interface for console connectivity plugins. - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H -#define CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H -#pragma once - - -////////////////////////////////////////////////////////////////////////// -// Description -// This interface provide access to the console connectivity -// functionality. -////////////////////////////////////////////////////////////////////////// -struct IConsoleConnectivity - : public IUnknown -{ - DEFINE_UUID(0x4DAA85E1, 0x8498, 0x402f, 0x9B, 0x85, 0x7F, 0x62, 0x9D, 0x76, 0x79, 0x8A); - - ////////////////////////////////////////////////////////////////////////// - //TODO: Must add the useful interface here. - ////////////////////////////////////////////////////////////////////////// - - // Description: - // Checks if a development console is connected to the development PC. - // See Also: - // Arguments: - // Nothing - // Return: - // bool - true if it is connected, false otherwise. - virtual bool IsConnectedToConsole() = 0; - - // Description: - // Send a file from the specified local filename to the console platform creating the full path - // as required so it can copy to the remote filename. - // See Also: - // Nothing - // Arguments: - // szLocalFileName - is the local filename from which you want to copy the file. - // szRemoteFilename - is the full path and filename to where you want to copy the file. - // Return: - // bool - true if the copy succeeded, false otherwise. - virtual bool SendFile(const char* szLocalFileName, const char* szRemoteFilename) = 0; - - // Description: - // Notifies to the console that a file has been changed, typically uploaded. - // This will be usually called after a SendFile (see above) call, so that the - // system running on the console may decide what to do with this new file. - // Typically the system will have to load or reloads this new file. - // See Also: - // SendFile - // Arguments: - // szRemoteFilename - is the full path and filename in the console of the changed - // file. - // Return: - // bool - true if succeeded sending the notification, false otherwise. - virtual bool NotifyFileChange(const char* szRemoteFilename) = 0; - - - // Description: - // Gets the the title IP for the connected console . - // Arguments: - // dwConsoleAddressPlaceholder - is the pointer to the placeholder of the variable - // which will contain the title IP of the console. - // Return: - // bool - true if dwConsoleAddressPlaceholder now contains the IP address, else false. - virtual bool GetConsoleAddress(DWORD* dwConsoleAddressPlaceholder) = 0; - ////////////////////////////////////////////////////////////////////////// - // IUnknown - ////////////////////////////////////////////////////////////////////////// - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { return E_NOINTERFACE; }; - virtual ULONG STDMETHODCALLTYPE AddRef() { return 0; }; - virtual ULONG STDMETHODCALLTYPE Release() { return 0; }; - ////////////////////////////////////////////////////////////////////////// -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_ICONSOLECONNECTIVITY_H diff --git a/Code/Editor/Include/IFacialEditor.h b/Code/Editor/Include/IFacialEditor.h deleted file mode 100644 index 5dfa9ab03f..0000000000 --- a/Code/Editor/Include/IFacialEditor.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IFACIALEDITOR_H -#define CRYINCLUDE_EDITOR_INCLUDE_IFACIALEDITOR_H -#pragma once - - -class IFacialEditor -{ -public: - enum EyeType - { - EYE_LEFT, - EYE_RIGHT - }; - - virtual int GetNumMorphTargets() const = 0; - virtual const char* GetMorphTargetName(int index) const = 0; - virtual void PreviewEffector(int index, float value) = 0; - virtual void ClearAllPreviewEffectors() = 0; - virtual void SetForcedNeckRotation(const Quat& rotation) = 0; - virtual void SetForcedEyeRotation(const Quat& rotation, EyeType eye) = 0; - virtual int GetJoystickCount() const = 0; - virtual const char* GetJoystickName(int joystickIndex) const = 0; - virtual void SetJoystickPosition(int joystickIndex, float x, float y) = 0; - virtual void GetJoystickPosition(int joystickIndex, float& x, float& y) const = 0; - virtual void LoadJoystickFile(const char* filename) = 0; - virtual void LoadCharacter(const char* filename) = 0; - virtual void LoadSequence(const char* filename) = 0; - virtual void SetVideoFrameResolution(int width, int height, int bpp) = 0; - virtual int GetVideoFramePitch() = 0; - virtual void* GetVideoFrameBits() = 0; - virtual void ShowVideoFramePane() = 0; -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IFACIALEDITOR_H diff --git a/Code/Editor/Include/IRenderListener.h b/Code/Editor/Include/IRenderListener.h deleted file mode 100644 index 892a42b701..0000000000 --- a/Code/Editor/Include/IRenderListener.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Interface for rendering custom 3D elements in the main -// render viewport. Particularly usefull for debug geometries. - - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H -#pragma once - - -struct DisplayContext; - -struct IRenderListener - : public IUnknown -{ - DEFINE_UUID(0x8D52F857, 0x1027, 0x4346, 0xAC, 0x7B, 0xF6, 0x20, 0xDA, 0x7C, 0xCE, 0x42) - - virtual void Render(DisplayContext& rDisplayContext) = 0; -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IRENDERLISTENER_H diff --git a/Code/Editor/Include/ITextureDatabaseUpdater.h b/Code/Editor/Include/ITextureDatabaseUpdater.h deleted file mode 100644 index 4482135b47..0000000000 --- a/Code/Editor/Include/ITextureDatabaseUpdater.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : This file declares the interface used by the texture viewer -// and (implemented first implemented by the Texture Database Creator) to -// syncronize their threads. A thread interace could be useful there. - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H -#define CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H -#pragma once - - -class CTextureDatabaseItem; - -struct ITextureDatabaseUpdater -{ -public: - ////////////////////////////////////////////////////////////////////////// - // Thread control - virtual void NotifyShutDown() = 0; - virtual void Lock() = 0; - virtual void Unlock() = 0; - virtual void WaitForThread() = 0; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Data access - virtual CTextureDatabaseItem* GetItem(const char* szAddItem) = 0; - ////////////////////////////////////////////////////////////////////////// -}; - -#endif // CRYINCLUDE_EDITOR_INCLUDE_ITEXTUREDATABASEUPDATER_H diff --git a/Code/Editor/MainWindow.qrc b/Code/Editor/MainWindow.qrc index 4506a4a2a8..c68e05ef41 100644 --- a/Code/Editor/MainWindow.qrc +++ b/Code/Editor/MainWindow.qrc @@ -166,7 +166,6 @@ arhitype_tree_01.png arhitype_tree_02.png arhitype_tree_03.png - water.png bmp00005_00.png bmp00005_01.png bmp00005_02.png diff --git a/Code/Editor/Resource.h b/Code/Editor/Resource.h index 432f07a531..ef72bfc9be 100644 --- a/Code/Editor/Resource.h +++ b/Code/Editor/Resource.h @@ -196,7 +196,6 @@ #define ID_FILE_EXPORT_TERRAINAREA 33904 #define ID_FILE_EXPORT_TERRAINAREAWITHOBJECTS 33910 #define ID_FILE_EXPORT_SELECTEDOBJECTS 33911 -#define ID_TERRAIN_TIMEOFDAY 33912 #define ID_SPLINE_PREVIOUS_KEY 33916 #define ID_SPLINE_NEXT_KEY 33917 #define ID_SPLINE_FLATTEN_ALL 33918 @@ -290,7 +289,6 @@ #define ID_TV_TRACKS_TOOLBAR_LAST 35183 // for up to 100 "Add Tracks..." dynamically added Track View Track buttons #define ID_OPEN_TERRAIN_EDITOR 36007 #define ID_OPEN_UICANVASEDITOR 36010 -#define ID_TERRAIN_TIMEOFDAYBUTTON 36011 #define ID_OPEN_TERRAINTEXTURE_EDITOR 36012 #define ID_SKINS_REFRESH 36014 #define ID_FILE_GENERATETERRAIN 36016 diff --git a/Code/Editor/TimeOfDay/main-00.png b/Code/Editor/TimeOfDay/main-00.png deleted file mode 100644 index 2c44fec541..0000000000 --- a/Code/Editor/TimeOfDay/main-00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5201dbba6c8114914ed680b04b72a5e18e22c0519a514bcccdc7ae8d32670b4e -size 993 diff --git a/Code/Editor/TimeOfDay/main-01.png b/Code/Editor/TimeOfDay/main-01.png deleted file mode 100644 index 5cc1bf33d8..0000000000 --- a/Code/Editor/TimeOfDay/main-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:48a7250ad41c5e298079ddd13910b58baca2ef592defcc162ccc9df542d28905 -size 981 diff --git a/Code/Editor/TimeOfDay/main-02.png b/Code/Editor/TimeOfDay/main-02.png deleted file mode 100644 index b7d90648a3..0000000000 --- a/Code/Editor/TimeOfDay/main-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98b9e9abcc54b4f3e6903ad74bb50f364bfe4c8cd9fedc9653a6603d64a1ee0a -size 838 diff --git a/Code/Editor/TimeOfDay/main-03.png b/Code/Editor/TimeOfDay/main-03.png deleted file mode 100644 index e073dbf60b..0000000000 --- a/Code/Editor/TimeOfDay/main-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1199c834fc8de69f9d7c76e8c7fbd84e9b92713b9f07b513137085e5089432cb -size 857 diff --git a/Code/Editor/TimeOfDay/main-04.png b/Code/Editor/TimeOfDay/main-04.png deleted file mode 100644 index 6049dbfe18..0000000000 --- a/Code/Editor/TimeOfDay/main-04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:79b44be1dbe5518e06dc8c8823d00462136d39ffe60a32ef4f64dc0712654d33 -size 646 diff --git a/Code/Editor/TimeOfDay/main-05.png b/Code/Editor/TimeOfDay/main-05.png deleted file mode 100644 index 054419f39a..0000000000 --- a/Code/Editor/TimeOfDay/main-05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ea7450c1a278570e2a1dba3a8b4d7d4e5f0d054e8371139ebdb5220c405d355 -size 537 diff --git a/Code/Editor/TimeOfDay/main-06.png b/Code/Editor/TimeOfDay/main-06.png deleted file mode 100644 index 35f8afdae2..0000000000 --- a/Code/Editor/TimeOfDay/main-06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc73f0720f2ff877aff5c6646938b7fc509a69d92e766fecb9fa010eecadee7b -size 606 diff --git a/Code/Editor/TimeOfDay/main-07.png b/Code/Editor/TimeOfDay/main-07.png deleted file mode 100644 index aca9597355..0000000000 --- a/Code/Editor/TimeOfDay/main-07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e63519ed54fc19a4b4a2a38cb2c5f148b7404ac614d4aab039b71fee64cd7425 -size 569 diff --git a/Code/Editor/TimeOfDay/main-08.png b/Code/Editor/TimeOfDay/main-08.png deleted file mode 100644 index abeb114fc2..0000000000 --- a/Code/Editor/TimeOfDay/main-08.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8742cad4b8f8f5bba59abb9cc028db84de222ed8b393398f6837fea16bb4a1d8 -size 563 diff --git a/Code/Editor/TimeOfDay/main-09.png b/Code/Editor/TimeOfDay/main-09.png deleted file mode 100644 index cc77b8c9e2..0000000000 --- a/Code/Editor/TimeOfDay/main-09.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ef85628301b4edc4f858f0988e4f072772be3feb92d27a2ec33b72a27bcee7ff -size 583 diff --git a/Code/Editor/TimeOfDay/main-10.png b/Code/Editor/TimeOfDay/main-10.png deleted file mode 100644 index dc463c6497..0000000000 --- a/Code/Editor/TimeOfDay/main-10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d17bfbdee6d37566b241adf64241ef47b62145aaac3e9e8f9691d1fb866b5fcb -size 717 diff --git a/Code/Editor/TimeOfDay/main-11.png b/Code/Editor/TimeOfDay/main-11.png deleted file mode 100644 index d686ab18c8..0000000000 --- a/Code/Editor/TimeOfDay/main-11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98b629abf927bcea41d8857b1761d12a37836471d7106b2f5210337c0ace0d9c -size 1103 diff --git a/Code/Editor/TimeOfDay/main-12.png b/Code/Editor/TimeOfDay/main-12.png deleted file mode 100644 index 069510ab24..0000000000 --- a/Code/Editor/TimeOfDay/main-12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e949111b33e28834995807cab30ecb58d988a81a2d58fa166117962c85b8e149 -size 849 diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp index 437dcead3b..dcf86abb02 100644 --- a/Code/Editor/Viewport.cpp +++ b/Code/Editor/Viewport.cpp @@ -30,7 +30,6 @@ #include "Objects/ObjectManager.h" #include "Util/3DConnexionDriver.h" #include "PluginManager.h" -#include "Include/IRenderListener.h" #include "GameEngine.h" #include "Settings.h" @@ -227,61 +226,6 @@ void QtViewport::GetDimensions(int* pWidth, int* pHeight) const } } -////////////////////////////////////////////////////////////////////////// -void QtViewport::RegisterRenderListener(IRenderListener* piListener) -{ -#ifdef _DEBUG - size_t nCount(0); - size_t nTotal(0); - - nTotal = m_cRenderListeners.size(); - for (nCount = 0; nCount < nTotal; ++nCount) - { - if (m_cRenderListeners[nCount] == piListener) - { - assert(!"Registered the same RenderListener multiple times."); - break; - } - } -#endif //_DEBUG - m_cRenderListeners.push_back(piListener); -} - -////////////////////////////////////////////////////////////////////////// -bool QtViewport::UnregisterRenderListener(IRenderListener* piListener) -{ - size_t nCount(0); - size_t nTotal(0); - - nTotal = m_cRenderListeners.size(); - for (nCount = 0; nCount < nTotal; ++nCount) - { - if (m_cRenderListeners[nCount] == piListener) - { - m_cRenderListeners.erase(m_cRenderListeners.begin() + nCount); - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool QtViewport::IsRenderListenerRegistered(IRenderListener* piListener) -{ - size_t nCount(0); - size_t nTotal(0); - - nTotal = m_cRenderListeners.size(); - for (nCount = 0; nCount < nTotal; ++nCount) - { - if (m_cRenderListeners[nCount] == piListener) - { - return true; - } - } - return false; -} - ////////////////////////////////////////////////////////////////////////// void QtViewport::AddPostRenderer(IPostRenderer* pPostRenderer) { @@ -1164,18 +1108,6 @@ bool QtViewport::GetAdvancedSelectModeFlag() return m_bAdvancedSelectMode; } -////////////////////////////////////////////////////////////////////////// -void QtViewport::ProcessRenderLisneters(DisplayContext& rstDisplayContext) -{ - size_t nCount(0); - size_t nTotal(0); - - nTotal = m_cRenderListeners.size(); - for (nCount = 0; nCount < nTotal; ++nCount) - { - m_cRenderListeners[nCount]->Render(rstDisplayContext); - } -} ////////////////////////////////////////////////////////////////////////// #if defined(AZ_PLATFORM_WINDOWS) // Note: Both CreateAnglesYPR and CreateOrientationYPR were copied verbatim from Cry_Camera.h which has been removed. diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h index 1b0e5a4d93..d992eb4cb0 100644 --- a/Code/Editor/Viewport.h +++ b/Code/Editor/Viewport.h @@ -43,7 +43,6 @@ class CLayoutViewPane; class CViewManager; class CBaseObjectsCache; struct HitContext; -struct IRenderListener; class CImageEx; class QMenu; @@ -104,10 +103,6 @@ public: //! Access to view manager. CViewManager* GetViewManager() const { return m_viewManager; }; - virtual void RegisterRenderListener(IRenderListener* piListener) = 0; - virtual bool UnregisterRenderListener(IRenderListener* piListener) = 0; - virtual bool IsRenderListenerRegistered(IRenderListener* piListener) = 0; - virtual void AddPostRenderer(IPostRenderer* pPostRenderer) = 0; virtual bool RemovePostRenderer(IPostRenderer* pPostRenderer) = 0; @@ -477,10 +472,6 @@ public: void ResetCursor() override; void SetSupplementaryCursorStr(const QString& str) override; - void RegisterRenderListener(IRenderListener* piListener) override; - bool UnregisterRenderListener(IRenderListener* piListener) override; - bool IsRenderListenerRegistered(IRenderListener* piListener) override; - void AddPostRenderer(IPostRenderer* pPostRenderer) override; bool RemovePostRenderer(IPostRenderer* pPostRenderer) override; @@ -508,8 +499,6 @@ protected: void setRenderOverlayVisible(bool); bool isRenderOverlayVisible() const; - void ProcessRenderLisneters(DisplayContext& rstDisplayContext); - void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void mouseDoubleClickEvent(QMouseEvent* event) override; @@ -597,8 +586,6 @@ protected: // Same construction matrix is shared by all viewports. Matrix34 m_constructionMatrix[LAST_COORD_SYSTEM]; - std::vector m_cRenderListeners; - typedef std::vector<_smart_ptr > PostRenderers; PostRenderers m_postRenderers; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index 59a1a91647..345a8e15e1 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -270,7 +270,6 @@ set(FILES Include/Command.h Include/HitContext.h Include/ICommandManager.h - Include/IConsoleConnectivity.h Include/IDisplayViewport.h Include/IEditorClassFactory.h Include/IEventLoopHook.h @@ -282,9 +281,7 @@ set(FILES Include/IObjectManager.h Include/IPlugin.h Include/IPreferencesPage.h - Include/IRenderListener.h Include/ISourceControl.h - Include/ITextureDatabaseUpdater.h Include/ITransformManipulator.h Include/IViewPane.h Include/ObjectEvent.h diff --git a/Code/Editor/water.png b/Code/Editor/water.png deleted file mode 100644 index 342dee81e3..0000000000 --- a/Code/Editor/water.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4abde33fa9c29e927e403e275979536e7defbb6476eb375e85f847396645953f -size 41419 From b04cecc34dd9ace183fab95b97e393c3212de272 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Fri, 7 Jan 2022 14:28:38 -0800 Subject: [PATCH 119/272] Move Draw2d interface back to IDraw2d (#6730) * Move Draw2d interface back to IDraw2d Signed-off-by: abrmich * Fix compile error for gems using LyShine Signed-off-by: abrmich --- Gems/LyShine/Code/CMakeLists.txt | 3 + Gems/LyShine/Code/Include/LyShine/Draw2d.h | 363 +------------- Gems/LyShine/Code/Include/LyShine/IDraw2d.h | 457 ++++++++++++++++++ Gems/LyShine/Code/Source/LyShineDebug.cpp | 26 +- .../LyShine/Code/Source/UiCanvasComponent.cpp | 4 +- Gems/LyShine/Code/Source/UiCanvasComponent.h | 4 +- Gems/LyShine/Code/Source/UiCanvasManager.cpp | 6 +- Gems/LyShine/Code/Source/UiRenderer.cpp | 2 +- 8 files changed, 502 insertions(+), 363 deletions(-) diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 77aaa681e0..4f2c4e90a7 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -47,6 +47,9 @@ ly_add_target( Gem::LyShine.Static Legacy::CryCommon Gem::LmbrCentral + PUBLIC + Gem::Atom_RHI.Reflect + Gem::Atom_RPI.Public RUNTIME_DEPENDENCIES Gem::LmbrCentral Gem::TextureAtlas diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Include/LyShine/Draw2d.h index f92c6ce2e1..d138f41b03 100644 --- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/Draw2d.h @@ -8,13 +8,10 @@ #pragma once #include -#include -#include #include #include #include -#include #include //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,69 +20,11 @@ //! The CDraw2d class implements the IDraw2d interface for drawing 2D images, shapes and text. //! Positions and sizes are specified in pixels in the associated 2D viewport. class CDraw2d - : public IDraw2d // [LYSHINE_ATOM_TODO][GHI #3573] Make Draw2d work better as an API + : public IDraw2d , public AZ::Render::Bootstrap::NotificationBus::Handler { public: // types - struct RenderState - { - RenderState() - { - m_blendState.m_enable = true; - m_blendState.m_blendSource = AZ::RHI::BlendFactor::AlphaSource; - m_blendState.m_blendDest = AZ::RHI::BlendFactor::AlphaSourceInverse; - - m_depthState.m_enable = false; - } - - AZ::RHI::TargetBlendState m_blendState; - AZ::RHI::DepthState m_depthState; - }; - - //! Struct used to pass additional image options. - // - //! If this is not passed then the defaults are used - struct ImageOptions - { - AZ::Vector3 color = AZ::Vector3(1.0f, 1.0f, 1.0f); - Rounding pixelRounding = Rounding::Nearest; - bool m_clamp = false; - RenderState m_renderState; - }; - - //! Struct used to pass additional text options - mostly ones that do not change from call to call. - // - //! If this is not passed then the defaults below are used - struct TextOptions - { - AZStd::string fontName; //!< default is "default" - unsigned int effectIndex; //!< default is 0 - AZ::Vector3 color; //!< default is (1,1,1) - HAlign horizontalAlignment; //!< default is HAlign::Left - VAlign verticalAlignment; //!< default is VAlign::Top - AZ::Vector2 dropShadowOffset; //!< default is (0,0), zero offset means no drop shadow is drawn - AZ::Color dropShadowColor; //!< default is (0,0,0,0), zero alpha means no drop shadow is drawn - float rotation; //!< default is 0 - bool depthTestEnabled; //!< default is false - }; - - //! Used to pass in arrays of vertices (e.g. to DrawQuad) - struct VertexPosColUV - { - VertexPosColUV() {} - VertexPosColUV(const AZ::Vector2& inPos, const AZ::Color& inColor, const AZ::Vector2& inUV) - { - position = inPos; - color = inColor; - uv = inUV; - } - - AZ::Vector2 position; //!< 2D position of vertex - AZ::Color color; //!< Float color - AZ::Vector2 uv; //!< Texture coordinate - }; - public: // member functions //! Constructor, constructed by the LyShine class @@ -116,7 +55,7 @@ public: // member functions //! \param imageOptions Optional struct specifying options that tend to be the same from call to call void DrawImage(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr, - ImageOptions* imageOptions = nullptr); + ImageOptions* imageOptions = nullptr) override; //! Draw a textured quad where the position specifies the point specified by the alignment. // @@ -135,7 +74,7 @@ public: // member functions void DrawImageAligned(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, HAlign horizontalAlignment, VAlign verticalAlignment, float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr, - ImageOptions* imageOptions = nullptr); + ImageOptions* imageOptions = nullptr) override; //! Draw a textured quad where the position, color and uv of each point is specified explicitly // @@ -143,11 +82,11 @@ public: // member functions //! \param verts An array of 4 vertices, in clockwise order (e.g. top left, top right, bottom right, bottom left) //! \param pixelRounding Whether and how to round pixel coordinates //! \param renderState Blend mode and depth state - virtual void DrawQuad(AZ::Data::Instance image, + void DrawQuad(AZ::Data::Instance image, VertexPosColUV* verts, Rounding pixelRounding = Rounding::Nearest, bool clamp = false, - const RenderState& renderState = RenderState{}); + const RenderState& renderState = RenderState{}) override; //! Draw a line // @@ -156,9 +95,9 @@ public: // member functions //! \param color The color of the line //! \param pixelRounding Whether and how to round pixel coordinates //! \param renderState Blend mode and depth state - virtual void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, + void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, - const RenderState& renderState = RenderState{}); + const RenderState& renderState = RenderState{}) override; //! Draw a line with a texture so it can be dotted or dashed // @@ -166,10 +105,10 @@ public: // member functions //! \param verts An array of 2 vertices for the start and end points of the line //! \param pixelRounding Whether and how to round pixel coordinates //! \param renderState Blend mode and depth state - virtual void DrawLineTextured(AZ::Data::Instance image, + void DrawLineTextured(AZ::Data::Instance image, VertexPosColUV* verts, IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, - const RenderState& renderState = RenderState{}); + const RenderState& renderState = RenderState{}) override; //! Draw a text string. Only supports ASCII text. // //! The font and effect used to render the text are specified in the textOptions structure @@ -179,7 +118,7 @@ public: // member functions //! \param opacity The opacity (alpha value) to use to draw the text //! \param textOptions Pointer to an options struct. If null the default options are used void DrawText(const char* textString, AZ::Vector2 position, float pointSize, - float opacity = 1.0f, TextOptions* textOptions = nullptr); + float opacity = 1.0f, TextOptions* textOptions = nullptr) override; //! Draw a rectangular outline with a texture // @@ -194,43 +133,43 @@ public: // member functions AZ::Vector2 rightVec, AZ::Vector2 downVec, AZ::Color color, - uint32_t lineThickness = 0); + uint32_t lineThickness = 0) override; //! Get the width and height (in pixels) that would be used to draw the given text string. // //! Pass the same parameter values that would be used to draw the string - AZ::Vector2 GetTextSize(const char* textString, float pointSize, TextOptions* textOptions = nullptr); + AZ::Vector2 GetTextSize(const char* textString, float pointSize, TextOptions* textOptions = nullptr) override; //! Get the width of the rendering viewport (in pixels). - float GetViewportWidth() const; + float GetViewportWidth() const override; //! Get the height of the rendering viewport (in pixels). - float GetViewportHeight() const; + float GetViewportHeight() const override; //! Get dpi scale factor - float GetViewportDpiScalingFactor() const; + float GetViewportDpiScalingFactor() const override; //! Get the default values that would be used if no image options were passed in // //! This is a convenient way to initialize the imageOptions struct - virtual const ImageOptions& GetDefaultImageOptions() const; + const ImageOptions& GetDefaultImageOptions() const override; //! Get the default values that would be used if no text options were passed in // //! This is a convenient way to initialize the textOptions struct - virtual const TextOptions& GetDefaultTextOptions() const; + const TextOptions& GetDefaultTextOptions() const override; //! Render the primitives that have been deferred - void RenderDeferredPrimitives(); + void RenderDeferredPrimitives() override; //! Specify whether to defer future primitives or render them right away - void SetDeferPrimitives(bool deferPrimitives); + void SetDeferPrimitives(bool deferPrimitives) override; //! Return whether future primitives will be deferred or rendered right away - bool GetDeferPrimitives(); + bool GetDeferPrimitives() override; //! Set sort key offset for following draws. - void SetSortKey(int64_t key); + void SetSortKey(int64_t key) override; private: @@ -378,263 +317,3 @@ protected: // attributes AZ::RHI::Ptr m_dynamicDraw; Draw2dShaderData m_shaderData; }; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//! Helper class for using the IDraw2d interface -//! -//! The Draw2dHelper class is an inline wrapper that provides the convenience feature of -//! automatically setting member options structures to their defaults and providing set functions. -class Draw2dHelper -{ -public: // member functions - - //! Start a section of 2D drawing function calls that will render to the default viewport - Draw2dHelper(bool deferCalls = false) - { - InitCommon(nullptr, deferCalls); - } - - //! Start a section of 2D drawing function calls that will render to the viewport - //! associated with the specified Draw2d object - Draw2dHelper(CDraw2d* draw2d, bool deferCalls = false) - { - InitCommon(draw2d, deferCalls); - } - - void InitCommon(CDraw2d* draw2d, bool deferCalls) - { - m_draw2d = draw2d; - - if (!m_draw2d) - { - // Set to default which is the game's draw 2d object - m_draw2d = GetDefaultDraw2d(); - } - - if (m_draw2d) - { - m_previousDeferCalls = m_draw2d->GetDeferPrimitives(); - m_draw2d->SetDeferPrimitives(deferCalls); - m_imageOptions = m_draw2d->GetDefaultImageOptions(); - m_textOptions = m_draw2d->GetDefaultTextOptions(); - } - } - - //! End a section of 2D drawing function calls. - ~Draw2dHelper() - { - if (m_draw2d) - { - m_draw2d->SetDeferPrimitives(m_previousDeferCalls); - } - } - - //! Draw a textured quad, optional rotation is counter-clockwise in degrees. - // - //! See IDraw2d:DrawImage for parameter descriptions - void DrawImage(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f, - float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr) - { - if (m_draw2d) - { - m_draw2d->DrawImage(image, position, size, opacity, rotation, pivotPoint, minMaxTexCoords, &m_imageOptions); - } - } - - //! Draw a textured quad where the position specifies the point specified by the alignment. - // - //! See IDraw2d:DrawImageAligned for parameter descriptions - void DrawImageAligned(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, - IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment, - float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr) - { - if (m_draw2d) - { - m_draw2d->DrawImageAligned(image, position, size, horizontalAlignment, verticalAlignment, - opacity, rotation, minMaxTexCoords, &m_imageOptions); - } - } - - //! Draw a textured quad where the position, color and uv of each point is specified explicitly - // - //! See IDraw2d:DrawQuad for parameter descriptions - void DrawQuad(AZ::Data::Instance image, CDraw2d::VertexPosColUV* verts, - IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, - bool clamp = false, - const CDraw2d::RenderState& renderState = CDraw2d::RenderState{}) - { - if (m_draw2d) - { - m_draw2d->DrawQuad(image, verts, pixelRounding, clamp, renderState); - } - } - - //! Draw a line - // - //! See IDraw2d:DrawLine for parameter descriptions - void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, - IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, - const CDraw2d::RenderState& renderState = CDraw2d::RenderState{}) - { - if (m_draw2d) - { - m_draw2d->DrawLine(start, end, color, pixelRounding, renderState); - } - } - - //! Draw a line with a texture so it can be dotted or dashed - // - //! See IDraw2d:DrawLineTextured for parameter descriptions - void DrawLineTextured(AZ::Data::Instance image, CDraw2d::VertexPosColUV* verts, - IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, - const CDraw2d::RenderState& renderState = CDraw2d::RenderState{}) - { - if (m_draw2d) - { - m_draw2d->DrawLineTextured(image, verts, pixelRounding, renderState); - } - } - - //! Draw a rect outline with a texture - // - //! See IDraw2d:DrawRectOutlineTextured for parameter descriptions - void DrawRectOutlineTextured(AZ::Data::Instance image, - UiTransformInterface::RectPoints points, - AZ::Vector2 rightVec, - AZ::Vector2 downVec, - AZ::Color color, - uint32_t lineThickness = 0) - { - if (m_draw2d) - { - m_draw2d->DrawRectOutlineTextured(image, points, rightVec, downVec, color, lineThickness); - } - } - - //! Draw a text string. Only supports ASCII text. - // - //! See IDraw2d:DrawText for parameter descriptions - void DrawText(const char* textString, AZ::Vector2 position, float pointSize, float opacity = 1.0f) - { - if (m_draw2d) - { - m_draw2d->DrawText(textString, position, pointSize, opacity, &m_textOptions); - } - } - - //! Get the width and height (in pixels) that would be used to draw the given text string. - // - //! See IDraw2d:GetTextSize for parameter descriptions - AZ::Vector2 GetTextSize(const char* textString, float pointSize) - { - if (m_draw2d) - { - return m_draw2d->GetTextSize(textString, pointSize, &m_textOptions); - } - else - { - return AZ::Vector2(0, 0); - } - } - - // State management - - //! Set the blend mode used for images, default is GS_BLSRC_SRCALPHA|GS_BLDST_ONEMINUSSRCALPHA. - void SetImageBlendMode(const AZ::RHI::TargetBlendState& blendState) { m_imageOptions.m_renderState.m_blendState = blendState; } - - //! Set the color used for DrawImage and other image drawing. - void SetImageColor(AZ::Vector3 color) { m_imageOptions.color = color; } - - //! Set whether images are rounded to have the points on exact pixel boundaries. - void SetImagePixelRounding(IDraw2d::Rounding round) { m_imageOptions.pixelRounding = round; } - - //! Set the base state (that blend mode etc is combined with) used for images, default is GS_NODEPTHTEST. - void SetImageDepthState(const AZ::RHI::DepthState& depthState) { m_imageOptions.m_renderState.m_depthState = depthState; } - - //! Set image clamp mode - void SetImageClamp(bool clamp) { m_imageOptions.m_clamp = clamp; } - - //! Set the text font. - void SetTextFont(AZStd::string_view fontName) { m_textOptions.fontName = fontName; } - - //! Set the text font effect index. - void SetTextEffectIndex(unsigned int effectIndex) { m_textOptions.effectIndex = effectIndex; } - - //! Set the text color. - void SetTextColor(AZ::Vector3 color) { m_textOptions.color = color; } - - //! Set the text alignment. - void SetTextAlignment(IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment) - { - m_textOptions.horizontalAlignment = horizontalAlignment; - m_textOptions.verticalAlignment = verticalAlignment; - } - - //! Set a drop shadow for text drawing. An alpha of zero disables drop shadow. - void SetTextDropShadow(AZ::Vector2 offset, AZ::Color color) - { - m_textOptions.dropShadowOffset = offset; - m_textOptions.dropShadowColor = color; - } - - //! Set a rotation for the text. The text rotates around its position (taking into account alignment). - void SetTextRotation(float rotation) - { - m_textOptions.rotation = rotation; - } - - //! Set wheter to enable depth test for the text - void SetTextDepthTestEnabled(bool enabled) - { - m_textOptions.depthTestEnabled = enabled; - } - -public: // static member functions - - //! Helper to get the default IDraw2d interface - static CDraw2d* GetDefaultDraw2d() - { - if (gEnv && gEnv->pLyShine) // [LYSHINE_ATOM_TODO][GHI #3569] Remove LyShine global interface pointer from legacy global environment - { - IDraw2d* draw2d = gEnv->pLyShine->GetDraw2d(); - return reinterpret_cast(draw2d); - } - - return nullptr; - } - - //! Round the X and Y coordinates of a point using the given rounding policy - template - static T RoundXY(T value, IDraw2d::Rounding roundingType) - { - T result = value; - - switch (roundingType) - { - case IDraw2d::Rounding::None: - // nothing to do - break; - case IDraw2d::Rounding::Nearest: - result.SetX(floor(value.GetX() + 0.5f)); - result.SetY(floor(value.GetY() + 0.5f)); - break; - case IDraw2d::Rounding::Down: - result.SetX(floor(value.GetX())); - result.SetY(floor(value.GetY())); - break; - case IDraw2d::Rounding::Up: - result.SetX(ceil(value.GetX())); - result.SetY(ceil(value.GetY())); - break; - } - - return result; - } - -protected: // attributes - - CDraw2d::ImageOptions m_imageOptions; //!< image options are stored locally and updated by member functions - CDraw2d::TextOptions m_textOptions; //!< text options are stored locally and updated by member functions - CDraw2d* m_draw2d; - bool m_previousDeferCalls; -}; diff --git a/Gems/LyShine/Code/Include/LyShine/IDraw2d.h b/Gems/LyShine/Code/Include/LyShine/IDraw2d.h index 3bfa3a1c14..620b8c23c9 100644 --- a/Gems/LyShine/Code/Include/LyShine/IDraw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/IDraw2d.h @@ -11,6 +11,10 @@ #include #include #include +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// //! Class for 2D drawing in screen space @@ -55,8 +59,461 @@ public: // types MAX_TEXT_STRING_LENGTH = 1024, }; + struct RenderState + { + RenderState() + { + m_blendState.m_enable = true; + m_blendState.m_blendSource = AZ::RHI::BlendFactor::AlphaSource; + m_blendState.m_blendDest = AZ::RHI::BlendFactor::AlphaSourceInverse; + + m_depthState.m_enable = false; + } + + AZ::RHI::TargetBlendState m_blendState; + AZ::RHI::DepthState m_depthState; + }; + + //! Struct used to pass additional image options. + // + //! If this is not passed then the defaults are used + struct ImageOptions + { + AZ::Vector3 color = AZ::Vector3(1.0f, 1.0f, 1.0f); + Rounding pixelRounding = Rounding::Nearest; + bool m_clamp = false; + RenderState m_renderState; + }; + + //! Struct used to pass additional text options - mostly ones that do not change from call to call. + // + //! If this is not passed then the defaults below are used + struct TextOptions + { + AZStd::string fontName; //!< default is "default" + unsigned int effectIndex; //!< default is 0 + AZ::Vector3 color; //!< default is (1,1,1) + HAlign horizontalAlignment; //!< default is HAlign::Left + VAlign verticalAlignment; //!< default is VAlign::Top + AZ::Vector2 dropShadowOffset; //!< default is (0,0), zero offset means no drop shadow is drawn + AZ::Color dropShadowColor; //!< default is (0,0,0,0), zero alpha means no drop shadow is drawn + float rotation; //!< default is 0 + bool depthTestEnabled; //!< default is false + }; + + //! Used to pass in arrays of vertices (e.g. to DrawQuad) + struct VertexPosColUV + { + VertexPosColUV() {} + VertexPosColUV(const AZ::Vector2& inPos, const AZ::Color& inColor, const AZ::Vector2& inUV) + { + position = inPos; + color = inColor; + uv = inUV; + } + + AZ::Vector2 position; //!< 2D position of vertex + AZ::Color color; //!< Float color + AZ::Vector2 uv; //!< Texture coordinate + }; + public: // member functions //! Implement virtual destructor just for safety. virtual ~IDraw2d() {} + + //! Draw a textured quad with the top left corner at the given position. + // + //! The image is drawn with the color specified by SetShapeColor and the opacity + //! passed as an argument. + //! If rotation is non-zero then the quad is rotated. If the pivot point is + //! provided then the points of the quad are rotated about that point, otherwise + //! they are rotated about the top left corner of the quad. + //! \param texId The texture ID returned by ITexture::GetTextureID() + //! \param position Position of the top left corner of the quad (before rotation) in pixels + //! \param size The width and height of the quad. Use texture width and height to avoid minification, + //! magnification or stretching (assuming the minMaxTexCoords are left to the default) + //! \param opacity The alpha value used when blending + //! \param rotation Angle of rotation in degrees counter-clockwise + //! \param pivotPoint The point about which the quad is rotated + //! \param minMaxTexCoords An optional two component array. The first component is the UV coord for the top left + //! point of the quad and the second is the UV coord of the bottom right point of the quad + //! \param imageOptions Optional struct specifying options that tend to be the same from call to call + virtual void DrawImage(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f, + float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr, + ImageOptions* imageOptions = nullptr) = 0; + + //! Draw a textured quad where the position specifies the point specified by the alignment. + // + //! Rotation is always around the position. + //! \param texId The texture ID returned by ITexture::GetTextureID() + //! \param position Position align point of the quad (before rotation) in pixels + //! \param size The width and height of the quad. Use texture width and height to avoid minification, + //! magnification or stretching (assuming the minMaxTexCoords are left to the default) + //! \param horizontalAlignment Specifies how the quad is horizontally aligned to the given position + //! \param verticalAlignment Specifies how the quad is vertically aligned to the given position + //! \param opacity The alpha value used when blending + //! \param rotation Angle of rotation in degrees counter-clockwise + //! \param minMaxTexCoords An optional two component array. The first component is the UV coord for the top left + //! point of the quad and the second is the UV coord of the bottom right point of the quad + //! \param imageOptions Optional struct specifying options that tend to be the same from call to call + virtual void DrawImageAligned(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, + HAlign horizontalAlignment, VAlign verticalAlignment, + float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr, + ImageOptions* imageOptions = nullptr) = 0; + + //! Draw a textured quad where the position, color and uv of each point is specified explicitly + // + //! \param texId The texture ID returned by ITexture::GetTextureID() + //! \param verts An array of 4 vertices, in clockwise order (e.g. top left, top right, bottom right, bottom left) + //! \param pixelRounding Whether and how to round pixel coordinates + //! \param renderState Blend mode and depth state + virtual void DrawQuad(AZ::Data::Instance image, + VertexPosColUV* verts, + Rounding pixelRounding = Rounding::Nearest, + bool clamp = false, + const RenderState& renderState = RenderState{}) = 0; + + //! Draw a line + // + //! \param start The start position + //! \param end The end position + //! \param color The color of the line + //! \param pixelRounding Whether and how to round pixel coordinates + //! \param renderState Blend mode and depth state + virtual void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, + IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + const RenderState& renderState = RenderState{}) = 0; + + //! Draw a line with a texture so it can be dotted or dashed + // + //! \param texId The texture ID returned by ITexture::GetTextureID() + //! \param verts An array of 2 vertices for the start and end points of the line + //! \param pixelRounding Whether and how to round pixel coordinates + //! \param renderState Blend mode and depth state + virtual void DrawLineTextured(AZ::Data::Instance image, + VertexPosColUV* verts, + IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + const RenderState& renderState = RenderState{}) = 0; + //! Draw a text string. Only supports ASCII text. + // + //! The font and effect used to render the text are specified in the textOptions structure + //! \param textString A null terminated ASCII text string. May contain \n characters + //! \param position Position of the text in pixels. Alignment values in textOptions affect actual position + //! \param pointSize The size of the font to use + //! \param opacity The opacity (alpha value) to use to draw the text + //! \param textOptions Pointer to an options struct. If null the default options are used + virtual void DrawText(const char* textString, AZ::Vector2 position, float pointSize, + float opacity = 1.0f, TextOptions* textOptions = nullptr) = 0; + + //! Draw a rectangular outline with a texture + // + //! \param image The texture to be used for drawing the outline + //! \param points The rect's vertices (top left, top right, bottom right, bottom left) + //! \param rightVec Right vector. Specified because the rect's width/height could be 0 + //! \param downVec Down vector. Specified because the rect's width/height could be 0 + //! \param color The color of the outline + //! \param lineThickness The thickness in pixels of the outline. If 0, it will be based on image height + virtual void DrawRectOutlineTextured(AZ::Data::Instance image, + UiTransformInterface::RectPoints points, + AZ::Vector2 rightVec, + AZ::Vector2 downVec, + AZ::Color color, + uint32_t lineThickness = 0) = 0; + + //! Get the width and height (in pixels) that would be used to draw the given text string. + // + //! Pass the same parameter values that would be used to draw the string + virtual AZ::Vector2 GetTextSize(const char* textString, float pointSize, TextOptions* textOptions = nullptr) = 0; + + //! Get the width of the rendering viewport (in pixels). + virtual float GetViewportWidth() const = 0; + + //! Get the height of the rendering viewport (in pixels). + virtual float GetViewportHeight() const = 0; + + //! Get dpi scale factor + virtual float GetViewportDpiScalingFactor() const = 0; + + //! Get the default values that would be used if no image options were passed in + // + //! This is a convenient way to initialize the imageOptions struct + virtual const ImageOptions& GetDefaultImageOptions() const = 0; + + //! Get the default values that would be used if no text options were passed in + // + //! This is a convenient way to initialize the textOptions struct + virtual const TextOptions& GetDefaultTextOptions() const = 0; + + //! Render the primitives that have been deferred + virtual void RenderDeferredPrimitives() = 0; + + //! Specify whether to defer future primitives or render them right away + virtual void SetDeferPrimitives(bool deferPrimitives) = 0; + + //! Return whether future primitives will be deferred or rendered right away + virtual bool GetDeferPrimitives() = 0; + + //! Set sort key offset for following draws. + virtual void SetSortKey(int64_t key) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//! Helper class for using the IDraw2d interface +//! +//! The Draw2dHelper class is an inline wrapper that provides the convenience feature of +//! automatically setting member options structures to their defaults and providing set functions. +class Draw2dHelper +{ +public: // member functions + + //! Start a section of 2D drawing function calls that will render to the default viewport + Draw2dHelper(bool deferCalls = false) + { + InitCommon(nullptr, deferCalls); + } + + //! Start a section of 2D drawing function calls that will render to the viewport + //! associated with the specified Draw2d object + Draw2dHelper(IDraw2d* draw2d, bool deferCalls = false) + { + InitCommon(draw2d, deferCalls); + } + + void InitCommon(IDraw2d* draw2d, bool deferCalls) + { + m_draw2d = draw2d; + + if (!m_draw2d) + { + // Set to default which is the game's draw 2d object + m_draw2d = GetDefaultDraw2d(); + } + + if (m_draw2d) + { + m_previousDeferCalls = m_draw2d->GetDeferPrimitives(); + m_draw2d->SetDeferPrimitives(deferCalls); + m_imageOptions = m_draw2d->GetDefaultImageOptions(); + m_textOptions = m_draw2d->GetDefaultTextOptions(); + } + } + + //! End a section of 2D drawing function calls. + ~Draw2dHelper() + { + if (m_draw2d) + { + m_draw2d->SetDeferPrimitives(m_previousDeferCalls); + } + } + + //! Draw a textured quad, optional rotation is counter-clockwise in degrees. + // + //! See IDraw2d:DrawImage for parameter descriptions + void DrawImage(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, float opacity = 1.0f, + float rotation = 0.0f, const AZ::Vector2* pivotPoint = nullptr, const AZ::Vector2* minMaxTexCoords = nullptr) + { + if (m_draw2d) + { + m_draw2d->DrawImage(image, position, size, opacity, rotation, pivotPoint, minMaxTexCoords, &m_imageOptions); + } + } + + //! Draw a textured quad where the position specifies the point specified by the alignment. + // + //! See IDraw2d:DrawImageAligned for parameter descriptions + void DrawImageAligned(AZ::Data::Instance image, AZ::Vector2 position, AZ::Vector2 size, + IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment, + float opacity = 1.0f, float rotation = 0.0f, const AZ::Vector2* minMaxTexCoords = nullptr) + { + if (m_draw2d) + { + m_draw2d->DrawImageAligned(image, position, size, horizontalAlignment, verticalAlignment, + opacity, rotation, minMaxTexCoords, &m_imageOptions); + } + } + + //! Draw a textured quad where the position, color and uv of each point is specified explicitly + // + //! See IDraw2d:DrawQuad for parameter descriptions + void DrawQuad(AZ::Data::Instance image, IDraw2d::VertexPosColUV* verts, + IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + bool clamp = false, + const IDraw2d::RenderState& renderState = IDraw2d::RenderState{}) + { + if (m_draw2d) + { + m_draw2d->DrawQuad(image, verts, pixelRounding, clamp, renderState); + } + } + + //! Draw a line + // + //! See IDraw2d:DrawLine for parameter descriptions + void DrawLine(AZ::Vector2 start, AZ::Vector2 end, AZ::Color color, + IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + const IDraw2d::RenderState& renderState = IDraw2d::RenderState{}) + { + if (m_draw2d) + { + m_draw2d->DrawLine(start, end, color, pixelRounding, renderState); + } + } + + //! Draw a line with a texture so it can be dotted or dashed + // + //! See IDraw2d:DrawLineTextured for parameter descriptions + void DrawLineTextured(AZ::Data::Instance image, IDraw2d::VertexPosColUV* verts, + IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest, + const IDraw2d::RenderState& renderState = IDraw2d::RenderState{}) + { + if (m_draw2d) + { + m_draw2d->DrawLineTextured(image, verts, pixelRounding, renderState); + } + } + + //! Draw a rect outline with a texture + // + //! See IDraw2d:DrawRectOutlineTextured for parameter descriptions + void DrawRectOutlineTextured(AZ::Data::Instance image, + UiTransformInterface::RectPoints points, + AZ::Vector2 rightVec, + AZ::Vector2 downVec, + AZ::Color color, + uint32_t lineThickness = 0) + { + if (m_draw2d) + { + m_draw2d->DrawRectOutlineTextured(image, points, rightVec, downVec, color, lineThickness); + } + } + + //! Draw a text string. Only supports ASCII text. + // + //! See IDraw2d:DrawText for parameter descriptions + void DrawText(const char* textString, AZ::Vector2 position, float pointSize, float opacity = 1.0f) + { + if (m_draw2d) + { + m_draw2d->DrawText(textString, position, pointSize, opacity, &m_textOptions); + } + } + + //! Get the width and height (in pixels) that would be used to draw the given text string. + // + //! See IDraw2d:GetTextSize for parameter descriptions + AZ::Vector2 GetTextSize(const char* textString, float pointSize) + { + if (m_draw2d) + { + return m_draw2d->GetTextSize(textString, pointSize, &m_textOptions); + } + else + { + return AZ::Vector2(0, 0); + } + } + + // State management + + //! Set the blend mode used for images, default is GS_BLSRC_SRCALPHA|GS_BLDST_ONEMINUSSRCALPHA. + void SetImageBlendMode(const AZ::RHI::TargetBlendState& blendState) { m_imageOptions.m_renderState.m_blendState = blendState; } + + //! Set the color used for DrawImage and other image drawing. + void SetImageColor(AZ::Vector3 color) { m_imageOptions.color = color; } + + //! Set whether images are rounded to have the points on exact pixel boundaries. + void SetImagePixelRounding(IDraw2d::Rounding round) { m_imageOptions.pixelRounding = round; } + + //! Set the base state (that blend mode etc is combined with) used for images, default is GS_NODEPTHTEST. + void SetImageDepthState(const AZ::RHI::DepthState& depthState) { m_imageOptions.m_renderState.m_depthState = depthState; } + + //! Set image clamp mode + void SetImageClamp(bool clamp) { m_imageOptions.m_clamp = clamp; } + + //! Set the text font. + void SetTextFont(AZStd::string_view fontName) { m_textOptions.fontName = fontName; } + + //! Set the text font effect index. + void SetTextEffectIndex(unsigned int effectIndex) { m_textOptions.effectIndex = effectIndex; } + + //! Set the text color. + void SetTextColor(AZ::Vector3 color) { m_textOptions.color = color; } + + //! Set the text alignment. + void SetTextAlignment(IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment) + { + m_textOptions.horizontalAlignment = horizontalAlignment; + m_textOptions.verticalAlignment = verticalAlignment; + } + + //! Set a drop shadow for text drawing. An alpha of zero disables drop shadow. + void SetTextDropShadow(AZ::Vector2 offset, AZ::Color color) + { + m_textOptions.dropShadowOffset = offset; + m_textOptions.dropShadowColor = color; + } + + //! Set a rotation for the text. The text rotates around its position (taking into account alignment). + void SetTextRotation(float rotation) + { + m_textOptions.rotation = rotation; + } + + //! Set wheter to enable depth test for the text + void SetTextDepthTestEnabled(bool enabled) + { + m_textOptions.depthTestEnabled = enabled; + } + +public: // static member functions + + //! Helper to get the default IDraw2d interface + static IDraw2d* GetDefaultDraw2d() + { + if (gEnv && gEnv->pLyShine) // [LYSHINE_ATOM_TODO][GHI #3569] Remove LyShine global interface pointer from legacy global environment + { + IDraw2d* draw2d = gEnv->pLyShine->GetDraw2d(); + return reinterpret_cast(draw2d); + } + + return nullptr; + } + + //! Round the X and Y coordinates of a point using the given rounding policy + template + static T RoundXY(T value, IDraw2d::Rounding roundingType) + { + T result = value; + + switch (roundingType) + { + case IDraw2d::Rounding::None: + // nothing to do + break; + case IDraw2d::Rounding::Nearest: + result.SetX(floor(value.GetX() + 0.5f)); + result.SetY(floor(value.GetY() + 0.5f)); + break; + case IDraw2d::Rounding::Down: + result.SetX(floor(value.GetX())); + result.SetY(floor(value.GetY())); + break; + case IDraw2d::Rounding::Up: + result.SetX(ceil(value.GetX())); + result.SetY(ceil(value.GetY())); + break; + } + + return result; + } + +protected: // attributes + + IDraw2d::ImageOptions m_imageOptions; //!< image options are stored locally and updated by member functions + IDraw2d::TextOptions m_textOptions; //!< text options are stored locally and updated by member functions + IDraw2d* m_draw2d; + bool m_previousDeferCalls; }; diff --git a/Gems/LyShine/Code/Source/LyShineDebug.cpp b/Gems/LyShine/Code/Source/LyShineDebug.cpp index 7762b1403b..bb57e70857 100644 --- a/Gems/LyShine/Code/Source/LyShineDebug.cpp +++ b/Gems/LyShine/Code/Source/LyShineDebug.cpp @@ -375,7 +375,7 @@ static void DebugDrawColoredBox(AZ::Vector2 pos, AZ::Vector2 size, AZ::Color col IDraw2d::HAlign horizontalAlignment = IDraw2d::HAlign::Left, IDraw2d::VAlign verticalAlignment = IDraw2d::VAlign::Top) { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); imageOptions.color = color.GetAsVector3(); @@ -390,7 +390,7 @@ static void DebugDrawColoredBox(AZ::Vector2 pos, AZ::Vector2 size, AZ::Color col static void DebugDrawStringWithSizeBox(AZStd::string_view font, unsigned int effectIndex, const char* sizeString, const char* testString, AZ::Vector2 pos, float spacing, float size) { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); if (!font.empty()) @@ -424,7 +424,7 @@ static void DebugDrawStringWithSizeBox(AZStd::string_view font, unsigned int eff #if !defined(_RELEASE) static void DebugDraw2dFontSizes(AZStd::string_view font, unsigned int effectIndex) { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); float xOffset = 20.0f; float yOffset = 20.0f; @@ -546,7 +546,7 @@ static void DebugDrawAlignedTextWithOriginBox(AZ::Vector2 pos, #if !defined(_RELEASE) static void DebugDraw2dFontAlignment() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); float w = draw2d->GetViewportWidth(); float yPos = 20; @@ -613,7 +613,7 @@ static void DebugDraw2dFontAlignment() #if !defined(_RELEASE) static AZ::Vector2 DebugDrawFontColorTestBox(AZ::Vector2 pos, const char* string, AZ::Vector3 color, float opacity) { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); float pointSize = 32.0f; const float spacing = 6.0f; @@ -648,7 +648,7 @@ static AZ::Vector2 DebugDrawFontColorTestBox(AZ::Vector2 pos, const char* string #if !defined(_RELEASE) static void DebugDraw2dFontColorAndOpacity() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); AZ::Vector2 size; AZ::Vector2 pos(20.0f, 20.0f); @@ -686,7 +686,7 @@ static void DebugDraw2dFontColorAndOpacity() #if !defined(_RELEASE) static void DebugDraw2dImageRotations() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); AZ::Data::Instance texture = GetMonoTestTexture(); @@ -738,7 +738,7 @@ static void DebugDraw2dImageRotations() #if !defined(_RELEASE) static void DebugDraw2dImageColor() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); AZ::Data::Instance texture = GetMonoAlphaTestTexture(); @@ -774,7 +774,7 @@ static void DebugDraw2dImageColor() #if !defined(_RELEASE) static void DebugDraw2dImageBlendMode() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); auto whiteTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White); @@ -841,7 +841,7 @@ static void DebugDraw2dImageBlendMode() #if !defined(_RELEASE) static void DebugDraw2dImageUVs() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); AZ::Data::Instance texture = GetColorTestTexture(); @@ -890,7 +890,7 @@ static void DebugDraw2dImageUVs() #if !defined(_RELEASE) static void DebugDraw2dImagePixelRounding() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); AZ::Data::Instance texture = GetColorTestTexture(); @@ -931,7 +931,7 @@ static void DebugDraw2dImagePixelRounding() #if !defined(_RELEASE) static void DebugDraw2dLineBasic() { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); @@ -1422,7 +1422,7 @@ void LyShineDebug::RenderDebug() #if !defined(_RELEASE) #ifndef EXCLUDE_DOCUMENTATION_PURPOSE - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); if (!draw2d) { return; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index 78b9c71f8e..0a21f92119 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -2122,13 +2122,13 @@ void UiCanvasComponent::DebugReportDrawCalls(AZ::IO::HandleType fileHandle, LySh } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UiCanvasComponent::DebugDisplayElemBounds(CDraw2d* draw2d) const +void UiCanvasComponent::DebugDisplayElemBounds(IDraw2d* draw2d) const { DebugDisplayChildElemBounds(draw2d, m_rootElement); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UiCanvasComponent::DebugDisplayChildElemBounds(CDraw2d* draw2d, const AZ::EntityId entity) const +void UiCanvasComponent::DebugDisplayChildElemBounds(IDraw2d* draw2d, const AZ::EntityId entity) const { AZ::u64 time = AZStd::GetTimeUTCMilliSecond(); uint32 fractionsOfOneSecond = time % 1000; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.h b/Gems/LyShine/Code/Source/UiCanvasComponent.h index 79cb044af0..050773131f 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.h +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.h @@ -292,8 +292,8 @@ public: // member functions void DebugReportDrawCalls(AZ::IO::HandleType fileHandle, LyShineDebug::DebugInfoDrawCallReport& reportInfo, void* context) const; - void DebugDisplayElemBounds(CDraw2d* draw2d) const; - void DebugDisplayChildElemBounds(CDraw2d* draw2d, const AZ::EntityId entity) const; + void DebugDisplayElemBounds(IDraw2d* draw2d) const; + void DebugDisplayChildElemBounds(IDraw2d* draw2d, const AZ::EntityId entity) const; #endif public: // static member functions diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index c6564f9b3a..70646246f0 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -997,7 +997,7 @@ void UiCanvasManager::DebugDisplayCanvasData(int setting) const { bool onlyShowEnabledCanvases = (setting == 2) ? true : false; - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); float dpiScale = draw2d->GetViewportDpiScalingFactor(); float xOffset = 20.0f * dpiScale; @@ -1152,7 +1152,7 @@ void UiCanvasManager::DebugDisplayCanvasData(int setting) const //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasManager::DebugDisplayDrawCallData() const { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); float dpiScale = draw2d->GetViewportDpiScalingFactor(); float xOffset = 20.0f * dpiScale; @@ -1486,7 +1486,7 @@ void UiCanvasManager::DebugReportDrawCalls(const AZStd::string& name) const //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasManager::DebugDisplayElemBounds(int canvasIndexFilter) const { - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); int canvasIndex = 0; for (auto canvas : m_loadedCanvases) diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index 64ec1bb485..acf17049ad 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -414,7 +414,7 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) return lhs.second > rhs.second; }); - CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); + IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); // setup to render lines of text for the debug display From 57e4fb9b393a9f37a6c31e4d65a87cff49de2aa7 Mon Sep 17 00:00:00 2001 From: moraaar Date: Mon, 10 Jan 2022 09:05:35 +0000 Subject: [PATCH 120/272] Fixed script canvas component asset not being found (#6727) Script canvas component has the member m_sourceData (that points to the script canvas asset) that internally has data, id and path. Path is serialized as the absolute path of the pc that is saving the level. So when another pc loads the same level it cannot find the script canvas asset. The function CompleteDescription takes a look at the id and takes the path from the asset catalog, but at the moment it's doing an early return because id and path are not empty (but path is the value serialized from other user saving the level). By removing the early return condition then it it will resolve by using id, looking into the catalog and getting the real path. This fix makes several physics automated tests that relied on script canvas to work. Signed-off-by: moraaar moraaar@amazon.com --- Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp index 2cd2dda89e..363f477fbf 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp @@ -33,11 +33,6 @@ namespace ScriptCanvasEditor { AZStd::optional CompleteDescription(const SourceHandle& source) { - if (source.IsDescriptionValid()) - { - return source; - } - AzToolsFramework::AssetSystemRequestBus::Events* assetSystem = AzToolsFramework::AssetSystemRequestBus::FindFirstHandler(); if (assetSystem) { From afc531d4c3ad1e7a413df68a7a22d7717a7b6a2a Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:22:02 +0100 Subject: [PATCH 121/272] Fixes VS2022 error C5233: explicit lambda capture 'isSlash' is not used (#6745) Signed-off-by: Benjamin Jillich --- Code/Tools/AssetProcessor/native/FileWatcher/FileWatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/AssetProcessor/native/FileWatcher/FileWatcher.cpp b/Code/Tools/AssetProcessor/native/FileWatcher/FileWatcher.cpp index f802bdbada..993e7f2760 100644 --- a/Code/Tools/AssetProcessor/native/FileWatcher/FileWatcher.cpp +++ b/Code/Tools/AssetProcessor/native/FileWatcher/FileWatcher.cpp @@ -25,7 +25,7 @@ static bool IsSubfolder(const QString& folderA, const QString& folderB) using AZStd::begin; using AZStd::end; - constexpr auto isSlash = [](const QChar c) constexpr + auto isSlash = [](const QChar c) constexpr { return c == AZ::IO::WindowsPathSeparator || c == AZ::IO::PosixPathSeparator; }; From 7c88f20e1e6bf4b24ea6c0631cccc20867c024bb Mon Sep 17 00:00:00 2001 From: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> Date: Mon, 10 Jan 2022 11:49:22 +0000 Subject: [PATCH 122/272] Spinboxes now correct when rounding. (#6748) * Spinboxes now correct when rounding. Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> * Changes from PR Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> * Fixed tests after change to rounding in spinbox Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> --- .../Components/Widgets/SpinBox.cpp | 2 +- .../AzQtComponents/Tests/AzQtComponentTests.cpp | 16 ++++++++++++++++ .../AzQtComponents/Utilities/Conversions.cpp | 16 ++++++++++++---- .../AzQtComponents/Utilities/Conversions.h | 2 +- .../AzToolsFramework/Tests/SpinBoxTests.cpp | 8 ++++---- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SpinBox.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SpinBox.cpp index 8ace8d0f40..e9f484ee11 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SpinBox.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SpinBox.cpp @@ -1460,7 +1460,7 @@ QString DoubleSpinBox::stringValue(double value, bool truncated) const numDecimals = 0; } - return toString(value, numDecimals, locale(), isGroupSeparatorShown()); + return toString(value, numDecimals, locale(), isGroupSeparatorShown(), true); } void DoubleSpinBox::updateToolTip(double value) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Tests/AzQtComponentTests.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Tests/AzQtComponentTests.cpp index 3c911c8acc..d87b238250 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Tests/AzQtComponentTests.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Tests/AzQtComponentTests.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include // Environments subclass from AZ::Test::ITestEnvironment class AzQtComponentsTestEnvironment : public AZ::Test::ITestEnvironment @@ -34,3 +36,17 @@ protected: }; AZ_UNIT_TEST_HOOK(new AzQtComponentsTestEnvironment); + +TEST(AzQtComponents, ToStringReturnsTruncatedString) +{ + double testVal = 1.2399999; + QString result = AzQtComponents::toString(testVal, 3, QLocale(), false, false); + EXPECT_TRUE(result == "1.239"); +} + +TEST(AzQtComponents, ToStringReturnsRoundedString) +{ + double testVal = 1.2399999; + QString result = AzQtComponents::toString(testVal, 3, QLocale(), false, true); + EXPECT_TRUE(result == "1.24"); +} diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.cpp index bef41bb487..542bfaf7c8 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.cpp @@ -39,15 +39,23 @@ namespace AzQtComponents return AZ::Color(static_cast(rgb.redF()), static_cast(rgb.greenF()), static_cast(rgb.blueF()), static_cast(rgb.alphaF())); } - QString toString(double value, int numDecimals, const QLocale& locale, bool showGroupSeparator) + QString toString(double value, int numDecimals, const QLocale& locale, bool showGroupSeparator, bool round) { const QChar decimalPoint = locale.decimalPoint(); const QChar zeroDigit = locale.zeroDigit(); const int numToStringDecimals = AZStd::max(numDecimals, 20); + QString retValue; - // We want to truncate, not round. toString will round, so we add extra decimal places to the formatting - // so we can remove the last values - QString retValue = locale.toString(value, 'f', (numDecimals > 0) ? numToStringDecimals : 0); + // If we want to truncate, not round, we add extra decimal places to the formatting + // so we can remove the last values otherwise we allow rounding + if (round) + { + retValue = locale.toString(value, 'f', (numDecimals > 0) ? numDecimals : 0); + } + else + { + retValue = locale.toString(value, 'f', (numDecimals > 0) ? numToStringDecimals : 0); + } // Handle special cases when we have decimals in our value if (numDecimals > 0) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.h b/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.h index 84e874fc5a..29988545f7 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.h +++ b/Code/Framework/AzQtComponents/AzQtComponents/Utilities/Conversions.h @@ -22,7 +22,7 @@ namespace AzQtComponents AZ_QT_COMPONENTS_API AZ::Color fromQColor(const QColor& color); - AZ_QT_COMPONENTS_API QString toString(double value, int numDecimals, const QLocale& locale, bool showGroupSeparator = false); + AZ_QT_COMPONENTS_API QString toString(double value, int numDecimals, const QLocale& locale, bool showGroupSeparator = false, bool round = false); // Maintained for backwards compile compatibility inline QColor ToQColor(const AZ::Color& color) diff --git a/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp b/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp index 2d524cbcf4..f885240fde 100644 --- a/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/SpinBoxTests.cpp @@ -275,7 +275,7 @@ namespace UnitTest QString testString = "0" + QString(testLocale.decimalPoint()) + "9999999"; QString value = setupTruncationTest(testString); - testString = "0" + QString(testLocale.decimalPoint()) + "999"; + testString = "1" + QString(testLocale.decimalPoint()) + "0"; EXPECT_TRUE(value == testString); } @@ -295,19 +295,19 @@ namespace UnitTest QString testString = "0" + QString(testLocale.decimalPoint()) + "12395"; QString value = setupTruncationTest(testString); - testString = "0" + QString(testLocale.decimalPoint()) + "123"; + testString = "0" + QString(testLocale.decimalPoint()) + "124"; EXPECT_TRUE(value == testString); testString = "0" + QString(testLocale.decimalPoint()) + "94496"; value = setupTruncationTest(testString); - testString = "0" + QString(testLocale.decimalPoint()) + "944"; + testString = "0" + QString(testLocale.decimalPoint()) + "945"; EXPECT_TRUE(value == testString); testString = "0" + QString(testLocale.decimalPoint()) + "0009999"; value = setupTruncationTest(testString); - testString = "0" + QString(testLocale.decimalPoint()) + "0"; + testString = "0" + QString(testLocale.decimalPoint()) + "001"; EXPECT_TRUE(value == testString); } From 098005afbce28facfcaf23673d07b8ba343ab366 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:03:31 -0600 Subject: [PATCH 123/272] AZStd::basic_string improvements (#6438) * AZStd::basic_string improvements The AZStd::basic_string class has a better implementation of the Short String Optimization, which increases the amount of characters that can be stored in a `basic_string` from 15 characters to 22 characters(not-including null-terminating characters). For a `basic_string` on Windows the amount of characters that can be stored increases from 7 to 10. Using `basic_string` on Unix platforms SSO character amount from 3 to 4 characters. An additional benefit is that the size of the AZStd::basic_string class has been reduced from 40 bytes to 32 bytes when using the AZStd::allocator. When using a stateless allocator with no non static data members such as AZStd::stateless_allocator, the size of the AZStd::basic_string is 24 bytes. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Corrected comments and updated type alias to usings for AZStd::basic_string Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added Benchmarks for the basic_string and basic_fixed_string class The benchmarks currently measure the speed of the `assign` overloads. A benchmark has also been added to compare the speed swapping two `basic_string` instances by 3 memcpy vs 3 pointer swap operations Speed up string operation when in the iterator overload cases of the `assign`, `append`, `insert` and `replace` function. The code was always performing the logic to copy over a string that is overlapping, without actually checking if the string was overlapping in the first place. Added an `az_builtin_is_constant_evaluated` macro that allows use of the C++20 `std::is_constant_evaluated` feature to determine if an operation is being performed at compile time vs run time. That macro is being used to speed up the char_trait operations at run time, by using the faster standard library functions. For example char_traits::move now uses "memmove" at runtime, instead of a for loop. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Simplified string logic in AWSMetricsServiceApiTest. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/PlatformDef.h | 76 + .../AzCore/AzCore/std/allocator_stateless.cpp | 10 +- .../AzCore/AzCore/std/allocator_stateless.h | 6 +- .../AzCore/std/containers/compressed_pair.h | 17 +- .../AzCore/std/containers/compressed_pair.inl | 4 +- .../AzCore/AzCore/std/string/fixed_string.h | 20 - .../AzCore/AzCore/std/string/fixed_string.inl | 415 +++-- .../AzCore/AzCore/std/string/string.h | 1494 +++++++++-------- .../AzCore/AzCore/std/string/string_view.h | 152 +- .../VisualStudio/AzCore/Natvis/azcore.natvis | 51 +- Code/Framework/AzCore/Tests/AZStd/String.cpp | 912 ++++++---- .../AWSAttributionServiceApiTest.cpp | 9 +- .../Code/Tests/AWSMetricsServiceApiTest.cpp | 7 +- .../Code/Tests/AnimGraphEventTests.cpp | 2 +- .../Code/Tests/AnimGraphRefCountTests.cpp | 2 +- 15 files changed, 1860 insertions(+), 1317 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/PlatformDef.h b/Code/Framework/AzCore/AzCore/PlatformDef.h index 8d28d27959..7f00f7e90e 100644 --- a/Code/Framework/AzCore/AzCore/PlatformDef.h +++ b/Code/Framework/AzCore/AzCore/PlatformDef.h @@ -149,3 +149,79 @@ #if !defined(AZ_COMMAND_LINE_LEN) # define AZ_COMMAND_LINE_LEN 2048 #endif + +#include +#include +#include +#include +#include + +// First check if the feature if is_constant_evaluated is available via the feature test macro +// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros#C.2B.2B20 +#if __cpp_lib_is_constant_evaluated + #define az_builtin_is_constant_evaluated() std::is_constant_evaluated() +#endif + +// Next check if there is a __builtin_is_constant_evaluated that can be used +// This works on MSVC 19.28+ toolsets when using C++17, as well as +// clang 9.0.0+ when using C++17. +// Finally it works on gcc 9.0+ when using C++17 +#if !defined(az_builtin_is_constant_evaluated) + #if defined(__has_builtin) + #if __has_builtin(__builtin_is_constant_evaluated) + #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() + #define az_has_builtin_is_constant_evaluated() true + #endif + #elif AZ_COMPILER_MSVC >= 1928 + #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() + #define az_has_builtin_is_constant_evaluated() true + #elif AZ_COMPILER_GCC + #define az_builtin_is_constant_evaluated() __builtin_is_constant_evaluated() + #define az_has_builtin_is_constant_evaluated() true + #endif +#endif + +// In this case no support for the determining whether an operation is occuring +// at compile time is supported so assume that evaluation is always occuring at compile time +// in order to make sure the "safe" operation is being performed +#if !defined(az_builtin_is_constant_evaluated) + namespace AZ::Internal + { + constexpr bool builtin_is_constant_evaluated() + { + return true; + } + } + #define az_builtin_is_constant_evaluated() AZ::Internal::builtin_is_constant_evaluated() + #define az_has_builtin_is_constant_evaluated() false +#endif + +// define builtin functions used by char_traits class for efficient compile time and runtime +// operations +#if defined(__has_builtin) + #if __has_builtin(__builtin_memcpy) + #define az_has_builtin_memcpy true + #endif + #if __has_builtin(__builtin_wmemcpy) + #define az_has_builtin_wmemcpy true + #endif + #if __has_builtin(__builtin_memmove) + #define az_has_builtin_memmove true + #endif + #if __has_builtin(__builtin_wmemmove) + #define az_has_builtin_wmemmove true + #endif +#endif + +#if !defined(az_has_builtin_memcpy) + #define az_has_builtin_memcpy false +#endif +#if !defined(az_has_builtin_wmemcpy) + #define az_has_builtin_wmemcpy false +#endif +#if !defined(az_has_builtin_memmove) + #define az_has_builtin_memmove false +#endif +#if !defined(az_has_builtin_wmemmove) + #define az_has_builtin_wmemmove false +#endif diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp index 5806cc485c..baf650a560 100644 --- a/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp +++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp @@ -11,17 +11,17 @@ namespace AZStd { - stateless_allocator::stateless_allocator(const char* name) - : m_name(name) {} + stateless_allocator::stateless_allocator() = default; + stateless_allocator::stateless_allocator(const char*) + {} const char* stateless_allocator::get_name() const { - return m_name; + return "AZStd::stateless_allocator"; } - void stateless_allocator::set_name(const char* name) + void stateless_allocator::set_name(const char*) { - m_name = name; } auto stateless_allocator::allocate(size_type byteSize) -> pointer_type diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.h b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h index b73c680c32..6b78aca53d 100644 --- a/Code/Framework/AzCore/AzCore/std/allocator_stateless.h +++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h @@ -26,7 +26,8 @@ namespace AZStd using difference_type = ptrdiff_t; using allow_memory_leaks = AZStd::true_type; - stateless_allocator(const char* name = "AZStd::stateless_allocator"); + stateless_allocator(); + explicit stateless_allocator(const char*); // Stateless allocator does not store a name stateless_allocator(const stateless_allocator& rhs) = default; stateless_allocator& operator=(const stateless_allocator& rhs) = default; @@ -51,9 +52,6 @@ namespace AZStd bool is_lock_free(); bool is_stale_read_allowed(); bool is_delayed_recycling(); - - private: - const char* m_name; }; bool operator==(const stateless_allocator& left, const stateless_allocator& right); diff --git a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h index 066ec7be5e..c79ddf11ee 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h +++ b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include /* Microsoft C++ ABI puts 1 byte of padding between each empty base class when multiple inheritance is being used @@ -20,7 +21,7 @@ #if defined(AZ_COMPILER_MSVC) #define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION __declspec(empty_bases) #else -#define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION +#define AZSTD_COMPRESSED_PAIR_EMPTY_BASE_OPTIMIZATION #endif namespace AZStd @@ -97,16 +98,14 @@ namespace AZStd using second_base_value_type = typename second_base_type::value_type; public: - // First template argument is a placeholder argument of void as MSVC examines the types - // of a templated function to determine if they are the same template - // Due to the "template compressed_pair(skip_element_tag, T&&)" - // constructor below, the default constructor template types needs to be distinguished from it - template ::value - && AZStd::is_default_constructible::value>> + // First template argument is used to perform a substitution into AZStd::enable_if_t + // so that SFINAE can trigger + template + && AZStd::is_default_constructible_v, Unused>> constexpr compressed_pair(); - template , compressed_pair>::value, bool> = true> + template , compressed_pair>, bool> = true> constexpr explicit compressed_pair(T&& firstElement); template diff --git a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl index 9fb5eb87fb..8e585a1467 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl +++ b/Code/Framework/AzCore/AzCore/std/containers/compressed_pair.inl @@ -75,7 +75,7 @@ namespace AZStd } template - template , compressed_pair>::value, bool>> + template , compressed_pair>, bool>> inline constexpr compressed_pair::compressed_pair(T&& firstElement) : first_base_type{ AZStd::forward(firstElement) } , second_base_type{} @@ -117,7 +117,7 @@ namespace AZStd { return static_cast(*this).get(); } - + template inline constexpr auto compressed_pair::second() -> second_base_value_type& { diff --git a/Code/Framework/AzCore/AzCore/std/string/fixed_string.h b/Code/Framework/AzCore/AzCore/std/string/fixed_string.h index a8e0f96988..ea841bc4ca 100644 --- a/Code/Framework/AzCore/AzCore/std/string/fixed_string.h +++ b/Code/Framework/AzCore/AzCore/std/string/fixed_string.h @@ -343,26 +343,6 @@ namespace AZStd static decltype(auto) format(const wchar_t* format, ...); protected: - template - constexpr auto append_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v, basic_fixed_string&>; - - template - constexpr auto construct_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v>; - - template - constexpr auto assign_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v, basic_fixed_string&>; - - template - constexpr auto insert_iter(const_iterator insertPos, InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v, iterator>; - - template - constexpr auto replace_iter(const_iterator first, const_iterator last, InputIt first2, InputIt last2) - -> enable_if_t && !is_convertible_v, basic_fixed_string&>; - constexpr auto fits_in_capacity(size_type newSize) -> bool; inline static constexpr size_type Capacity = MaxElementCount; // current storage reserved for string not including null-terminator diff --git a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl index 8b973d3b2c..15d2acf7a1 100644 --- a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl +++ b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl @@ -62,14 +62,7 @@ namespace AZStd template inline constexpr basic_fixed_string::basic_fixed_string(InputIt first, InputIt last) { // construct from [first, last) - if (first == last) - { - Traits::assign(m_buffer[0], Element()); // terminate - } - else - { - construct_iter(first, last); - } + assign(first, last); } // #7 @@ -98,8 +91,7 @@ namespace AZStd template inline constexpr basic_fixed_string::basic_fixed_string(const T& convertibleToView) { - AZStd::basic_string_view view = convertibleToView; - assign(view.begin(), view.end()); + assign(convertibleToView); } // #11 @@ -313,15 +305,7 @@ namespace AZStd if (count > 0 && fits_in_capacity(num)) { pointer data = m_buffer; - // make room and append new stuff using assign - if (count == 1) - { - Traits::assign(*(data + m_size), ch); - } - else - { - Traits::assign(data + m_size, count, ch); - } + Traits::assign(data + m_size, count, ch); m_size = static_cast(num); Traits::assign(data[num], Element()); // terminate } @@ -332,13 +316,47 @@ namespace AZStd template inline constexpr auto basic_fixed_string::append(InputIt first, InputIt last) -> enable_if_t && !is_convertible_v, basic_fixed_string&> - { // append [first, last) - return append_iter(first, last); + { + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + return append(AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be appended one by one into the buffer + size_type newSize = m_size + AZStd::distance(first, last); + if (fits_in_capacity(newSize)) + { + for (size_t updateIndex = m_size; first != last; ++first, ++updateIndex) + { + Traits::assign(m_buffer[updateIndex], static_cast(*first)); + } + m_size = static_cast(newSize); + Traits::assign(m_buffer[newSize], Element()); // terminate + } + return *this; + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_fixed_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } + + return append(inputCopy.c_str(), inputCopy.size()); + } } template inline constexpr auto basic_fixed_string::append(AZStd::initializer_list ilist) -> basic_fixed_string& - { // append [first, last) - return append_iter(ilist.begin(), ilist.end()); + { + return append(ilist.begin(), ilist.size()); } template @@ -420,18 +438,10 @@ namespace AZStd inline constexpr auto basic_fixed_string::assign(size_type count, Element ch) -> basic_fixed_string& { // assign count * ch - AZSTD_CONTAINER_ASSERT(count != npos, "result is too long!"); if (fits_in_capacity(count)) { // make room and assign new stuff pointer data = m_buffer; - if (count == 1) - { - Traits::assign(*(data), ch); - } - else - { - Traits::assign(data, count, ch); - } + Traits::assign(data, count, ch); m_size = static_cast(count); Traits::assign(data[count], Element()); // terminate } @@ -443,12 +453,46 @@ namespace AZStd inline constexpr auto basic_fixed_string::assign(InputIt first, InputIt last) -> enable_if_t && !is_convertible_v, basic_fixed_string&> { - return assign_iter(first, last); + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + return assign(AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be assigned one by one into the buffer + size_type newSize = AZStd::distance(first, last); + if (fits_in_capacity(newSize)) + { + for (size_t updateIndex = 0; first != last; ++first, ++updateIndex) + { + Traits::assign(m_buffer[updateIndex], static_cast(*first)); + } + m_size = static_cast(newSize); + Traits::assign(m_buffer[newSize], Element()); // terminate + } + return *this; + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_fixed_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } + + return assign(inputCopy.c_str(), inputCopy.size()); + } } template inline constexpr auto basic_fixed_string::assign(AZStd::initializer_list ilist) -> basic_fixed_string& { - return assign_iter(ilist.begin(), ilist.end()); + return assign(ilist.begin(), ilist.size()); } template @@ -536,14 +580,7 @@ namespace AZStd pointer data = m_buffer; // make room and insert new stuff Traits::copy_backward(data + offset + count, data + offset, m_size - offset); // empty out hole - if (count == 1) - { - Traits::assign(*(data + offset), ch); - } - else - { - Traits::assign(data + offset, count, ch); - } + Traits::assign(data + offset, count, ch); m_size = static_cast(num); Traits::assign(data[num], Element()); // terminate } @@ -582,14 +619,51 @@ namespace AZStd inline constexpr auto basic_fixed_string::insert(const_iterator insertPos, InputIt first, InputIt last)-> enable_if_t && !is_convertible_v, iterator> { // insert [_First, _Last) at _Where - return insert_iter(insertPos, first, last); + size_type insertOffset = AZStd::distance(cbegin(), insertPos); + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + insert(insertOffset, AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be inserted one by one into the buffer + size_type count = AZStd::distance(first, last); + size_type newSize = m_size + count; + if (fits_in_capacity(newSize)) + { + Traits::copy_backward(m_buffer + insertOffset + count, m_buffer + insertOffset, m_size - insertOffset); // empty out hole + for (size_t updateIndex = insertOffset; first != last; ++first, ++updateIndex) + { + Traits::assign(m_buffer[updateIndex], static_cast(*first)); + } + m_size = static_cast(newSize); + Traits::assign(m_buffer[newSize], Element()); // terminate + } + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_fixed_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } + + insert(insertOffset, inputCopy.c_str(), inputCopy.size()); + } + return begin() + insertOffset; } template inline constexpr auto basic_fixed_string::insert(const_iterator insertPos, AZStd::initializer_list ilist) -> iterator { // insert [_First, _Last) at _Where - return insert_iter(insertPos, ilist.begin(), ilist.end()); + return insert(insertPos, ilist.begin(), ilist.end()); } template @@ -604,7 +678,7 @@ namespace AZStd { // move elements down pointer data = m_buffer; - Traits::copy(data + offset, data + offset + count, m_size - offset - count); + Traits::move(data + offset, data + offset + count, m_size - offset - count); m_size = static_cast(m_size - count); Traits::assign(data[m_size], Element()); // terminate } @@ -643,7 +717,7 @@ namespace AZStd const basic_fixed_string& rhs) -> basic_fixed_string& { // replace [offset, offset + count) with rhs - return replace(offset, count, rhs, size_type(0), npos); + return replace(offset, count, rhs.c_str(), rhs.size()); } template @@ -651,56 +725,7 @@ namespace AZStd const basic_fixed_string& rhs, size_type rhsOffset, size_type rhsCount) -> basic_fixed_string& { // replace [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount) - AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offsets"); - if (m_size - offset < count) - { - count = m_size - offset; // trim count to size - } - size_type num = rhs.m_size - rhsOffset; - if (num < rhsCount) - { - rhsCount = num; // trim rhsCount to size - } - AZSTD_CONTAINER_ASSERT(npos - rhsCount > m_size - count, "Result is too long"); - - size_type nm = m_size - count - offset; // length of preserved tail - size_type newSize = m_size + rhsCount - count; - if (fits_in_capacity(newSize)) - { - pointer data = m_buffer; - const_pointer rhsData = rhs.m_buffer; - - if (this != &rhs) - { // no overlap, just move down and copy in new stuff - Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // empty hole - Traits::copy(data + offset, rhsData + rhsOffset, rhsCount); // fill hole - } - else if (rhsCount <= count) - { // hole doesn't get larger, just copy in substring - Traits::copy(data + offset, data + rhsOffset, rhsCount); // fill hole - Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down - } - else if (rhsOffset <= offset) - { // hole gets larger, substring begins before hole - Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down - Traits::copy(data + offset, data + rhsOffset, rhsCount); // fill hole - } - else if (offset + count <= rhsOffset) - { // hole gets larger, substring begins after hole - Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down - Traits::copy(data + offset, data + (rhsOffset + rhsCount - count), rhsCount); // fill hole - } - else - { // hole gets larger, substring begins in hole - Traits::copy(data + offset, data + rhsOffset, count); // fill old hole - Traits::copy_backward(data + offset + rhsCount, data + offset + count, nm); // move tail down - Traits::copy(data + offset + count, data + rhsOffset + rhsCount, rhsCount - count); // fill rest of new hole - } - - m_size = static_cast(newSize); - Traits::assign(data[newSize], Element()); // terminate - } - return *this; + return replace(offset, count, rhs.c_str() + rhsOffset, AZStd::min(rhsCount, rhs.size() - rhsOffset)); } template template @@ -720,35 +745,83 @@ namespace AZStd pointer data = m_buffer; // replace [offset, offset + count) with [ptr, ptr + ptrCount) AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - if (m_size - offset < count) - { - count = m_size - offset; // trim _N0 to size - } - AZSTD_CONTAINER_ASSERT(npos - ptrCount > m_size - count, "Result too long"); + // Make sure count is within is no larger than the distance from the offset + // to the end of this string + count = AZStd::min(count, m_size - offset); - size_type nm = m_size - count - offset; - if (ptrCount < count) + size_type newSize = m_size + ptrCount - count; + if (fits_in_capacity(newSize)) { - Traits::copy(data + offset + ptrCount, data + offset + count, nm); // smaller hole, move tail up - } - size_type num = m_size + ptrCount - count; - if ((0 != ptrCount || 0 != count) && fits_in_capacity(num)) - { - data = m_buffer; - // make room and rearrange - if (count < ptrCount) + // The code assumes that compile time evaluation will not need to deal with overlapping input + size_type charsAfterCountToMove = m_size - count - offset; + if (az_builtin_is_constant_evaluated() || !((ptr >= data + offset && ptr < data + offset + count) + || (ptr + ptrCount > data + offset && ptr + ptrCount <= data + offset + count))) { - Traits::copy_backward(data + offset + ptrCount, data + offset + count, nm); // move tail down + // Ex1. this = "ABCDEFG", offset = 1, count = 4 + // Input string is "CDE" + // First the text post offset + count is moved to right after the input string will be copied + // "ABCDFG" + // ^^^ + // Next the input string is copied into the buffer + // "ACDEFG" + // + // Ex2. this = "ABCDEFG", offset = 1, count = 2 + // Input string is "CDE" + // Performing the same two steps above, the string transform as follows + // "ABCDEFG" -> "ABCDDEFG" -> "ACDEDEFG" + // ^^^ + if (count != ptrCount) + { + Traits::move(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); + } + if (ptrCount > 0) + { + // Copy bytes up to the minimum of this string count and input string count + Traits::copy(data + offset, ptr, ptrCount); + } } - - if (ptrCount > 0) + else { - Traits::copy(data + offset, ptr, ptrCount); // fill hole + // Overlap checks for fixed_string only needs to check between this string + // [offset, offset + count) due to fixed_string never moving memory + // + // Ex. this = "ABCDEFG", offset = 1, count=4 + // substring is "CDE" + // The text from offset 1 for 4 chars "BCDE": should be replaced with "CDE" + // making a whole for the bytes results in output = "ABCDFG" + // Afterwards output = "ACDEFG" + // The input string overlaps with this string in this case + // So the string is copied piecewise + if (ptrCount <= count) + { // hole doesn't get larger, just copy in substring + Traits::move(data + offset, ptr, ptrCount); // fill hole + Traits::copy(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down + } + else + { + if (ptr <= data + offset) + { // hole gets larger, substring begins before hole + Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(data + offset, ptr, ptrCount); // fill hole + } + else if (data + offset + count <= ptr) + { // hole gets larger, substring begins after hole + Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(data + offset, ptr + (ptrCount - count), ptrCount); // fill hole + } + else + { // hole gets larger, substring begins in hole + Traits::copy(data + offset, ptr, count); // fill old hole + Traits::copy_backward(data + offset + ptrCount, data + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(data + offset + count, ptr + ptrCount, ptrCount - count); // fill rest of new hole + } + } } - - m_size = static_cast(num); - Traits::assign(data[num], Element()); // terminate } + + m_size = static_cast(newSize); + Traits::assign(data[newSize], Element()); // terminate + return *this; } @@ -793,14 +866,7 @@ namespace AZStd { Traits::copy_backward(data + offset + num, data + offset + count, nm); // move tail down } - if (count == 1) - { - Traits::assign(*(data + offset), ch); - } - else - { - Traits::assign(data + offset, num, ch); - } + Traits::assign(data + offset, num, ch); m_size = static_cast(numToGrow); Traits::assign(data[numToGrow], Element()); // terminate } @@ -851,15 +917,54 @@ namespace AZStd template template inline constexpr auto basic_fixed_string::replace(const_iterator first, const_iterator last, - InputIt first2, InputIt last2) -> enable_if_t && !is_convertible_v, basic_fixed_string&> - { // replace [first, last) with [first2,last2) - return replace_iter(first, last, first2, last2); + InputIt replaceFirst, InputIt replaceLast) -> enable_if_t && !is_convertible_v, basic_fixed_string&> + { // replace [first, last) with [replaceFirst,replaceLast) + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + return replace(first, last, AZStd::to_address(replaceFirst), AZStd::distance(replaceFirst, replaceLast)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be appended one by one into the buffer + + size_type insertOffset = AZStd::distance(cbegin(), first); + size_type postInsertOffset = AZStd::distance(cbegin(), last); + size_type count = AZStd::distance(replaceFirst, replaceLast); + size_type newSize = m_size + count - AZStd::distance(first, last); + if (fits_in_capacity(newSize)) + { + Traits::move(first + count, last, m_size - postInsertOffset); // empty out hole + for (size_t updateIndex = insertOffset; replaceFirst != replaceLast; ++replaceFirst, ++updateIndex) + { + Traits::assign(m_buffer[updateIndex], static_cast(*replaceFirst)); + } + m_size = static_cast(newSize); + Traits::assign(m_buffer[newSize], Element()); // terminate + } + return *this; + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_fixed_string inputCopy; + for (; replaceFirst != replaceLast; ++replaceFirst) + { + inputCopy.push_back(static_cast(*replaceFirst)); + } + + return replace(first, last, inputCopy.c_str(), inputCopy.size()); + } } template inline constexpr auto basic_fixed_string::replace(const_iterator first, const_iterator last, AZStd::initializer_list ilist) -> basic_fixed_string& - { // replace [first, last) with [first2,last2) - return replace_iter(first, last, ilist.begin(), ilist.end()); + { + return replace(first, last, ilist.begin(), ilist.end()); } template @@ -1411,54 +1516,6 @@ namespace AZStd return result; } - template - template - inline constexpr auto basic_fixed_string::construct_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v> - { - // initialize from [first, last), input iterators - for (; first != last; ++first) - { - append((size_type)1, (Element)* first); - } - } - - template - template - inline constexpr auto basic_fixed_string::append_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v, basic_fixed_string&> - { // append [first, last), input iterators - return replace(end(), end(), first, last); - } - - template - template - inline constexpr auto basic_fixed_string::assign_iter(InputIt first, InputIt last) - -> enable_if_t && !is_convertible_v, basic_fixed_string&> - { - return replace(begin(), end(), first, last); - } - - template - template - inline constexpr auto basic_fixed_string::insert_iter(const_iterator insertPos, InputIt first, - InputIt last) -> enable_if_t && !is_convertible_v, iterator> - { // insert [first, last) at insertPos, input iterators - difference_type offset = insertPos - cbegin(); - replace(insertPos, insertPos, first, last); - return iterator(m_buffer + offset); - } - - template - template - inline constexpr auto basic_fixed_string::replace_iter(const_iterator first, const_iterator last, - InputIt first2, InputIt last2) -> enable_if_t && !is_convertible_v, basic_fixed_string&> - { // replace [first, last) with [first2, last2), input iterators - basic_fixed_string rhs(first2, last2); - replace(first, last, rhs); - return *this; - } - template inline constexpr auto basic_fixed_string::fits_in_capacity(size_type newSize)-> bool { diff --git a/Code/Framework/AzCore/AzCore/std/string/string.h b/Code/Framework/AzCore/AzCore/std/string/string.h index e107c4657d..7dd6dd7065 100644 --- a/Code/Framework/AzCore/AzCore/std/string/string.h +++ b/Code/Framework/AzCore/AzCore/std/string/string.h @@ -5,24 +5,43 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#ifndef AZSTD_STRING_H -#define AZSTD_STRING_H +#pragma once #include #include #include #include +#include #include #include #include #include #include -#include #include #include +namespace AZStd::StringInternal +{ + template + struct Padding + { + AZ::u8 m_padding[ElementSize - 1]; + }; + + template + struct Padding + {}; +} + +#if defined(HAVE_BENCHMARK) +namespace Benchmark +{ + class StringBenchmarkFixture; +} +#endif + namespace AZStd { /** @@ -35,130 +54,95 @@ namespace AZStd : public Debug::checked_container_base #endif { - typedef basic_string this_type; + using this_type = basic_string; public: - typedef Element* pointer; - typedef const Element* const_pointer; + using pointer = Element*; + using const_pointer = const Element*; - typedef Element& reference; - typedef const Element& const_reference; - typedef typename Allocator::difference_type difference_type; - typedef typename Allocator::size_type size_type; + using reference = Element&; + using const_reference = const Element&; + using difference_type = typename Allocator::difference_type; + using size_type = typename Allocator::size_type; - typedef pointer iterator_impl; - typedef const_pointer const_iterator_impl; + using iterator_impl = pointer; + using const_iterator_impl = const_pointer; #ifdef AZSTD_HAS_CHECKED_ITERATORS - typedef Debug::checked_randomaccess_iterator iterator; - typedef Debug::checked_randomaccess_iterator const_iterator; + using iterator = Debug::checked_randomaccess_iterator; + using const_iterator = Debug::checked_randomaccess_iterator; #else - typedef iterator_impl iterator; - typedef const_iterator_impl const_iterator; + using iterator = iterator_impl; + using const_iterator = const_iterator_impl; #endif - typedef AZStd::reverse_iterator reverse_iterator; - typedef AZStd::reverse_iterator const_reverse_iterator; - typedef Element value_type; - typedef Traits traits_type; - typedef Allocator allocator_type; + using reverse_iterator = AZStd::reverse_iterator; + using const_reverse_iterator = AZStd::reverse_iterator; + using value_type = Element; + using traits_type = Traits; + using allocator_type = Allocator; // AZSTD extension. /** * \brief Allocation node type. Common for all AZStd containers. * In vectors case we allocate always "sizeof(node_type)*capacity" block. */ - typedef value_type node_type; + using node_type = value_type; - static const size_type npos = size_type(-1); + inline static constexpr size_type npos = size_type(-1); inline basic_string(const Allocator& alloc = Allocator()) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + : m_storage{ skip_element_tag{}, alloc } { - Traits::assign(m_buffer[0], Element()); + Traits::assign(m_storage.first().GetData()[0], Element()); } inline basic_string(const_pointer ptr, size_type count, const Allocator& alloc = Allocator()) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + : m_storage{ skip_element_tag{}, alloc } { // construct from [ptr, ptr + count) assign(ptr, count); } inline basic_string(const_pointer ptr, const Allocator& alloc = Allocator()) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + : m_storage{ skip_element_tag{}, alloc } { // construct from [ptr, ) assign(ptr); } inline basic_string(size_type count, Element ch, const Allocator& alloc = Allocator()) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + : m_storage{ skip_element_tag{}, alloc } { // construct from count * ch assign(count, ch); } - template - inline basic_string(InputIterator first, InputIterator last, const Allocator& alloc = Allocator()) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + template && !is_convertible_v>> + inline basic_string(InputIt first, InputIt last, const Allocator& alloc = Allocator()) + : m_storage{ skip_element_tag{}, alloc } { // construct from [first, last) - if (first == last) - { - Traits::assign(m_buffer[0], Element()); // terminate - } - else - { - construct_iter(first, last, is_integral()); - } + assign(first, last); } inline basic_string(const_pointer first, const_pointer last) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) { // construct from [first, last), const pointers - assign(&*first, last - first); + assign(first, last - first); } - //inline basic_string(const_iterator _First, const_iterator _Last) - // : m_size(0) - // , m_capacity(SSO_BUF_SIZE-1) - //{ // construct from [_First, _Last), const_iterators - // if (first != last) - // assign(&*first, last - first); - //} - inline basic_string(const this_type& rhs) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(rhs.m_allocator) + : m_storage{ skip_element_tag{}, rhs.m_storage.second() } { assign(rhs, 0, npos); } inline basic_string(this_type&& rhs) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(AZStd::move(rhs.m_allocator)) + : m_storage{ skip_element_tag{}, AZStd::move(rhs.m_storage.second()) } { assign(AZStd::forward(rhs)); } inline basic_string(const this_type& rhs, size_type rhsOffset, size_type count = npos) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) { // construct from rhs [rhsOffset, rhsOffset + count) assign(rhs, rhsOffset, count); } inline basic_string(const this_type& rhs, size_type rhsOffset, size_type count, const Allocator& alloc) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) - , m_allocator(alloc) + : m_storage{ skip_element_tag{}, alloc } { // construct from rhs [rhsOffset, rhsOffset + count) with allocator assign(rhs, rhsOffset, count); } @@ -174,7 +158,7 @@ namespace AZStd inline ~basic_string() { // destroy the string - deallocate_memory(m_data, 0, typename allocator_type::allow_memory_leaks()); + deallocate_memory(m_storage.first().GetData(), 0, typename allocator_type::allow_memory_leaks()); } operator AZStd::basic_string_view() const @@ -182,12 +166,12 @@ namespace AZStd return AZStd::basic_string_view(data(), size()); } - inline iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); } - inline const_iterator begin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); } - inline const_iterator cbegin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer)); } - inline iterator end() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); } - inline const_iterator end() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); } - inline const_iterator cend() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer) + m_size)); } + inline iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_storage.first().GetData())); } + inline const_iterator begin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, m_storage.first().GetData())); } + inline const_iterator cbegin() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, m_storage.first().GetData())); } + inline iterator end() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); } + inline const_iterator end() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); } + inline const_iterator cend() const { return const_iterator(AZSTD_CHECKED_ITERATOR(const_iterator_impl, (m_storage.first().GetData()) + m_storage.first().GetSize())); } inline reverse_iterator rbegin() { return reverse_iterator(end()); } inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } inline const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } @@ -196,7 +180,7 @@ namespace AZStd inline const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } inline this_type& operator=(const this_type& rhs) { return assign(rhs); } - inline this_type& operator=(this_type&& rhs) { return assign(AZStd::forward(rhs)); } + inline this_type& operator=(this_type&& rhs) { return assign(AZStd::move(rhs)); } inline this_type& operator=(AZStd::basic_string_view view) { return assign(view); } inline this_type& operator=(const_pointer ptr) { return assign(ptr); } inline this_type& operator=(Element ch) { return assign(1, ch); } @@ -208,21 +192,18 @@ namespace AZStd this_type& append(const this_type& rhs, size_type rhsOffset, size_type count) { // append rhs [rhsOffset, rhsOffset + count) AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset!"); - size_type num = rhs.m_size - rhsOffset; - if (num < count) + count = AZStd::min(count, rhs.size() - rhsOffset); + + size_type oldSize = size(); + size_type newSize = oldSize + count; + if (count > 0 && grow(newSize)) { - count = num; // trim count to size - } - AZSTD_CONTAINER_ASSERT(npos - m_size > count && m_size + count >= m_size, "result is too long!"); - num = m_size + count; - if (count > 0 && grow(num)) - { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; + pointer data = m_storage.first().GetData(); + const_pointer rhsData = rhs.data(); // make room and append new stuff - Traits::copy(data + m_size /*, m_capacity - m_size*/, rhsData + rhsOffset, count); - m_size = num; - Traits::assign(data[num], Element()); // terminate + Traits::copy(data + oldSize, rhsData + rhsOffset, count); + m_storage.first().SetSize(newSize); + Traits::assign(data[newSize], Element()); // terminate } return *this; } @@ -230,20 +211,21 @@ namespace AZStd this_type& append(const_pointer ptr, size_type count) { // append [ptr, ptr + count) - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (ptr != 0 && ptr >= data && (data + m_size) > ptr) + pointer data = m_storage.first().GetData(); + if (ptr != nullptr && ptr >= data && (data + size()) > ptr) { return append(*this, ptr - data, count); // substring } - AZSTD_CONTAINER_ASSERT(npos - m_size > count && m_size + count >= m_size, "result is too long!"); - size_type num = m_size + count; - if (count > 0 && grow(num)) + AZSTD_CONTAINER_ASSERT(npos - size() > count && size() + count >= size(), "result is too long!"); + size_type oldSize = size(); + size_type newSize = oldSize + count; + if (count > 0 && grow(newSize)) { // make room and append new stuff - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - Traits::copy(data + m_size /*, m_capacity - m_size*/, ptr, count); - m_size = num; - Traits::assign(data[num], Element()); // terminate + data = m_storage.first().GetData(); + Traits::copy(data + oldSize , ptr, count); + m_storage.first().SetSize(newSize); + Traits::assign(data[newSize], Element()); // terminate } return *this; } @@ -252,30 +234,60 @@ namespace AZStd this_type& append(size_type count, Element ch) { // append count * ch - AZSTD_CONTAINER_ASSERT(npos - m_size > count, "result is too long"); - size_type num = m_size + count; + AZSTD_CONTAINER_ASSERT(npos - size() > count, "result is too long"); + size_type num = size() + count; if (count > 0 && grow(num)) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); // make room and append new stuff using assign - if (count == 1) - { - Traits::assign(*(data + m_size), ch); - } - else - { - Traits::assign(data + m_size, count, ch); - } - m_size = num; + Traits::assign(data + size(), count, ch); + m_storage.first().SetSize(num); Traits::assign(data[num], Element()); // terminate } return *this; } - template - inline this_type& append(InputIterator first, InputIterator last) + template + inline auto append(InputIt first, InputIt last) + -> enable_if_t && !is_convertible_v, this_type&> { // append [first, last) - return append_iter(first, last, AZStd::is_integral()); + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + return append(AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be appended one by one into the buffer + size_type oldSize = size(); + size_type newSize = oldSize + AZStd::distance(first, last); + if (grow(newSize)) + { + pointer buffer = data(); + for (size_t updateIndex = oldSize; first != last; ++first, ++updateIndex) + { + Traits::assign(buffer[updateIndex], static_cast(*first)); + } + m_storage.first().SetSize(newSize); + Traits::assign(buffer[newSize], Element()); // terminate + } + return *this; + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } + + return append(inputCopy.c_str(), inputCopy.size()); + } } inline this_type& append(const_pointer first, const_pointer last) @@ -283,11 +295,6 @@ namespace AZStd return replace(end(), end(), first, last); } - //inline this_type& append(const_iterator first, const_iterator last) - //{ // append [first, last), const_iterators - // return replace(end(), end(), first, last); - //} - inline this_type& assign(const this_type& rhs) { return assign(rhs, 0, npos); @@ -302,27 +309,34 @@ namespace AZStd { if (this != &rhs) { - if (SSO_BUF_SIZE <= m_capacity) + deallocate_memory(m_storage.first().GetData(), 0, typename allocator_type::allow_memory_leaks()); + + m_storage.first().SetCapacity(rhs.capacity()); + + pointer data = m_storage.first().GetData(); + pointer rhsData = rhs.data(); + // Memmove the right hand side string data if it is using the short string optimization + // Otherwise set the pointer to the right hand side + if (rhs.m_storage.first().ShortStringOptimizationActive()) { - deallocate_memory(m_data, 0, typename allocator_type::allow_memory_leaks()); + Traits::move(data, rhsData, rhs.size() + 1); // string + null-terminator } + else + { + m_storage.first().SetData(rhsData); + } + m_storage.first().SetSize(rhs.size()); + m_storage.second() = rhs.m_storage.second(); - Traits::move(m_buffer, rhs.m_buffer, sizeof(m_buffer)); - m_size = rhs.m_size; - m_capacity = rhs.m_capacity; - m_allocator = rhs.m_allocator; - - rhs.m_data = nullptr; - rhs.m_size = 0; - rhs.m_capacity = SSO_BUF_SIZE - 1; + rhs.leak_and_reset(); } return *this; } this_type& assign(const this_type& rhs, size_type rhsOffset, size_type count) { // assign rhs [rhsOffset, rhsOffset + count) - AZSTD_CONTAINER_ASSERT(rhs.m_size >= rhsOffset, "Invalid offset"); - size_type num = rhs.m_size - rhsOffset; + AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset"); + size_type num = rhs.size() - rhsOffset; if (count < num) { num = count; // trim num to size @@ -334,10 +348,10 @@ namespace AZStd } else if (grow(num)) { // make room and assign new stuff - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - Traits::copy(data /*, m_capacity*/, rhsData + rhsOffset, num); - m_size = num; + pointer data = m_storage.first().GetData(); + const_pointer rhsData = rhs.data(); + Traits::copy(data, rhsData + rhsOffset, num); + m_storage.first().SetSize(num); Traits::assign(data[num], Element()); // terminate } return *this; @@ -345,20 +359,20 @@ namespace AZStd this_type& assign(const_pointer ptr, size_type count) { // assign [ptr, ptr + count) - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (ptr != 0 && ptr >= data && (data + m_size) > ptr) + pointer data = m_storage.first().GetData(); + if (ptr != nullptr && ptr >= data && (data + size()) > ptr) { return assign(*this, ptr - data, count); // substring } if (grow(count)) { // make room and assign new stuff - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + data = m_storage.first().GetData(); if (count > 0) { Traits::copy(data, ptr, count); } - m_size = count; + m_storage.first().SetSize(count); Traits::assign(data[count], Element()); // terminate } return *this; @@ -367,109 +381,132 @@ namespace AZStd this_type& assign(size_type count, Element ch) { // assign count * ch - AZSTD_CONTAINER_ASSERT(count != npos, "result is too long!"); if (grow(count)) { // make room and assign new stuff - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (count == 1) - { - Traits::assign(*(data), ch); - } - else - { - Traits::assign(data, count, ch); - } - m_size = count; + pointer data = m_storage.first().GetData(); + Traits::assign(data, count, ch); + m_storage.first().SetSize(count); Traits::assign(data[count], Element()); // terminate } return *this; } - template - inline this_type& assign(InputIterator first, InputIterator last) { return assign_iter(first, last, AZStd::is_integral()); } - inline this_type& assign(const_pointer first, const_pointer last) { return replace(begin(), end(), first, last); } - inline this_type& insert(size_type offset, const this_type& rhs) { return insert(offset, rhs, 0, npos); } + template + auto assign(InputIt first, InputIt last) + -> enable_if_t && !is_convertible_v, this_type&> + { + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + return assign(AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // forward iterator pointer type doesn't match the const_pointer type + // So the elements need to be assigned one by one into the buffer + size_type newSize = AZStd::distance(first, last); + if (grow(newSize)) + { + pointer buffer = data(); + for (size_t updateIndex = 0; first != last; ++first, ++updateIndex) + { + Traits::assign(buffer[updateIndex], static_cast(*first)); + } + m_storage.first().SetSize(newSize); + Traits::assign(buffer[newSize], Element()); // terminate + } + return *this; + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } + + return assign(inputCopy.c_str(), inputCopy.size()); + } + } + inline this_type& insert(size_type offset, const this_type& rhs) { return insert(offset, rhs, 0, npos); } this_type& insert(size_type offset, const this_type& rhs, size_type rhsOffset, size_type count) { // insert rhs [rhsOffset, rhsOffset + count) at offset - AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offset(s)"); - size_type num = rhs.m_size - rhsOffset; + AZSTD_CONTAINER_ASSERT(size() >= offset && rhs.size() >= rhsOffset, "Invalid offset(s)"); + size_type num = rhs.size() - rhsOffset; if (num < count) { count = num; // trim _Count to size } - AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long"); - num = m_size + count; + AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long"); + num = size() + count; if (count > 0 && grow(num)) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); // make room and insert new stuff - Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole + Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole if (this == &rhs) { - Traits::move(data + offset /*, m_capacity - offset*/, data + (offset < rhsOffset ? rhsOffset + count : rhsOffset), count); // substring + Traits::move(data + offset, data + (offset < rhsOffset ? rhsOffset + count : rhsOffset), count); // substring } else { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - Traits::copy(data + offset /*, m_capacity - offset*/, rhsData + rhsOffset, count); // fill hole + const_pointer rhsData = rhs.data(); + Traits::copy(data + offset, rhsData + rhsOffset, count); // fill hole } - m_size = num; + m_storage.first().SetSize(num); Traits::assign(data[num], Element()); // terminate } return (*this); } - this_type& insert(size_type offset, const_pointer ptr, size_type count) + this_type& insert(size_type offset, const_pointer ptr, size_type count) { // insert [ptr, ptr + count) at offset - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (ptr != 0 && ptr >= data && (data + m_size) > ptr) + pointer data = m_storage.first().GetData(); + if (ptr != nullptr && ptr >= data && (data + size()) > ptr) { - return insert(offset, *this, ptr - data, count); // substring + return insert(offset, *this, ptr - data, count); // substring } - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long"); - size_type num = m_size + count; + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long"); + size_type num = size() + count; if (count > 0 && grow(num)) { // make room and insert new stuff - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole - Traits::copy(data + offset /*, m_capacity - offset*/, ptr, count); // fill hole - m_size = num; + data = m_storage.first().GetData(); + Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole + Traits::copy(data + offset, ptr, count); // fill hole + m_storage.first().SetSize(num); Traits::assign(data[num], Element()); // terminate } return *this; } - inline this_type& insert(size_type offset, const_pointer ptr) { return insert(offset, ptr, Traits::length(ptr)); } + inline this_type& insert(size_type offset, const_pointer ptr) { return insert(offset, ptr, Traits::length(ptr)); } this_type& insert(size_type offset, size_type count, Element ch) { // insert count * ch at offset - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - AZSTD_CONTAINER_ASSERT(npos - m_size > count, "Result is too long"); - size_type num = m_size + count; + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + AZSTD_CONTAINER_ASSERT(npos - size() > count, "Result is too long"); + size_type num = size() + count; if (count > 0 && grow(num)) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); // make room and insert new stuff - Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + offset, m_size - offset); // empty out hole - if (count == 1) - { - Traits::assign(*(data + offset), ch); - } - else - { - Traits::assign(data + offset, count, ch); - } - m_size = num; + Traits::move(data + offset + count, data + offset, size() - offset); // empty out hole + Traits::assign(data + offset, count, ch); + m_storage.first().SetSize(num); Traits::assign(data[num], Element()); // terminate } return *this; } - inline iterator insert(const_iterator insertPos) { return insert(insertPos, Element()); } + inline iterator insert(const_iterator insertPos) { return insert(insertPos, Element()); } iterator insert(const_iterator insertPos, Element ch) { @@ -479,54 +516,89 @@ namespace AZStd const_pointer insertPosPtr = insertPos; #endif - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + const_pointer data = m_storage.first().GetData(); size_type offset = insertPosPtr - data; insert(offset, 1, ch); return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + offset)); } - void insert(const_iterator insertPos, size_type count, Element ch) + iterator insert(const_iterator insertPos, size_type count, Element ch) { // insert count * elem at insertPos #ifdef AZSTD_HAS_CHECKED_ITERATORS const_pointer insertPosPtr = insertPos.get_iterator(); #else const_pointer insertPosPtr = insertPos; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); size_type offset = insertPosPtr - data; insert(offset, count, ch); + return begin() + offset; } - template - inline void insert(const_iterator insertPos, InputIterator first, InputIterator last) + template + auto insert(const_iterator insertPos, InputIt first, InputIt last) + -> enable_if_t && !is_convertible_v, iterator> { // insert [_First, _Last) at _Where - insert_iter(insertPos, first, last, is_integral()); - } + size_type insertOffset = AZStd::distance(cbegin(), insertPos); + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) + { + insert(insertOffset, AZStd::to_address(first), AZStd::distance(first, last)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be inserted one by one into the buffer + size_type count = AZStd::distance(first, last); + size_type oldSize = size(); + size_type newSize = oldSize + count; + if (grow(newSize)) + { + pointer buffer = m_storage.first().GetData(); + Traits::copy_backward(buffer + insertOffset + count, buffer + insertOffset, oldSize - insertOffset); // empty out hole + for (size_t updateIndex = insertOffset; first != last; ++first, ++updateIndex) + { + Traits::assign(buffer[updateIndex], static_cast(*first)); + } + m_storage.first().SetSize(newSize); + Traits::assign(buffer[newSize], Element()); // terminate + } + } + else + { + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_string inputCopy; + for (; first != last; ++first) + { + inputCopy.push_back(static_cast(*first)); + } - inline void insert(const_iterator insertPos, const_pointer first, const_pointer last) - { // insert [first, last) at insertPos, const pointers - replace(insertPos, insertPos, first, last); + insert(insertOffset, inputCopy.c_str(), inputCopy.size()); + } + return begin() + insertOffset; } - this_type& erase(size_type offset = 0, size_type count = npos) { // erase elements [offset, offset + count) - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - if (m_size - offset < count) + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + if (size() - offset < count) { - count = m_size - offset; // trim count + count = size() - offset; // trim count } if (count > 0) { // move elements down - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); #ifdef AZSTD_HAS_CHECKED_ITERATORS orphan_range(data + offset, data + offset + count); #endif - Traits::move(data + offset /*, m_capacity - offset*/, data + offset + count, m_size - offset - count); - m_size = m_size - count; - Traits::assign(data[m_size], Element()); // terminate - } + Traits::move(data + offset, data + offset + count, size() - offset - count); + m_storage.first().SetSize(size() - count); + Traits::assign(data[size()], Element()); // terminate + } return *this; } @@ -538,10 +610,10 @@ namespace AZStd const_pointer erasePtr = erasePos; #endif // erase element at insertPos - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + const_pointer data = m_storage.first().GetData(); size_type count = erasePtr - data; erase(count, 1); - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + data = m_storage.first().GetData(); return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + count)); } @@ -554,159 +626,152 @@ namespace AZStd const_pointer firstPtr = first; const_pointer lastPtr = last; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); size_type count = firstPtr - data; erase(count, lastPtr - firstPtr); - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + data = m_storage.first().GetData(); return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, data + count)); } - inline void clear() { erase(begin(), end()); } - inline this_type& replace(size_type offset, size_type count, const this_type& rhs) + inline void clear() { erase(begin(), end()); } + this_type& replace(size_type offset, size_type count, const this_type& rhs) { - // replace [offset, offset + count) with rhs - return replace(offset, count, rhs, 0, npos); + return replace(offset, count, rhs.c_str(), rhs.size()); } this_type& replace(size_type offset, size_type count, const this_type& rhs, size_type rhsOffset, size_type rhsCount) { - // replace [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount) - AZSTD_CONTAINER_ASSERT(m_size >= offset && rhs.m_size >= rhsOffset, "Invalid offsets"); - if (m_size - offset < count) - { - count = m_size - offset; // trim count to size - } - size_type num = rhs.m_size - rhsOffset; - if (num < rhsCount) - { - rhsCount = num; // trim rhsCount to size - } - AZSTD_CONTAINER_ASSERT(npos - rhsCount > m_size - count, "Result is too long"); - - size_type nm = m_size - count - offset; // length of preserved tail - size_type newSize = m_size + rhsCount - count; - if (m_size < newSize) - { - grow(newSize); - } - - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - -#ifdef AZSTD_HAS_CHECKED_ITERATORS - orphan_range(data + offset, data + offset + count); -#endif - if (this != &rhs) - { // no overlap, just move down and copy in new stuff - Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // empty hole - Traits::copy(data + offset /*, m_capacity - offset*/, rhsData + rhsOffset, rhsCount); // fill hole - } - else if (rhsCount <= count) - { // hole doesn't get larger, just copy in substring - Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, rhsCount); // fill hole - Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down - } - else if (rhsOffset <= offset) - { // hole gets larger, substring begins before hole - Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down - Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, rhsCount); // fill hole - } - else if (offset + count <= rhsOffset) - { // hole gets larger, substring begins after hole - Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down - Traits::move(data + offset /*, m_capacity - offset*/, data + (rhsOffset + rhsCount - count), rhsCount); // fill hole - } - else - { // hole gets larger, substring begins in hole - Traits::move(data + offset /*, m_capacity - offset*/, data + rhsOffset, count); // fill old hole - Traits::move(data + offset + rhsCount /*, m_capacity - offset - rhsCount*/, data + offset + count, nm); // move tail down - Traits::move(data + offset + count /*, m_capacity - offset - count*/, data + rhsOffset + rhsCount, rhsCount - count); // fill rest of new hole - } - - m_size = newSize; - Traits::assign(data[newSize], Element()); // terminate - return (*this); + return replace(offset, count, rhs.c_str() + rhsOffset, AZStd::min(rhsCount, rhs.size() - rhsOffset)); } this_type& replace(size_type offset, size_type count, const_pointer ptr, size_type ptrCount) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; // replace [offset, offset + count) with [ptr, ptr + ptrCount) - if (ptr != 0 && ptr >= data && (data + m_size) > ptr) - { - return (replace(offset, count, *this, ptr - data, ptrCount)); // substring, replace carefully - } - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - if (m_size - offset < count) - { - count = m_size - offset; // trim _N0 to size - } - AZSTD_CONTAINER_ASSERT(npos - ptrCount > m_size - count, "Result too long"); + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + // Make sure count is within is no larger than the distance from the offset + // to the end of this string + count = AZStd::min(count, size() - offset); -#ifdef AZSTD_HAS_CHECKED_ITERATORS - orphan_range(data + offset, data + offset + count); -#endif - size_type nm = m_size - count - offset; - if (ptrCount < count) + size_type newSize = size() + ptrCount - count; + size_type charsAfterCountToMove = size() - count - offset; + pointer inputStringCopy{}; + + if (pointer thisBuffer = m_storage.first().GetData(); + (ptr >= thisBuffer && ptr < thisBuffer + size()) + || (ptr + ptrCount > thisBuffer && ptr + ptrCount <= thisBuffer + size())) { - Traits::move(data + offset + ptrCount, data + offset + count, nm); // smaller hole, move tail up - } - size_type num = m_size + ptrCount - count; - if ((0 < ptrCount || 0 < count) && grow(num)) - { - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - // make room and rearrange - if (count < ptrCount) + // Overlap checks for tring needs if the input pointer is anywhere within the string + // even if it is outside of the range of [offset, offset + count) as a growing + // the string buffer could cause a realloc to occur + if (!fits_in_capacity(newSize)) { - Traits::move(data + offset + ptrCount /*, m_capacity - offset - ptrCount*/, data + offset + count, nm); // move tail down + // If the input string is a sub-string and it would cause + // this string to need to re-allocated as it doesn't fit in the capacity + // Then the input string is needs to be copied into a local buffer + inputStringCopy = reinterpret_cast(get_allocator().allocate(ptrCount * sizeof(value_type), alignof(value_type))); + Traits::copy(inputStringCopy, ptr, ptrCount); + // Updated the input string pointer to point to the local buffer + ptr = inputStringCopy; + // Now this string buffer can now be safely resized and the non-overlapping string logic below can be used + } + else + { + // overlapping string in-place logic + // Ex. this = "ABCDEFG", offset = 1, count=4 + // substring is "CDE" + // The text from offset 1 for 4 chars "BCDE": should be replaced with "CDE" + // making a whole for the bytes results in output = "ABCDFG" + // Afterwards output = "ACDEFG" + // The input string overlaps with this string in this case + // So the string is copied piecewise + if (ptrCount <= count) + { // hole doesn't get larger, just copy in substring + Traits::move(thisBuffer + offset, ptr, ptrCount); // fill hole + Traits::copy(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down + } + else + { + if (ptr <= thisBuffer + offset) + { // hole gets larger, substring begins before hole + Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(thisBuffer + offset, ptr, ptrCount); // fill hole + } + else if (thisBuffer + offset + count <= ptr) + { // hole gets larger, substring begins after hole + Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(thisBuffer + offset, ptr + (ptrCount - count), ptrCount); // fill hole + } + else + { // hole gets larger, substring begins in hole + Traits::copy(thisBuffer + offset, ptr, count); // fill old hole + Traits::copy_backward(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); // move tail down + Traits::copy(thisBuffer + offset + count, ptr + ptrCount, ptrCount - count); // fill rest of new hole + } + } + m_storage.first().SetSize(newSize); + Traits::assign(thisBuffer[newSize], Element()); // terminate + return *this; + } + } + + // input string doesn't overlap, so this string can be re-allocated safely + if (grow(newSize)) + { + // Need to regrab the memory address for the storage buffer + // in case the grow re-allocated memory + pointer thisBuffer = m_storage.first().GetData(); + if (count != ptrCount) + { + Traits::move(thisBuffer + offset + ptrCount, thisBuffer + offset + count, charsAfterCountToMove); } if (ptrCount > 0) { - Traits::copy(data + offset /*, m_capacity - offset*/, ptr, ptrCount); // fill hole + // Copy bytes up to the minimum of this string count and input string count + Traits::copy(thisBuffer + offset, ptr, ptrCount); } - - m_size = num; - Traits::assign(data[num], Element()); // terminate + // input string doesn't overlap, so this string can be re-allocated safely + m_storage.first().SetSize(newSize); + Traits::assign(thisBuffer[newSize], Element()); // terminate } + + // If a local string was allocated, then de-allocate its memory + if (inputStringCopy != nullptr) + { + get_allocator().deallocate(inputStringCopy, 0, alignof(value_type)); + } + return *this; } inline this_type& replace(size_type offset, size_type count, const_pointer ptr) { return replace(offset, count, ptr, Traits::length(ptr)); } this_type& replace(size_type offset, size_type count, size_type num, Element ch) { // replace [offset, offset + count) with num * ch - AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset"); - if (m_size - offset < count) + AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset"); + if (size() - offset < count) { - count = m_size - offset; // trim count to size + count = size() - offset; // trim count to size } - AZSTD_CONTAINER_ASSERT(npos - num > m_size - count, "Result is too long"); - size_type nm = m_size - count - offset; + AZSTD_CONTAINER_ASSERT(npos - num > size() - count, "Result is too long"); + size_type nm = size() - count - offset; - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); #ifdef AZSTD_HAS_CHECKED_ITERATORS orphan_range(data + offset, data + offset + count); #endif if (num < count) { - Traits::move(data + offset + num /*, m_capacity - offset - num*/, data + offset + count, nm); // smaller hole, move tail up + Traits::move(data + offset + num, data + offset + count, nm); // smaller hole, move tail up } - size_type numToGrow = m_size + num - count; + size_type numToGrow = size() + num - count; if ((0 < num || 0 < count) && grow(numToGrow)) { // make room and rearrange - data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + data = m_storage.first().GetData(); if (count < num) { - Traits::move(data + offset + num /*, m_capacity - offset - num*/, data + offset + count, nm); // move tail down + Traits::move(data + offset + num, data + offset + count, nm); // move tail down } - if (count == 1) - { - Traits::assign(*(data + offset), ch); - } - else - { - Traits::assign(data + offset, num, ch); - } - m_size = numToGrow; + Traits::assign(data + offset, num, ch); + m_storage.first().SetSize(numToGrow); Traits::assign(data[numToGrow], Element()); // terminate } return *this; @@ -722,7 +787,7 @@ namespace AZStd const_pointer firstPtr = first; const_pointer lastPtr = last; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); return replace(firstPtr - data, lastPtr - firstPtr, rhs); } @@ -735,7 +800,7 @@ namespace AZStd const_pointer firstPtr = first; const_pointer lastPtr = last; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); return replace(firstPtr - data, lastPtr - firstPtr, ptr, count); } @@ -748,7 +813,7 @@ namespace AZStd const_pointer firstPtr = first; const_pointer lastPtr = last; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); return replace(firstPtr - data, lastPtr - firstPtr, ptr); } @@ -761,113 +826,133 @@ namespace AZStd const_pointer firstPtr = first; const_pointer lastPtr = last; #endif - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); return replace(firstPtr - data, lastPtr - firstPtr, count, ch); } - template - inline this_type& replace(const_iterator first, const_iterator last, InputIterator first2, InputIterator last2) - { // replace [first, last) with [first2,last2) - return replace_iter(first, last, first2, last2, is_integral()); - } - - this_type& replace(const_iterator first, const_iterator last, const_pointer first2, const_pointer last2) + template + inline auto replace(const_iterator first, const_iterator last, InputIt replaceFirst, InputIt replaceLast) + -> enable_if_t && !is_convertible_v, this_type&> { -#ifdef AZSTD_HAS_CHECKED_ITERATORS - const_pointer first1 = first.get_iterator(); - const_pointer last1 = last.get_iterator(); -#else - const_pointer first1 = first; - const_pointer last1 = last; -#endif - // replace [first, last) with [first2, last2), const pointers - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (first2 == last2) + if constexpr (Internal::satisfies_contiguous_iterator_concept_v + && is_same_v::value_type, value_type>) { - erase(first1 - data, last1 - first1); + return replace(first, last, AZStd::to_address(replaceFirst), AZStd::distance(replaceFirst, replaceLast)); + } + else if constexpr (Internal::is_forward_iterator_v) + { + // Input Iterator pointer type doesn't match the const_pointer type + // So the elements need to be appended one by one into the buffer + + size_type insertOffset = AZStd::distance(cbegin(), first); + size_type postInsertOffset = AZStd::distance(cbegin(), last); + size_type count = AZStd::distance(replaceFirst, replaceLast); + size_type oldSize = size(); + size_type newSize = oldSize + count - AZStd::distance(first, last); + if (grow(newSize)) + { + pointer buffer = data(); + Traits::move(first + count, last, oldSize - postInsertOffset); // empty out hole + for (size_t updateIndex = insertOffset; replaceFirst != replaceLast; ++replaceFirst, ++updateIndex) + { + Traits::assign(buffer[updateIndex], static_cast(*replaceFirst)); + } + m_storage.first().SetSize(newSize); + Traits::assign(buffer[newSize], Element()); // terminate + } + return *this; } else { - replace(first1 - data, last1 - first1, &*first2, last2 - first2); + // input iterator that aren't forward iterators can only be used in a single pass + // algorithm. Therefore AZStd::distance can't be used + // So the input is copied into a local string and then delegated + // to use the (const_pointer, size_type) overload + basic_string inputCopy; + for (; replaceFirst != replaceLast; ++replaceFirst) + { + inputCopy.push_back(static_cast(*replaceFirst)); + } + + return replace(first, last, inputCopy.c_str(), inputCopy.size()); } - return *this; } inline reference at(size_type offset) { // subscript mutable sequence with checking - AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset"); - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset"); + pointer data = m_storage.first().GetData(); return data[offset]; } inline const_reference at(size_type offset) const { // subscript nonmutable sequence with checking - AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset"); - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset"); + const_pointer data = m_storage.first().GetData(); return data[offset]; } inline reference operator[](size_type offset) { // subscript mutable sequence with checking - AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset"); - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset"); + pointer data = m_storage.first().GetData(); return data[offset]; } inline const_reference operator[](size_type offset) const { // subscript nonmutable sequence with checking - AZSTD_CONTAINER_ASSERT(m_size > offset, "Invalid offset"); - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() > offset, "Invalid offset"); + const_pointer data = m_storage.first().GetData(); return data[offset]; } inline reference front() { - AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::front - string is empty!"); - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::front - string is empty!"); + pointer data = m_storage.first().GetData(); return data[0]; } inline const_reference front() const { - AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::front - string is empty!"); - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::front - string is empty!"); + const_pointer data = m_storage.first().GetData(); return data[0]; } inline reference back() { - AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::back - string is empty!"); - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - return data[m_size - 1]; + AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::back - string is empty!"); + pointer data = m_storage.first().GetData(); + return data[size() - 1]; } inline const_reference back() const { - AZSTD_CONTAINER_ASSERT(m_size != 0, "AZStd::string::back - string is empty!"); - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - return data[m_size - 1]; + AZSTD_CONTAINER_ASSERT(size() != 0, "AZStd::string::back - string is empty!"); + const_pointer data = m_storage.first().GetData(); + return data[size() - 1]; } inline void push_back(Element ch) { - const_pointer end = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - end += m_size; + const_pointer end = data(); + end += size(); insert(end, ch); } - inline const_pointer c_str() const { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); } - inline size_type length() const { return m_size; } - inline size_type size() const { return m_size; } - inline size_type capacity() const { return m_capacity; } + inline const_pointer c_str() const { return (data()); } + inline size_type length() const { return m_storage.first().GetSize(); } + inline size_type size() const { return m_storage.first().GetSize(); } + inline size_type capacity() const { return m_storage.first().GetCapacity(); } inline size_type max_size() const { // return maximum possible length of sequence - return AZStd::allocator_traits::max_size(m_allocator) / sizeof(value_type); + return AZStd::allocator_traits::max_size(m_storage.second()) / sizeof(value_type); } inline void resize(size_type newSize) @@ -877,58 +962,58 @@ namespace AZStd inline void resize_no_construct(size_type newSize) { - if (newSize <= m_size) + if (newSize <= size()) { erase(newSize); } else { reserve(newSize); - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - m_size = newSize; - Traits::assign(data[m_size], Element()); // terminate + pointer data = m_storage.first().GetData(); + m_storage.first().SetSize(newSize); + Traits::assign(data[newSize], Element()); // terminate } } inline void resize(size_type newSize, Element ch) { // determine new length, padding with ch elements as needed - if (newSize <= m_size) + if (newSize <= size()) { erase(newSize); } else { - append(newSize - m_size, ch); + append(newSize - size(), ch); } } void reserve(size_type newCapacity = 0) { // determine new minimum length of allocated storage - if (m_size <= newCapacity && m_capacity != newCapacity) + if (size() <= newCapacity && capacity() != newCapacity) { // change reservation - size_type size = m_size; + size_type curSize = size(); if (grow(newCapacity)) { - m_size = size; - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - Traits::assign(data[size], Element()); // terminate + m_storage.first().SetSize(curSize); + pointer data = m_storage.first().GetData(); + Traits::assign(data[curSize], Element()); // terminate } } } - inline bool empty() const { return (m_size == 0); } - size_type copy(Element* dest /*, size_type destSize */, size_type count, size_type offset = 0) const + inline bool empty() const { return size() == 0; } + size_type copy(Element* dest, size_type count, size_type offset = 0) const { // copy [offset, offset + count) to [dest, dest + count) // assume there is enough space in _Ptr - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - if (m_size - offset < count) + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + if (size() - offset < count) { - count = m_size - offset; + count = size() - offset; } - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - Traits::copy(dest /*, destSize*/, data + offset, count); + const_pointer data = m_storage.first().GetData(); + Traits::copy(dest, data + offset, count); return count; } @@ -939,19 +1024,10 @@ namespace AZStd return; } - if (m_allocator == rhs.m_allocator) + if (m_storage.second() == rhs.m_storage.second()) { - // same allocator, swap control information -#ifdef AZSTD_HAS_CHECKED_ITERATORS - swap_all(rhs); -#endif - Element temp[SSO_BUF_SIZE]; - ::memcpy(temp, rhs.m_buffer, sizeof(m_buffer)); - ::memcpy(rhs.m_buffer, m_buffer, sizeof(m_buffer)); - ::memcpy(m_buffer, temp, sizeof(m_buffer)); - - AZStd::swap(m_size, rhs.m_size); - AZStd::swap(m_capacity, rhs.m_capacity); + // same allocator, swap storage + m_storage.first().swap(rhs.m_storage.first()); } else { @@ -980,174 +1056,76 @@ namespace AZStd inline size_type find(const this_type& rhs, size_type offset = 0) const { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return find(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return find(rhsData, offset, rhs.size()); } size_type find(const_pointer ptr, size_type offset, size_type count) const { - AZ_Assert(ptr != NULL, "Invalid input!"); - - // look for [ptr, ptr + count) beginning at or after offset - if (count == 0 && offset <= m_size) - { - return offset; // null string always matches (if inside string) - } - size_type nm; - if (offset < m_size && count <= (nm = m_size - offset)) - { // room for match, look for it - const_pointer uptr, vptr; - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - for (nm -= count - 1, vptr = data + offset; (uptr = Traits::find(vptr, nm, *ptr)) != 0; nm -= uptr - vptr + 1, vptr = uptr + 1) - { - if (Traits::compare(uptr, ptr, count) == 0) - { - return (uptr - data); // found a match - } - } - } - - return (npos); // no match + return StringInternal::find(data(), size(), ptr, offset, count, npos); } inline size_type find(const_pointer ptr, size_type offset = 0) const { return find(ptr, offset, Traits::length(ptr)); } inline size_type find(Element ch, size_type offset = 0) const { return find((const_pointer) & ch, offset, 1); } inline size_type rfind(const this_type& rhs, size_type offset = npos) const { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return rfind(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return rfind(rhsData, offset, rhs.size()); } size_type rfind(const_pointer ptr, size_type offset, size_type count) const - { // look for [ptr, ptr + count) beginning before offset - if (count == 0) - { - return (offset < m_size ? offset : m_size); // null always matches - } - if (count <= m_size) - { // room for match, look for it - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const_pointer uptr = data + (offset < m_size - count ? offset : m_size - count); - for (;; --uptr) - { - if (Traits::eq(*uptr, *ptr) && Traits::compare(uptr, ptr, count) == 0) - { - return (uptr - data); // found a match - } - else if (uptr == data) - { - break; // at beginning, no more chance for match - } - } - } - - return npos; // no match + { + return StringInternal::rfind(data(), size(), ptr, offset, count, npos); } inline size_type rfind(const_pointer ptr, size_type offset = npos) const { return rfind(ptr, offset, Traits::length(ptr)); } inline size_type rfind(Element ch, size_type offset = npos) const { return rfind((const_pointer) & ch, offset, 1); } inline size_type find_first_of(const this_type& rhs, size_type offset = 0) const { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return find_first_of(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return find_first_of(rhsData, offset, rhs.size()); } size_type find_first_of(const_pointer ptr, size_type offset, size_type count) const - { // look for one of [ptr, ptr + count) at or after offset - if (0 < count && offset < m_size) - { // room for match, look for it - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const Element* const vptr = data + m_size; - for (const_pointer uptr = data + offset; uptr < vptr; ++uptr) - { - if (Traits::find(ptr, count, *uptr) != 0) - { - return uptr - data; // found a match - } - } - } - return npos; // no match + { + return StringInternal::find_first_of(data(), size(), ptr, offset, count, npos); } inline size_type find_first_of(const_pointer ptr, size_type offset = 0) const { return find_first_of(ptr, offset, Traits::length(ptr)); } inline size_type find_first_of(Element ch, size_type offset = 0) const { return find((const_pointer) & ch, offset, 1); } inline size_type find_last_of(const this_type& rhs, size_type offset = npos) const { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return find_last_of(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return find_last_of(rhsData, offset, rhs.size()); } size_type find_last_of(const_pointer ptr, size_type offset, size_type count) const - { // look for one of [ptr, ptr + count) before offset - if (0 < count && 0 < m_size) - { - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - for (const_pointer uptr = data + (offset < m_size ? offset : m_size - 1);; --uptr) - { - if (Traits::find(ptr, count, *uptr) != 0) - { - return uptr - data; // found a match - } - else if (uptr == data) - { - break; // at beginning, no more chance for match - } - } - } - - return npos; // no match + { + return StringInternal::find_last_of(data(), size(), ptr, offset, count, npos); } inline size_type find_last_of(const_pointer ptr, size_type offset = npos) const { return find_last_of(ptr, offset, Traits::length(ptr)); } inline size_type find_last_of(Element ch, size_type offset = npos) const { return rfind((const_pointer) & ch, offset, 1); } inline size_type find_first_not_of(const this_type& rhs, size_type offset = 0) const { // look for none of rhs at or after offset - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return find_first_not_of(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return find_first_not_of(rhsData, offset, rhs.size()); } size_type find_first_not_of(const_pointer ptr, size_type offset, size_type count) const { - // look for none of [ptr, ptr + count) at or after offset - if (offset < m_size) - { // room for match, look for it - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - const Element* const vptr = data + m_size; - for (const_pointer uptr = data + offset; uptr < vptr; ++uptr) - { - if (Traits::find(ptr, count, *uptr) == 0) - { - return uptr - data; - } - } - } - return npos; + return StringInternal::find_first_not_of(data(), size(), ptr, offset, count, npos); } inline size_type find_first_not_of(const_pointer ptr, size_type offset = 0) const { return find_first_not_of(ptr, offset, Traits::length(ptr)); } inline size_type find_first_not_of(Element ch, size_type offset = 0) const { return find_first_not_of((const_pointer) & ch, offset, 1); } inline size_type find_last_not_of(const this_type& rhs, size_type offset = npos) const { // look for none of rhs before offset - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return find_last_not_of(rhsData, offset, rhs.m_size); + const_pointer rhsData = rhs.data(); + return find_last_not_of(rhsData, offset, rhs.size()); } size_type find_last_not_of(const_pointer ptr, size_type offset, size_type count) const - { // look for none of [ptr, ptr + count) before offset - if (0 < m_size) - { - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - for (const_pointer uptr = data + (offset < m_size ? offset : m_size - 1);; --uptr) - { - if (Traits::find(ptr, count, *uptr) == 0) - { - return uptr - data; - } - else if (uptr == data) - { - break; - } - } - } - return npos; + { + return StringInternal::find_last_not_of(data(), size(), ptr, offset, count, npos); } inline size_type find_last_not_of(const_pointer ptr, size_type offset = npos) const { return find_last_not_of(ptr, offset, Traits::length(ptr)); } @@ -1161,8 +1139,8 @@ namespace AZStd inline int compare(const this_type& rhs) const { - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; - return compare(0, m_size, rhsData, rhs.m_size); + const_pointer rhsData = rhs.data(); + return compare(0, size(), rhsData, rhs.size()); } inline int compare(size_type offset, size_type count, const this_type& rhs) const @@ -1173,26 +1151,26 @@ namespace AZStd int compare(size_type offset, size_type count, const this_type& rhs, size_type rhsOffset, size_type rhsCount) const { // compare [offset, offset + count) with rhs [rhsOffset, rhsOffset + rhsCount) - AZSTD_CONTAINER_ASSERT(rhs.m_size >= rhsOffset, "Invalid offset"); - if (rhs.m_size - rhsOffset < rhsCount) + AZSTD_CONTAINER_ASSERT(rhs.size() >= rhsOffset, "Invalid offset"); + if (rhs.size() - rhsOffset < rhsCount) { - rhsCount = rhs.m_size - rhsOffset; // trim rhsCount to size + rhsCount = rhs.size() - rhsOffset; // trim rhsCount to size } - const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer; + const_pointer rhsData = rhs.data(); return compare(offset, count, rhsData + rhsOffset, rhsCount); } - inline int compare(const_pointer ptr) const { return compare(0, m_size, ptr, Traits::length(ptr)); } + inline int compare(const_pointer ptr) const { return compare(0, size(), ptr, Traits::length(ptr)); } inline int compare(size_type offset, size_type count, const_pointer ptr) const { return compare(offset, count, ptr, Traits::length(ptr)); } int compare(size_type offset, size_type count, const_pointer ptr, size_type ptrCount) const { // compare [offset, offset + _N0) with [_Ptr, _Ptr + _Count) - AZSTD_CONTAINER_ASSERT(m_size >= offset, "Invalid offset"); - if (m_size - offset < count) + AZSTD_CONTAINER_ASSERT(size() >= offset, "Invalid offset"); + if (size() - offset < count) { - count = m_size - offset; // trim count to size + count = size() - offset; // trim count to size } - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + const_pointer data = m_storage.first().GetData(); size_type ans = Traits::compare(data + offset, ptr, count < ptrCount ? count : ptrCount); return (ans != 0 ? (int)ans : count < ptrCount ? -1 : count == ptrCount ? 0 : +1); } @@ -1231,11 +1209,11 @@ namespace AZStd inline void pop_back() { - if (m_size > 0) + if (!empty()) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - --m_size; - Traits::assign(data[m_size], Element()); // terminate + pointer data = m_storage.first().GetData(); + m_storage.first().SetSize(m_storage.first().GetSize() - 1); + Traits::assign(data[size()], Element()); // terminate } } @@ -1245,39 +1223,35 @@ namespace AZStd * @{ */ /// TR1 Extension. Return pointer to the vector data. The vector data is guaranteed to be stored as an array. - inline pointer data() { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); } - inline const_pointer data() const { return (SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer); } + inline pointer data() { return m_storage.first().GetData(); } + inline const_pointer data() const { return m_storage.first().GetData(); } /// /// The only difference from the standard is that we return the allocator instance, not a copy. - inline allocator_type& get_allocator() { return m_allocator; } - inline const allocator_type& get_allocator() const { return m_allocator; } + inline allocator_type& get_allocator() { return m_storage.second(); } + inline const allocator_type& get_allocator() const { return m_storage.second(); } /// Set the vector allocator. If different than then current all elements will be reallocated. void set_allocator(const allocator_type& allocator) { - if (m_allocator != allocator) + if (m_storage.second() != allocator) { - if (m_size > 0 && SSO_BUF_SIZE <= m_capacity) + if (!empty() && !m_storage.first().ShortStringOptimizationActive()) { allocator_type newAllocator = allocator; - pointer data = m_data; + pointer data = m_storage.first().GetData(); - pointer newData = reinterpret_cast(newAllocator.allocate(sizeof(node_type) * (m_capacity + 1), alignment_of::value)); + pointer newData = reinterpret_cast(newAllocator.allocate(sizeof(node_type) * (capacity() + 1), alignof(node_type))); - Traits::copy(newData, data, m_size + 1); // copy elements and terminator + Traits::copy(newData, data, size() + 1); // copy elements and terminator // Free memory (if needed). deallocate_memory(data, 0, typename allocator_type::allow_memory_leaks()); - m_allocator = newAllocator; - -#ifdef AZSTD_HAS_CHECKED_ITERATORS - orphan_all(); -#endif + m_storage.second() = newAllocator; } else { - m_allocator = allocator; + m_storage.second() = allocator; } } } @@ -1296,12 +1270,12 @@ namespace AZStd #else pointer iterPtr = iter; #endif - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (iterPtr < data || iterPtr > (data + m_size)) + const_pointer data = m_storage.first().GetData(); + if (iterPtr < data || iterPtr > (data + size())) { return isf_none; } - else if (iterPtr == (data + m_size)) + else if (iterPtr == (data + size())) { return isf_valid; } @@ -1316,12 +1290,12 @@ namespace AZStd #else const_pointer iterPtr = iter; #endif - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - if (iterPtr < data || iterPtr > (data + m_size)) + const_pointer data = m_storage.first().GetData(); + if (iterPtr < data || iterPtr > (data + size())) { return isf_none; } - else if (iterPtr == (data + m_size)) + else if (iterPtr == (data + size())) { return isf_valid; } @@ -1337,86 +1311,74 @@ namespace AZStd * \note This function is added to the vector for consistency. In the vector case we have only one allocation, and if the allocator allows memory leaks * it can just leave deallocate function empty, which performance wise will be the same. For more complex containers this will make big difference. */ - void leak_and_reset() + void leak_and_reset() { - m_size = 0; - m_capacity = SSO_BUF_SIZE - 1; - Traits::assign(m_buffer[0], Element()); - -#ifdef AZSTD_HAS_CHECKED_ITERATORS - orphan_all(); -#endif + m_storage.first() = {}; } /** * Set the capacity, if necessary it will erase elements at the end of the container to match the new capacity. */ - void set_capacity(size_type numElements) + void set_capacity(size_type numElements) { // sets the new capacity of the vector, can be smaller than size() - if (m_capacity != numElements) + if (capacity() != numElements) { - if (numElements < SSO_BUF_SIZE) + if (numElements < ShortStringData::Capacity) { - if (m_capacity >= SSO_BUF_SIZE) + if (!m_storage.first().ShortStringOptimizationActive()) { // copy any leftovers to small buffer and deallocate - pointer ptr = m_data; - numElements = numElements < m_size ? numElements : m_size; + pointer ptr = m_storage.first().GetData(); + numElements = numElements < size() ? numElements : size(); + m_storage.first().SetCapacity(ShortStringData::Capacity); if (0 < numElements) { - Traits::copy(m_buffer /*, SSO_BUF_SIZE*/, ptr, numElements); + Traits::copy(m_storage.first().GetData(), ptr, numElements); } - deallocate_memory(ptr, 0, typename allocator_type::allow_memory_leaks()); - m_capacity = SSO_BUF_SIZE - 1; + // deallocate_memory functione examines the current + // m_storage short string optimization state was changed to true + // by the SetCapacity call above. Therefore m_storage.second().deallocate + // is used directly + m_storage.second().deallocate(ptr, 0, alignof(node_type)); } - m_size = numElements; - Traits::assign(m_buffer[numElements], Element()); // terminate + m_storage.first().SetSize(numElements); + Traits::assign(m_storage.first().GetData()[numElements], Element()); // terminate } else { size_type expandedSize = 0; - if (m_capacity >= SSO_BUF_SIZE) + if (!m_storage.first().ShortStringOptimizationActive()) { - expandedSize = m_allocator.resize(m_data, sizeof(node_type) * (numElements + 1)); + expandedSize = m_storage.second().resize(m_storage.first().GetData(), sizeof(node_type) * (numElements + 1)); // our memory managers allocate on 8+ bytes boundary and our node type should be less than that in general, otherwise // we need to take care when we compute the size on deallocate. AZ_Assert(expandedSize % sizeof(node_type) == 0, "Expanded size not a multiply of node type. This should not happen"); size_type expandedCapacity = expandedSize / sizeof(node_type); if (expandedCapacity > numElements) { - m_capacity = expandedCapacity - 1; + m_storage.first().SetCapacity(expandedCapacity - 1); return; } } - pointer newData = reinterpret_cast(m_allocator.allocate(sizeof(node_type) * (numElements + 1), alignment_of::value)); - AZSTD_CONTAINER_ASSERT(newData != 0, "AZStd::string allocation failed!"); + pointer newData = reinterpret_cast(m_storage.second().allocate(sizeof(node_type) * (numElements + 1), alignof(node_type))); + AZSTD_CONTAINER_ASSERT(newData != nullptr, "AZStd::string allocation failed!"); - size_type newSize = numElements < m_size ? numElements : m_size; - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + size_type newSize = numElements < m_storage.first().GetSize() ? numElements : m_storage.first().GetSize(); + pointer data = m_storage.first().GetData(); if (newSize > 0) { - Traits::copy(newData /*, newSize + 1*/, data, newSize); // copy existing elements - } - if (m_capacity >= SSO_BUF_SIZE) - { - deallocate_memory(m_data, expandedSize, typename allocator_type::allow_memory_leaks()); + Traits::copy(newData, data, newSize); // copy existing elements } + deallocate_memory(data, expandedSize, typename allocator_type::allow_memory_leaks()); - m_data = newData; - m_capacity = numElements; - m_size = newSize; - Traits::assign(m_data[newSize], Element()); // terminate + Traits::assign(newData[newSize], Element()); // terminate + m_storage.first().SetCapacity(numElements); + m_storage.first().SetData(newData); + m_storage.first().SetSize(newSize); } - -#ifdef AZSTD_HAS_CHECKED_ITERATORS - // when we move data in the buffer we don't really need to make invalid all iterators, but it's - // very important that we are consistent, so people don't have different behavior when they have - // short strings - orphan_all(); -#endif } } @@ -1521,9 +1483,9 @@ namespace AZStd } }; -// Clang supports compile-time check for printf-like signatures -// On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check -// For not affecting final release binary size, we don't use the templated version on Release configuration either + // Clang supports compile-time check for printf-like signatures + // On MSVC, *only* if /analyze flag is enabled(defines _PREFAST_) we can also do a compile-time check + // For not affecting final release binary size, we don't use the templated version on Release configuration either #if AZ_COMPILER_CLANG || defined(_PREFAST_) || defined(_RELEASE) # if AZ_COMPILER_CLANG # define FORMAT_FUNC __attribute__((format(printf, 1, 2))) @@ -1597,137 +1559,70 @@ namespace AZStd template inline basic_string(const basic_string& rhs) - : m_size(0) - , m_capacity(SSO_BUF_SIZE - 1) { assign(rhs.c_str()); } template inline this_type& operator=(const basic_string& rhs) { return assign(rhs.c_str()); } template - inline this_type& append(const basic_string& rhs) { return append(rhs.c_str()); } + inline this_type& append(const basic_string& rhs) { return append(rhs.c_str()); } template inline this_type& insert(size_type offset, const basic_string& rhs) { return insert(offset, rhs.c_str()); } template inline this_type& replace(size_type offset, size_type count, const basic_string& rhs) { return replace(offset, count, rhs.c_str()); } template - inline int compare(const basic_string& rhs) { return compare(rhs.c_str()); } + inline int compare(const basic_string& rhs) { return compare(rhs.c_str()); } // @} protected: - enum - { // length of internal buffer, [1, 16] - SSO_BUF_SIZE = 16 / sizeof (Element) < 1 ? 1 : 16 / sizeof(Element) - }; enum { // roundup mask for allocated buffers, [0, 15] - _ALLOC_MASK = sizeof (Element) <= 1 ? 15 : sizeof (Element) <= 2 ? 7 : sizeof (Element) <= 4 ? 3 : sizeof (Element) <= 8 ? 1 : 0 + _ALLOC_MASK = sizeof(Element) <= 1 ? 15 + : sizeof(Element) <= 2 ? 7 + : sizeof(Element) <= 4 ? 3 + : sizeof(Element) <= 8 ? 1 : 0 }; - template - inline this_type& append_iter(InputIterator count, InputIterator ch, const true_type& /* is_integral */) - { // append count * ch - return append((size_type)count, (Element)ch); - } - - template - inline void construct_iter(InputIterator count, InputIterator ch, const true_type& /* is_integral */) - { // initialize from count * ch - assign((size_type)count, (Element)ch); - } - - template - inline void construct_iter(InputIterator first, InputIterator last, const false_type& /*, const input_iterator_tag&*/) - { - // initialize from [first, last), input iterators - // \todo use insert ? - for (; first != last; ++first) - { - append((size_type)1, (Element) * first); - } - } - - - template - inline this_type& append_iter(InputIterator first, InputIterator last, const false_type& /* !is_integral */) - { // append [first, last), input iterators - return replace(end(), end(), first, last); - } - - - template - inline this_type& assign_iter(InputIterator count, InputIterator ch, const true_type&) { return assign((size_type)count, (Element)ch); } - template - inline this_type& assign_iter(InputIterator first, InputIterator last, const false_type&){ return replace(begin(), end(), first, last); } - - template - inline void insert_iter(const_iterator insertPos, InputIterator count, InputIterator ch, const true_type& /* is_integral() */) - { // insert count * ch at insertPos - insert(insertPos, (size_type)count, (Element)ch); - } - - template - inline void insert_iter(const_iterator insertPos, InputIterator first, InputIterator last, const false_type& /* is_integral() */) - { // insert [first, last) at insertPos, input iterators - replace(insertPos, insertPos, first, last); - } - - - template - inline this_type& replace_iter(const_iterator first, const_iterator last, InputIterator count, InputIterator ch, const true_type& /* is_intergral */) - { // replace [first, last) with count * ch - return replace(first, last, (size_type)count, (Element)ch); - } - - template - inline this_type& replace_iter(const_iterator first, const_iterator last, InputIterator first2, InputIterator last2, const false_type& /* !is_intergral */) - { // replace [first, last) with [first2, last2), input iterators - this_type rhs(first2, last2); - replace(first, last, rhs); - return *this; - } - void copy(size_type newSize, size_type oldLength) { size_type newCapacity = newSize | _ALLOC_MASK; - if (newCapacity / 3 < m_capacity / 2) + size_type currentCapacity = capacity(); + if (newCapacity / 3 < currentCapacity / 2) { - newCapacity = m_capacity + m_capacity / 2; // grow exponentially if possible + newCapacity = currentCapacity + currentCapacity / 2; // grow exponentially if possible } - if (newCapacity >= SSO_BUF_SIZE) + if (newCapacity >= ShortStringData::Capacity) { size_type expandedSize = 0; - if (m_capacity >= SSO_BUF_SIZE) + if (!m_storage.first().ShortStringOptimizationActive()) { - expandedSize = m_allocator.resize(m_data, sizeof(node_type) * (newCapacity + 1)); + expandedSize = m_storage.second().resize(m_storage.first().GetData(), sizeof(node_type) * (newCapacity + 1)); // our memory managers allocate on 8+ bytes boundary and our node type should be less than that in general, otherwise // we need to take care when we compute the size on deallocate. - AZ_Assert(expandedSize % sizeof(node_type) == 0, "Expanded size not a multiply of node type. This should not happen"); + AZ_Assert(expandedSize % sizeof(node_type) == 0, "Expanded size not a multiple of node type. This should not happen"); size_type expandedCapacity = expandedSize / sizeof(node_type); if (expandedCapacity > newCapacity) { - m_capacity = expandedCapacity - 1; + m_storage.first().SetCapacity(expandedCapacity - 1); return; } } - pointer newData = reinterpret_cast(m_allocator.allocate(sizeof(node_type) * (newCapacity + 1), alignment_of::value)); - AZSTD_CONTAINER_ASSERT(newData != 0, "AZStd::string allocation failed!"); + pointer newData = reinterpret_cast(m_storage.second().allocate(sizeof(node_type) * (newCapacity + 1), alignof(node_type))); + AZSTD_CONTAINER_ASSERT(newData != nullptr, "AZStd::string allocation failed!"); if (newData) { - const_pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; + pointer data = m_storage.first().GetData(); if (0 < oldLength) { - Traits::copy(newData /*, newSize + 1*/, data, oldLength); // copy existing elements - } - if (m_capacity >= SSO_BUF_SIZE) - { - deallocate_memory(m_data, expandedSize, typename allocator_type::allow_memory_leaks()); + Traits::copy(newData, data, oldLength); // copy existing elements } + deallocate_memory(data, expandedSize, typename allocator_type::allow_memory_leaks()); - m_data = newData; - m_capacity = newCapacity; - Traits::assign(m_data[newSize], Element()); // terminate + Traits::assign(newData[oldLength], Element()); // terminate + m_storage.first().SetCapacity(newCapacity); + m_storage.first().SetSize(oldLength); + m_storage.first().SetData(newData); } } } @@ -1735,40 +1630,209 @@ namespace AZStd bool grow(size_type newSize) { // ensure buffer is big enough, trim to size if _Trim is true - if (m_capacity < newSize) + if (capacity() < newSize) { - copy(newSize, m_size); // reallocate to grow + copy(newSize, size()); // reallocate to grow } else if (newSize == 0) { - pointer data = SSO_BUF_SIZE <= m_capacity ? m_data : m_buffer; - m_size = 0; + pointer data = m_storage.first().GetData(); + m_storage.first().SetSize(0); Traits::assign(data[0], Element()); // terminate } return (0 < newSize); // return true only if more work to do } + bool fits_in_capacity(size_type newSize) + { + return newSize <= capacity(); + } + inline void deallocate_memory(pointer, size_type, const true_type& /* allocator::allow_memory_leaks */) {} inline void deallocate_memory(pointer data, size_type expandedSize, const false_type& /* !allocator::allow_memory_leaks */) { - if (m_capacity >= SSO_BUF_SIZE) + if (!m_storage.first().ShortStringOptimizationActive()) { - size_type byteSize = (expandedSize == 0) ? (sizeof(node_type) * (m_capacity + 1)) : expandedSize; - m_allocator.deallocate(data, byteSize, alignment_of::value); + size_type byteSize = (expandedSize == 0) ? (sizeof(node_type) * (m_storage.first().GetCapacity() + 1)) : expandedSize; + m_storage.second().deallocate(data, byteSize, alignof(node_type)); } } - union //Storage + //! Assuming 64-bit for pointer and size_t size + //! The offset and sizes of each structure are marked below + + //! dynamically allocated data + struct AllocatedStringData { - Element m_buffer[SSO_BUF_SIZE]; //< small buffer used for small string optimization - pointer m_data; //< dynamically allocated data + AllocatedStringData() + { + m_capacity = 0; + m_ssoActive = false; + } + // bit offset: 0, bits: 64 + pointer m_data{}; + + // bit offset: 64, bit: 64 + size_type m_size{}; + + // Use all but the top bit of a size_t for the string capacity + // This allows the short string optimization to be used + // with no additional space at the cost of cutting the max_size in half + // to 2^63-1 + // offset: 128, bits: 63 + size_type m_capacity : AZStd::numeric_limits::digits - 1; + + // bit offset: 191, bits: 1 + size_type m_ssoActive : 1; + + // Total size 192 bits(24 bytes) }; - size_type m_size; // current length of string - size_type m_capacity; // current storage reserved for string - allocator_type m_allocator; + static_assert(sizeof(AllocatedStringData) <= 24, "The AllocatedStringData structure" + " should be an 8-byte pointer, 8 byte size, 63-bit capacity and 1-bit SSO flag for" + " a total of 24 bytes"); + + //! small buffer used for small string optimization + struct ShortStringData + { + //! The size can be stored within 7 bits since the buffer will be no larger + //! than 23 bytes(22 characters + 1 null-terminating character) + inline static constexpr size_type BufferMaxSize = sizeof(AllocatedStringData) - sizeof(AZ::u8); + static_assert(sizeof(Element) < BufferMaxSize, "The size of Element type must be less than the size of " + " the AllocatedStringData struct in order to use it with the basic_string class"); + inline static constexpr size_type BufferCapacityPlusNull = BufferMaxSize / sizeof(Element); + + inline static constexpr size_type Capacity = BufferCapacityPlusNull - 1; + + ShortStringData() + { + // Make sure the short string buffer is null-terminated + m_buffer[0] = Element{}; + m_size = 0; + m_ssoActive = true; + } + + // bit offset: 0, bits: 184 + Element m_buffer[BufferCapacityPlusNull]; + + // Padding to make sure for Element types with a size >1 + // such as wchar_t, that the `m_size` member starts at the bit 164 + // NOTE: Uses the anonymous struct extension + // supported by MSVC, Clang and GCC + // Takes advantage of the empty base optimization + // to have the StringInternal::Padding struct + // take 0 bytes when the Element type is 1-byte type like `char` + // When C++20 support is added, this can be changed to use [[no_unique_address]] + struct + : StringInternal::Padding + { + + // bit offset: 184, bits: 7 + AZ::u8 m_size : AZStd::numeric_limits::digits - 1; + + // bit offset: 191, bits: 1 + AZ::u8 m_ssoActive : 1; + }; + // Total size 192 bits(24 bytes) + }; + + struct PointerAlignedData + { + uintptr_t m_alignedValues[sizeof(ShortStringData) / sizeof(uintptr_t)]; + }; + + static_assert(sizeof(AllocatedStringData) == sizeof(ShortStringData) && "Short string struct must be the same size" + " as the regular allocated string struct"); + + static_assert(sizeof(PointerAlignedData) == sizeof(ShortStringData) && "Pointer aligned struct must be the same size" + " as the short string struct "); + + // The top-bit in the last byte of the AllocatedStringData and ShortStringData is used to determine if the short string optimization is being used + union Storage + { + Storage() {}; + + bool ShortStringOptimizationActive() const + { + return m_shortData.m_ssoActive; + } + const_pointer GetData() const + { + return ShortStringOptimizationActive() ? m_shortData.m_buffer + : reinterpret_cast(m_shortData).m_data; + } + pointer GetData() + { + return ShortStringOptimizationActive() ? m_shortData.m_buffer + : reinterpret_cast(m_shortData).m_data; + } + void SetData(pointer address) + { + if (!ShortStringOptimizationActive()) + { + reinterpret_cast(m_shortData).m_data = address; + } + else + { + AZSTD_CONTAINER_ASSERT(false, "Programming Error: string class is invoking SetData when the Short Optimization" + " is active. Make sure SetCapacity() is invoked" + " before calling this function."); + } + } + size_type GetSize() const + { + return ShortStringOptimizationActive() ? m_shortData.m_size + : reinterpret_cast(m_shortData).m_size; + } + void SetSize(size_type size) + { + if (ShortStringOptimizationActive()) + { + m_shortData.m_size = size; + } + else + { + reinterpret_cast(m_shortData).m_size = size; + } + } + size_type GetCapacity() const + { + return ShortStringOptimizationActive() ? m_shortData.Capacity + : reinterpret_cast(m_shortData).m_capacity; + } + void SetCapacity(size_type capacity) + { + if (capacity <= ShortStringData::Capacity) + { + m_shortData.m_ssoActive = true; + } + else + { + m_shortData.m_ssoActive = false; + reinterpret_cast(m_shortData).m_capacity = capacity; + } + } + void swap(Storage& rhs) + { + // Use pointer sized swaps to swap the string storage + AZStd::aligned_storage_for_t tempStorage; + ::memcpy(&tempStorage, this, sizeof(Storage)); + ::memcpy(this, &rhs, sizeof(Storage)); + ::memcpy(&rhs, &tempStorage, sizeof(Storage)); + } + private: + ShortStringData m_shortData{}; + AllocatedStringData m_allocatedData; + PointerAlignedData m_pointerData; + }; + + AZStd::compressed_pair m_storage; + +#if defined(HAVE_BENCHMARK) + friend class Benchmark::StringBenchmarkFixture; +#endif #ifdef AZSTD_HAS_CHECKED_ITERATORS void orphan_range(pointer first, pointer last) const @@ -1809,18 +1873,7 @@ namespace AZStd }; template - const typename basic_string::size_type basic_string::npos; - - // basic_string implements a performant swap - /*template - class move_operation_category > - { - public: - typedef swap_move_tag move_cat; - };*/ - - template - inline void swap(basic_string& left, basic_string& right) + inline void swap(basic_string& left, basic_string& right) { left.swap(right); } @@ -2027,6 +2080,3 @@ namespace AZStd }; } // namespace AZStd - -#endif // AZSTD_STRING_H -#pragma once diff --git a/Code/Framework/AzCore/AzCore/std/string/string_view.h b/Code/Framework/AzCore/AzCore/std/string/string_view.h index 30e61f95ce..841044dd16 100644 --- a/Code/Framework/AzCore/AzCore/std/string/string_view.h +++ b/Code/Framework/AzCore/AzCore/std/string/string_view.h @@ -280,18 +280,36 @@ namespace AZStd static constexpr char_type* assign(char_type* dest, size_t count, char_type ch) noexcept { AZ_Assert(dest, "Invalid input!"); - for (char_type* iter = dest; count; --count, ++iter) + + if constexpr (AZStd::is_same_v) { - assign(*iter, ch); + // Use builtin_memset if available for char type + if (az_builtin_is_constant_evaluated()) + { + for (char_type* iter = dest; count; --count, ++iter) + { + assign(*iter, ch); + } + } + else + { + ::memset(dest, ch, count); + } } + else + { + for (char_type* iter = dest; count; --count, ++iter) + { + assign(*iter, ch); + } + } + return dest; } static constexpr bool eq(char_type left, char_type right) noexcept { return left == right; } static constexpr bool lt(char_type left, char_type right) noexcept { return left < right; } static constexpr int compare(const char_type* s1, const char_type* s2, size_t count) noexcept { - // Regression in VS2017 15.8 and 15.9 where __builtin_memcmp fails in valid checks in constexpr evaluation -#if !defined(AZ_COMPILER_MSVC) || AZ_COMPILER_MSVC < 1915 || AZ_COMPILER_MSVC > 1916 if constexpr (AZStd::is_same_v) { return __builtin_memcmp(s1, s2, count); @@ -301,7 +319,6 @@ namespace AZStd return __builtin_wmemcmp(s1, s2, count); } else -#endif { for (; count; --count, ++s1, ++s2) { @@ -339,10 +356,6 @@ namespace AZStd } static constexpr const char_type* find(const char_type* s, size_t count, const char_type& ch) noexcept { - // There is a bug with the __builtin_char_memchr intrinsic in Visual Studio 2017 15.8.x and 15.9.x - // It reads in one more additional character than the value of count. - // This is probably due to assuming null-termination -#if !defined(AZ_COMPILER_MSVC) || AZ_COMPILER_MSVC < 1915 || AZ_COMPILER_MSVC > 1916 if constexpr (AZStd::is_same_v) { return __builtin_char_memchr(s, ch, count); @@ -353,7 +366,6 @@ namespace AZStd } else -#endif { for (; count; --count, ++s) { @@ -368,64 +380,112 @@ namespace AZStd static constexpr char_type* move(char_type* dest, const char_type* src, size_t count) noexcept { AZ_Assert(dest != nullptr && src != nullptr, "Invalid input!"); - if (count == 0) + if (count == 0 || src == dest) { return dest; } - char_type* result = dest; - // The less than(<), greater than(>) and other variants(<=, >=) - // Cannot be compare pointers within a constexpr due to the potential for undefined behavior - // per the bullet linked in the C++ standard at http://eel.is/c++draft/expr.compound#expr.rel-5 - // Now clang and gcc compilers allow the use of this relation operators in a constexpr, but - // msvc is not so forgiving - // So a workaround of iterating the src pointer, checking for equality with the dest pointer - // is used to check for overlap - auto should_copy_forward = [](const char_type* dest1, const char_type* src2, size_t count2) constexpr -> bool + + #if az_has_builtin_memmove + __builtin_memmove(dest, src, count * sizeof(char_type)); + #else + auto NonBuiltinMove = [](char_type* dest1, const char_type* src1, size_t count1) constexpr + -> char_type* { - bool dest_less_than_src{ true }; - for(const char_type* src_iter = src2; src_iter != src2 + count2; ++src_iter) + if (az_builtin_is_constant_evaluated()) { - if (src_iter == dest1) + // The less than(<), greater than(>) and other variants(<=, >=) + // Cannot be compare pointers within a constexpr due to the potential for undefined behavior + // per the bullet linked in the C++ standard at http://eel.is/c++draft/expr.compound#expr.rel-5 + // Now clang and gcc compilers allow the use of this relation operators in a constexpr, but + // msvc is not so forgiving + // So a workaround of iterating the src pointer, checking for equality with the dest pointer + // is used to check for overlap + auto should_copy_forward = [](const char_type* dest2, const char_type* src2, size_t count2) constexpr -> bool { - dest_less_than_src = false; - break; + bool dest_less_than_src{ true }; + for (const char_type* src_iter = src2; src_iter != src2 + count2; ++src_iter) + { + if (src_iter == dest2) + { + dest_less_than_src = false; + break; + } + } + return dest_less_than_src; + }; + + if (should_copy_forward(dest1, src1, count1)) + { + copy(dest1, src1, count1); + } + else + { + copy_backward(dest1, src1, count1); } } - return dest_less_than_src; + else + { + // Use the faster ::memmove operation at runtime + ::memmove(dest1, src1, count1 * sizeof(char_type)); + } + + return dest1; }; + NonBuiltinMove(dest, src, count); + #endif - if (should_copy_forward(dest, src, count)) - { - copy(dest, src, count); - } - else - { - copy_backward(dest, src, count); - } - - return result; + return dest; } static constexpr char_type* copy(char_type* dest, const char_type* src, size_t count) noexcept { AZ_Assert(dest != nullptr && src != nullptr, "Invalid input!"); - char_type* result = dest; - for(; count; --count, ++dest, ++src) + + #if az_has_builtin_memcpy + __builtin_memcpy(dest, src, count * sizeof(char_type)); + #else + auto NonBuiltinCopy = [](char_type* dest1, const char_type* src1, size_t count1) constexpr + -> char_type* { - assign(*dest, *src); - } - return result; + if (az_builtin_is_constant_evaluated()) + { + for (; count1; --count1, ++dest1, ++src1) + { + assign(*dest1, *src1); + } + } + else + { + ::memcpy(dest1, src1, count1 * sizeof(char_type)); + } + return dest1; + }; + NonBuiltinCopy(dest, src, count); + #endif + + return dest; } // Extension for constexpr workarounds: Addresses of a string literal cannot be compared at compile time and MSVC and clang will just refuse to compile the constexpr // Adding a copy_backwards overload that always copies backwards. - static constexpr char_type* copy_backward(char_type* dest, const char_type*src, size_t count) noexcept + static constexpr char_type* copy_backward(char_type* dest, const char_type* src, size_t count) noexcept { char_type* result = dest; - dest += count; - src += count; - for (; count; --count) + #if az_has_builtin_memmove + __builtin_memmove(dest, src, count * sizeof(char_type)); + #else + if (az_builtin_is_constant_evaluated()) { - assign(*--dest, *--src); + dest += count; + src += count; + for (; count; --count) + { + assign(*--dest, *--src); + } } + else + { + ::memmove(dest, src, count); + } + #endif return result; } diff --git a/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/azcore.natvis b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/azcore.natvis index 3730b8a4f9..dca82e2439 100644 --- a/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/azcore.natvis +++ b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/azcore.natvis @@ -10,6 +10,13 @@ + + {m_element} + + + {$T1} is empty + + reverse_iterator base() {m_current} @@ -388,35 +395,41 @@ - - {m_buffer,s} - {m_data,s} - m_buffer,s - m_data,s + + {((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer,s} + {((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data,s} + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer,s + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data,s - m_size - m_capacity + (size_t)((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.Capacity + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_capacity - m_size - m_buffer - m_data + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_size,u + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer + ((AZStd::compressed_pair_element<AZStd::basic_string<char,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data - {m_buffer,su} - {m_data,su} - m_buffer,su - m_data,su + {((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer,su} + {((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data,su} + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer,su + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data,su - m_size - m_capacity + (size_t)((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.Capacity + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_capacity - m_size - m_buffer - m_data + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_size,u + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_size + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_shortData.m_buffer + ((AZStd::compressed_pair_element<AZStd::basic_string<wchar_t,$T1,$T2>::Storage,0,0>&)m_storage).m_element.m_allocatedData.m_data diff --git a/Code/Framework/AzCore/Tests/AZStd/String.cpp b/Code/Framework/AzCore/Tests/AZStd/String.cpp index 356310a94d..0f84ad0970 100644 --- a/Code/Framework/AzCore/Tests/AZStd/String.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/String.cpp @@ -8,11 +8,11 @@ #include "UserTypes.h" #include -#include #include #include #include #include +#include #include #include #include @@ -21,13 +21,10 @@ #include // we need this for AZ_TEST_FLOAT compare -#include #include #include #include -using namespace AZStd; - // Because of the SSO (small string optimization) we always shoule have capacity != 0 and data != 0 #define AZ_TEST_VALIDATE_EMPTY_STRING(_String) \ EXPECT_TRUE(_String.validate()); \ @@ -81,8 +78,6 @@ namespace UnitTest va_end(mark); } -#if !AZ_UNIT_TEST_SKIP_STD_STRING_TESTS - TEST(StringC, VSNPrintf) { char buffer32[32]; @@ -168,75 +163,75 @@ namespace UnitTest { const char* sChar = "SSO string"; // 10 characters const char* sCharLong = "This is a long string test that will allocate"; // 45 characters - array aChar = { + AZStd::array aChar = { { 'a', 'b', 'c', 'd', 'e', 'f' } }; // short string (should use SSO) - string str1; + AZStd::string str1; AZ_TEST_VALIDATE_EMPTY_STRING(str1); // short char* - string str2(sChar); + AZStd::string str2(sChar); AZ_TEST_VALIDATE_STRING(str2, 10); - string str2_1(""); + AZStd::string str2_1(""); AZ_TEST_VALIDATE_EMPTY_STRING(str2_1); - string str3(sChar, 5); + AZStd::string str3(sChar, 5); AZ_TEST_VALIDATE_STRING(str3, 5); // long char* - string str4(sCharLong); + AZStd::string str4(sCharLong); AZ_TEST_VALIDATE_STRING(str4, 45); - string str5(sCharLong, 35); + AZStd::string str5(sCharLong, 35); AZ_TEST_VALIDATE_STRING(str5, 35); // element - string str6(13, 'a'); + AZStd::string str6(13, 'a'); AZ_TEST_VALIDATE_STRING(str6, 13); - string str6_1(0, 'a'); + AZStd::string str6_1(0, 'a'); AZ_TEST_VALIDATE_EMPTY_STRING(str6_1); - string str7(aChar.begin(), aChar.end()); + AZStd::string str7(aChar.begin(), aChar.end()); AZ_TEST_VALIDATE_STRING(str7, 6); - string str7_1(aChar.begin(), aChar.begin()); + AZStd::string str7_1(aChar.begin(), aChar.begin()); AZ_TEST_VALIDATE_EMPTY_STRING(str7_1); - string str8(sChar, sChar + 3); + AZStd::string str8(sChar, sChar + 3); AZ_TEST_VALIDATE_STRING(str8, 3); - string str8_1(sChar, sChar); + AZStd::string str8_1(sChar, sChar); AZ_TEST_VALIDATE_EMPTY_STRING(str8_1); // - string str9(str2); + AZStd::string str9(str2); AZ_TEST_VALIDATE_STRING(str9, 10); - string str9_1(str1); + AZStd::string str9_1(str1); AZ_TEST_VALIDATE_EMPTY_STRING(str9_1); - string str10(str2, 4); + AZStd::string str10(str2, 4); AZ_TEST_VALIDATE_STRING(str10, 6); - string str11(str2, 4, 3); + AZStd::string str11(str2, 4, 3); AZ_TEST_VALIDATE_STRING(str11, 3); - string str12(sChar); - string large = sCharLong; + AZStd::string str12(sChar); + AZStd::string large = sCharLong; // move ctor - string strSm = AZStd::move(str12); + AZStd::string strSm = AZStd::move(str12); AZ_TEST_VALIDATE_STRING(strSm, 10); AZ_TEST_VALIDATE_EMPTY_STRING(str12); - string strLg(AZStd::move(large)); + AZStd::string strLg(AZStd::move(large)); AZ_TEST_VALIDATE_STRING(strLg, 45); AZ_TEST_VALIDATE_EMPTY_STRING(large); - string strEmpty(AZStd::move(str1)); + AZStd::string strEmpty(AZStd::move(str1)); AZ_TEST_VALIDATE_EMPTY_STRING(strEmpty); AZ_TEST_VALIDATE_EMPTY_STRING(str1); @@ -369,7 +364,7 @@ namespace UnitTest AZ_TEST_VALIDATE_STRING(str2, 28); AZ_TEST_ASSERT(str2[0] == 'b'); - str2.erase(str2.begin(), next(str2.begin(), 4)); + str2.erase(str2.begin(), AZStd::next(str2.begin(), 4)); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'f'); @@ -400,33 +395,33 @@ namespace UnitTest AZ_TEST_ASSERT(str2[3] == 'g'); AZ_TEST_ASSERT(str2[4] == 'g'); - str2.replace(str2.begin(), next(str2.begin(), str1.length()), str1); + str2.replace(str2.begin(), AZStd::next(str2.begin(), str1.length()), str1); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'a'); AZ_TEST_ASSERT(str2[1] == 'b'); - str2.replace(str2.begin(), next(str2.begin(), 10), sChar); + str2.replace(str2.begin(), AZStd::next(str2.begin(), 10), sChar); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'S'); AZ_TEST_ASSERT(str2[1] == 'S'); - str2.replace(str2.begin(), next(str2.begin(), 3), sChar, 3); + str2.replace(str2.begin(), AZStd::next(str2.begin(), 3), sChar, 3); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'S'); AZ_TEST_ASSERT(str2[1] == 'S'); AZ_TEST_ASSERT(str2[2] == 'O'); - str2.replace(str2.begin(), next(str2.begin(), 2), 2, 'h'); + str2.replace(str2.begin(), AZStd::next(str2.begin(), 2), 2, 'h'); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'h'); AZ_TEST_ASSERT(str2[1] == 'h'); - str2.replace(str2.begin(), next(str2.begin(), 2), aChar.begin(), next(aChar.begin(), 2)); + str2.replace(str2.begin(), AZStd::next(str2.begin(), 2), aChar.begin(), AZStd::next(aChar.begin(), 2)); AZ_TEST_VALIDATE_STRING(str2, 24); AZ_TEST_ASSERT(str2[0] == 'a'); AZ_TEST_ASSERT(str2[1] == 'b'); - str2.replace(str2.begin(), next(str2.begin(), 2), sChar, sChar + 5); + str2.replace(str2.begin(), AZStd::next(str2.begin(), 2), sChar, sChar + 5); AZ_TEST_VALIDATE_STRING(str2, 27); AZ_TEST_ASSERT(str2[0] == 'S'); AZ_TEST_ASSERT(str2[1] == 'S'); @@ -489,7 +484,7 @@ namespace UnitTest AZ_TEST_ASSERT(pos == 2); pos = str1.find('Z'); - AZ_TEST_ASSERT(pos == string::npos); + AZ_TEST_ASSERT(pos == AZStd::string::npos); pos = str1.rfind(str2); AZ_TEST_ASSERT(pos == 12); @@ -510,7 +505,7 @@ namespace UnitTest AZ_TEST_ASSERT(pos == 12); pos = str1.rfind('Z'); - AZ_TEST_ASSERT(pos == string::npos); + AZ_TEST_ASSERT(pos == AZStd::string::npos); pos = str1.find_first_of(str2); AZ_TEST_ASSERT(pos == 2); @@ -535,7 +530,7 @@ namespace UnitTest AZ_TEST_ASSERT(pos == 12); pos = str1.find_first_of('Z'); - AZ_TEST_ASSERT(pos == string::npos); + AZ_TEST_ASSERT(pos == AZStd::string::npos); pos = str1.find_last_of(str2); AZ_TEST_ASSERT(pos == 14); @@ -550,7 +545,7 @@ namespace UnitTest AZ_TEST_ASSERT(pos == 12); pos = str1.find_last_of('Z'); - AZ_TEST_ASSERT(pos == string::npos); + AZ_TEST_ASSERT(pos == AZStd::string::npos); pos = str1.find_first_not_of(str2, 3); AZ_TEST_ASSERT(pos == 5); @@ -559,13 +554,13 @@ namespace UnitTest AZ_TEST_ASSERT(pos == 0); pos = str1.find_last_not_of(sChar); - AZ_TEST_ASSERT(pos == string::npos); + AZ_TEST_ASSERT(pos == AZStd::string::npos); pos = str1.find_last_not_of('Z'); AZ_TEST_ASSERT(pos == 19); - string sub = str1.substr(0, 10); + AZStd::string sub = str1.substr(0, 10); AZ_TEST_VALIDATE_STRING(sub, 10); AZ_TEST_ASSERT(sub[0] == 'S'); AZ_TEST_ASSERT(sub[9] == 'g'); @@ -594,13 +589,13 @@ namespace UnitTest using iteratorType = char; auto testValue = str4; - reverse_iterator rend = testValue.rend(); - reverse_iterator crend1 = testValue.rend(); - reverse_iterator crend2 = testValue.crend(); + AZStd::reverse_iterator rend = testValue.rend(); + AZStd::reverse_iterator crend1 = testValue.rend(); + AZStd::reverse_iterator crend2 = testValue.crend(); - reverse_iterator rbegin = testValue.rbegin(); - reverse_iterator crbegin1 = testValue.rbegin(); - reverse_iterator crbegin2 = testValue.crbegin(); + AZStd::reverse_iterator rbegin = testValue.rbegin(); + AZStd::reverse_iterator crbegin1 = testValue.rbegin(); + AZStd::reverse_iterator crbegin2 = testValue.crbegin(); AZ_TEST_ASSERT(rend == crend1); AZ_TEST_ASSERT(crend1 == crend2); @@ -630,128 +625,128 @@ namespace UnitTest TEST_F(String, Algorithms) { - string str = string::format("%s %d", "BlaBla", 5); + AZStd::string str = AZStd::string::format("%s %d", "BlaBla", 5); AZ_TEST_VALIDATE_STRING(str, 8); - wstring wstr = wstring::format(L"%ls %d", L"BlaBla", 5); + AZStd::wstring wstr = AZStd::wstring::format(L"%ls %d", L"BlaBla", 5); AZ_TEST_VALIDATE_WSTRING(wstr, 8); - to_lower(str.begin(), str.end()); + AZStd::to_lower(str.begin(), str.end()); AZ_TEST_ASSERT(str[0] == 'b'); AZ_TEST_ASSERT(str[3] == 'b'); - to_upper(str.begin(), str.end()); + AZStd::to_upper(str.begin(), str.end()); AZ_TEST_ASSERT(str[1] == 'L'); AZ_TEST_ASSERT(str[2] == 'A'); - string intStr("10"); + AZStd::string intStr("10"); int ival = AZStd::stoi(intStr); AZ_TEST_ASSERT(ival == 10); - wstring wintStr(L"10"); + AZStd::wstring wintStr(L"10"); ival = AZStd::stoi(wintStr); AZ_TEST_ASSERT(ival == 10); - string floatStr("2.32"); + AZStd::string floatStr("2.32"); float fval = AZStd::stof(floatStr); AZ_TEST_ASSERT_FLOAT_CLOSE(fval, 2.32f); - wstring wfloatStr(L"2.32"); + AZStd::wstring wfloatStr(L"2.32"); fval = AZStd::stof(wfloatStr); AZ_TEST_ASSERT_FLOAT_CLOSE(fval, 2.32f); - to_string(intStr, 20); + AZStd::to_string(intStr, 20); AZ_TEST_ASSERT(intStr == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); - AZ_TEST_ASSERT(to_string(static_cast(20)) == "20"); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); + EXPECT_EQ("20", AZStd::to_string(static_cast(20))); // wstring to string - string str1; - to_string(str1, wstr); + AZStd::string str1; + AZStd::to_string(str1, wstr); AZ_TEST_ASSERT(str1 == "BlaBla 5"); EXPECT_EQ(8, to_string_length(wstr)); - str1 = string::format("%ls", wstr.c_str()); + str1 = AZStd::string::format("%ls", wstr.c_str()); AZ_TEST_ASSERT(str1 == "BlaBla 5"); // string to wstring - wstring wstr1; - to_wstring(wstr1, str); + AZStd::wstring wstr1; + AZStd::to_wstring(wstr1, str); AZ_TEST_ASSERT(wstr1 == L"BLABLA 5"); - wstr1 = wstring::format(L"%hs", str.c_str()); + wstr1 = AZStd::wstring::format(L"%hs", str.c_str()); AZ_TEST_ASSERT(wstr1 == L"BLABLA 5"); // wstring to char buffer char strBuffer[9]; - to_string(strBuffer, 9, wstr1.c_str()); + AZStd::to_string(strBuffer, 9, wstr1.c_str()); AZ_TEST_ASSERT(0 == azstricmp(strBuffer, "BLABLA 5")); EXPECT_EQ(8, to_string_length(wstr1)); // wstring to char with unicode - wstring ws1InfinityEscaped = L"Infinity: \u221E"; // escaped + AZStd::wstring ws1InfinityEscaped = L"Infinity: \u221E"; // escaped EXPECT_EQ(13, to_string_length(ws1InfinityEscaped)); // wchar_t buffer to char buffer wchar_t wstrBuffer[9] = L"BLABLA 5"; memset(strBuffer, 0, AZ_ARRAY_SIZE(strBuffer)); - to_string(strBuffer, 9, wstrBuffer); + AZStd::to_string(strBuffer, 9, wstrBuffer); AZ_TEST_ASSERT(0 == azstricmp(strBuffer, "BLABLA 5")); // string to wchar_t buffer memset(wstrBuffer, 0, AZ_ARRAY_SIZE(wstrBuffer)); - to_wstring(wstrBuffer, 9, str1.c_str()); + AZStd::to_wstring(wstrBuffer, 9, str1.c_str()); AZ_TEST_ASSERT(0 == azwcsicmp(wstrBuffer, L"BlaBla 5")); // char buffer to wchar_t buffer memset(wstrBuffer, L' ', AZ_ARRAY_SIZE(wstrBuffer)); // to check that the null terminator is properly placed - to_wstring(wstrBuffer, 9, strBuffer); + AZStd::to_wstring(wstrBuffer, 9, strBuffer); AZ_TEST_ASSERT(0 == azwcsicmp(wstrBuffer, L"BLABLA 5")); // wchar UTF16/UTF32 to/from Utf8 wstr1 = L"this is a \u20AC \u00A3 test"; // that's a euro and a pound sterling AZStd::to_string(str, wstr1); - wstring wstr2; + AZStd::wstring wstr2; AZStd::to_wstring(wstr2, str); AZ_TEST_ASSERT(wstr1 == wstr2); // tokenize - vector tokens; - tokenize(string("one, two, three"), string(", "), tokens); + AZStd::vector tokens; + AZStd::tokenize(AZStd::string("one, two, three"), AZStd::string(", "), tokens); AZ_TEST_ASSERT(tokens.size() == 3); AZ_TEST_ASSERT(tokens[0] == "one"); AZ_TEST_ASSERT(tokens[1] == "two"); AZ_TEST_ASSERT(tokens[2] == "three"); - tokenize(string("one, ,, two, ,, three"), string(", "), tokens); + AZStd::tokenize(AZStd::string("one, ,, two, ,, three"), AZStd::string(", "), tokens); AZ_TEST_ASSERT(tokens.size() == 3); AZ_TEST_ASSERT(tokens[0] == "one"); AZ_TEST_ASSERT(tokens[1] == "two"); AZ_TEST_ASSERT(tokens[2] == "three"); - tokenize(string("thequickbrownfox"), string("ABC"), tokens); + AZStd::tokenize(AZStd::string("thequickbrownfox"), AZStd::string("ABC"), tokens); AZ_TEST_ASSERT(tokens.size() == 1); AZ_TEST_ASSERT(tokens[0] == "thequickbrownfox"); - tokenize(string(""), string(""), tokens); + AZStd::tokenize(AZStd::string{}, AZStd::string{}, tokens); AZ_TEST_ASSERT(tokens.empty()); - tokenize(string("ABC"), string("ABC"), tokens); + AZStd::tokenize(AZStd::string("ABC"), AZStd::string("ABC"), tokens); AZ_TEST_ASSERT(tokens.empty()); - tokenize(string(" foo bar "), string(" "), tokens); + AZStd::tokenize(AZStd::string(" foo bar "), AZStd::string(" "), tokens); AZ_TEST_ASSERT(tokens.size() == 2); AZ_TEST_ASSERT(tokens[0] == "foo"); AZ_TEST_ASSERT(tokens[1] == "bar"); - tokenize_keep_empty(string(" foo , bar "), string(","), tokens); + AZStd::tokenize_keep_empty(AZStd::string(" foo , bar "), AZStd::string(","), tokens); AZ_TEST_ASSERT(tokens.size() == 2); AZ_TEST_ASSERT(tokens[0] == " foo "); AZ_TEST_ASSERT(tokens[1] == " bar "); // Sort - AZStd::vector toSort; + AZStd::vector toSort; toSort.push_back("z2"); toSort.push_back("z100"); toSort.push_back("z1"); @@ -761,39 +756,39 @@ namespace UnitTest AZ_TEST_ASSERT(toSort[2] == "z2"); // Natural sort - AZ_TEST_ASSERT(alphanum_comp("", "") == 0); - AZ_TEST_ASSERT(alphanum_comp("", "a") < 0); - AZ_TEST_ASSERT(alphanum_comp("a", "") > 0); - AZ_TEST_ASSERT(alphanum_comp("a", "a") == 0); - AZ_TEST_ASSERT(alphanum_comp("", "9") < 0); - AZ_TEST_ASSERT(alphanum_comp("9", "") > 0); - AZ_TEST_ASSERT(alphanum_comp("1", "1") == 0); - AZ_TEST_ASSERT(alphanum_comp("1", "2") < 0); - AZ_TEST_ASSERT(alphanum_comp("3", "2") > 0); - AZ_TEST_ASSERT(alphanum_comp("a1", "a1") == 0); - AZ_TEST_ASSERT(alphanum_comp("a1", "a2") < 0); - AZ_TEST_ASSERT(alphanum_comp("a2", "a1") > 0); - AZ_TEST_ASSERT(alphanum_comp("a1a2", "a1a3") < 0); - AZ_TEST_ASSERT(alphanum_comp("a1a2", "a1a0") > 0); - AZ_TEST_ASSERT(alphanum_comp("134", "122") > 0); - AZ_TEST_ASSERT(alphanum_comp("12a3", "12a3") == 0); - AZ_TEST_ASSERT(alphanum_comp("12a1", "12a0") > 0); - AZ_TEST_ASSERT(alphanum_comp("12a1", "12a2") < 0); - AZ_TEST_ASSERT(alphanum_comp("a", "aa") < 0); - AZ_TEST_ASSERT(alphanum_comp("aaa", "aa") > 0); - AZ_TEST_ASSERT(alphanum_comp("Alpha 2", "Alpha 2") == 0); - AZ_TEST_ASSERT(alphanum_comp("Alpha 2", "Alpha 2A") < 0); - AZ_TEST_ASSERT(alphanum_comp("Alpha 2 B", "Alpha 2") > 0); - string strA("Alpha 2"); - AZ_TEST_ASSERT(alphanum_comp(strA, "Alpha 2") == 0); - AZ_TEST_ASSERT(alphanum_comp(strA, "Alpha 2A") < 0); - AZ_TEST_ASSERT(alphanum_comp("Alpha 2 B", strA) > 0); - AZ_TEST_ASSERT(alphanum_comp(strA, strdup("Alpha 2")) == 0); - AZ_TEST_ASSERT(alphanum_comp(strA, strdup("Alpha 2A")) < 0); - AZ_TEST_ASSERT(alphanum_comp(strdup("Alpha 2 B"), strA) > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("", "") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("", "a") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a", "") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a", "a") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("", "9") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("9", "") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("1", "1") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("1", "2") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("3", "2") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a1", "a1") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a1", "a2") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a2", "a1") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a1a2", "a1a3") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a1a2", "a1a0") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("134", "122") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("12a3", "12a3") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("12a1", "12a0") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("12a1", "12a2") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("a", "aa") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("aaa", "aa") > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("Alpha 2", "Alpha 2") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("Alpha 2", "Alpha 2A") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("Alpha 2 B", "Alpha 2") > 0); + AZStd::string strA("Alpha 2"); + AZ_TEST_ASSERT(AZStd::alphanum_comp(strA, "Alpha 2") == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp(strA, "Alpha 2A") < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp("Alpha 2 B", strA) > 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp(strA, strdup("Alpha 2")) == 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp(strA, strdup("Alpha 2A")) < 0); + AZ_TEST_ASSERT(AZStd::alphanum_comp(strdup("Alpha 2 B"), strA) > 0); // show usage of the comparison functor with a set - using StringSetType = set>; + using StringSetType = AZStd::set>; StringSetType s; s.insert("Xiph Xlater 58"); s.insert("Xiph Xlater 5000"); @@ -879,7 +874,7 @@ namespace UnitTest AZ_TEST_ASSERT(*setIt++ == "Xiph Xlater 10000"); // show usage of comparison functor with a map - using StringIntMapType = map>; + using StringIntMapType = AZStd::map>; StringIntMapType m; m["z1.doc"] = 1; m["z10.doc"] = 2; @@ -931,13 +926,13 @@ namespace UnitTest AZ_TEST_ASSERT((mapIt++)->second == 5); // show usage of comparison functor with an STL algorithm on a vector - vector v; + AZStd::vector v; // vector contents are reversed sorted contents of the old set - AZStd::copy(s.rbegin(), s.rend(), back_inserter(v)); + AZStd::copy(s.rbegin(), s.rend(), AZStd::back_inserter(v)); // now sort the vector with the algorithm - AZStd::sort(v.begin(), v.end(), alphanum_less()); + AZStd::sort(v.begin(), v.end(), AZStd::alphanum_less()); // check values - vector::const_iterator vecIt = v.begin(); + AZStd::vector::const_iterator vecIt = v.begin(); AZ_TEST_ASSERT(*vecIt++ == "10X Radonius"); AZ_TEST_ASSERT(*vecIt++ == "20X Radonius"); AZ_TEST_ASSERT(*vecIt++ == "20X Radonius Prime"); @@ -988,52 +983,52 @@ namespace UnitTest TEST_F(Regex, Regex_IPAddressSubnetPattern_Success) { // Error case for LY-43888 - regex txt_regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(/([0-9]|[1-2][0-9]|3[0-2]))?$"); - string sample_input("10.85.22.92/24"); - bool match = regex_match(sample_input, txt_regex); + AZStd::regex txt_regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(/([0-9]|[1-2][0-9]|3[0-2]))?$"); + AZStd::string sample_input("10.85.22.92/24"); + bool match = AZStd::regex_match(sample_input, txt_regex); AZ_TEST_ASSERT(match); } TEST_F(Regex, MatchConstChar) { //regex - AZ_TEST_ASSERT(regex_match("subject", regex("(sub)(.*)"))); + AZ_TEST_ASSERT(AZStd::regex_match("subject", AZStd::regex("(sub)(.*)"))); } TEST_F(Regex, MatchString) { - string reStr("subject"); - regex re("(sub)(.*)"); - AZ_TEST_ASSERT(regex_match(reStr, re)); - AZ_TEST_ASSERT(regex_match(reStr.begin(), reStr.end(), re)) + AZStd::string reStr("subject"); + AZStd::regex re("(sub)(.*)"); + AZ_TEST_ASSERT(AZStd::regex_match(reStr, re)); + AZ_TEST_ASSERT(AZStd::regex_match(reStr.begin(), reStr.end(), re)) } TEST_F(Regex, CMatch) { - regex re("(sub)(.*)"); - cmatch cm; // same as match_results cm; - regex_match("subject", cm, re); + AZStd::regex re("(sub)(.*)"); + AZStd::cmatch cm; // same as match_results cm; + AZStd::regex_match("subject", cm, re); AZ_TEST_ASSERT(cm.size() == 3); } TEST_F(Regex, SMatch) { - string reStr("subject"); - regex re("(sub)(.*)"); - smatch sm; // same as std::match_results sm; - regex_match(reStr, sm, re); + AZStd::string reStr("subject"); + AZStd::regex re("(sub)(.*)"); + AZStd::smatch sm; // same as std::match_results sm; + AZStd::regex_match(reStr, sm, re); AZ_TEST_ASSERT(sm.size() == 3); - regex_match(reStr.cbegin(), reStr.cend(), sm, re); + AZStd::regex_match(reStr.cbegin(), reStr.cend(), sm, re); AZ_TEST_ASSERT(sm.size() == 3); } TEST_F(Regex, CMatchWithFlags) { - regex re("(sub)(.*)"); - cmatch cm; // same as match_results cm; + AZStd::regex re("(sub)(.*)"); + AZStd::cmatch cm; // same as match_results cm; // using explicit flags: - regex_match("subject", cm, re, regex_constants::match_default); + AZStd::regex_match("subject", cm, re, AZStd::regex_constants::match_default); AZ_TEST_ASSERT(cm[0] == "subject"); AZ_TEST_ASSERT(cm[1] == "sub"); AZ_TEST_ASSERT(cm[2] == "ject"); @@ -1042,18 +1037,18 @@ namespace UnitTest TEST_F(Regex, PatternMatchFiles) { // Simple regular expression matching - string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; - regex txt_regex("[a-z]+\\.txt"); + AZStd::string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; + AZStd::regex txt_regex("[a-z]+\\.txt"); for (size_t i = 0; i < AZ_ARRAY_SIZE(fnames); ++i) { if (i < 2) { - AZ_TEST_ASSERT(regex_match(fnames[i], txt_regex) == true); + AZ_TEST_ASSERT(AZStd::regex_match(fnames[i], txt_regex) == true); } else { - AZ_TEST_ASSERT(regex_match(fnames[i], txt_regex) == false); + AZ_TEST_ASSERT(AZStd::regex_match(fnames[i], txt_regex) == false); } } } @@ -1061,13 +1056,13 @@ namespace UnitTest TEST_F(Regex, PatternWithSingleCaptureGroup) { // Extraction of a sub-match - string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; - regex base_regex("([a-z]+)\\.txt"); - smatch base_match; + AZStd::string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; + AZStd::regex base_regex("([a-z]+)\\.txt"); + AZStd::smatch base_match; for (size_t i = 0; i < AZ_ARRAY_SIZE(fnames); ++i) { - if (regex_match(fnames[i], base_match, base_regex)) + if (AZStd::regex_match(fnames[i], base_match, base_regex)) { AZ_TEST_ASSERT(base_match.size() == 2); AZ_TEST_ASSERT(base_match[1] == "foo" || base_match[1] == "bar") @@ -1078,12 +1073,12 @@ namespace UnitTest TEST_F(Regex, PatternWithMultipleCaptureGroups) { // Extraction of several sub-matches - string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; - regex pieces_regex("([a-z]+)\\.([a-z]+)"); - smatch pieces_match; + AZStd::string fnames[] = { "foo.txt", "bar.txt", "baz.dat", "zoidberg" }; + AZStd::regex pieces_regex("([a-z]+)\\.([a-z]+)"); + AZStd::smatch pieces_match; for (size_t i = 0; i < AZ_ARRAY_SIZE(fnames); ++i) { - if (regex_match(fnames[i], pieces_match, pieces_regex)) + if (AZStd::regex_match(fnames[i], pieces_match, pieces_regex)) { AZ_TEST_ASSERT(pieces_match.size() == 3); AZ_TEST_ASSERT(pieces_match[0] == "foo.txt" || pieces_match[0] == "bar.txt" || pieces_match[0] == "baz.dat"); @@ -1096,40 +1091,40 @@ namespace UnitTest TEST_F(Regex, WideCharTests) { //wchar_t - AZ_TEST_ASSERT(regex_match(L"subject", wregex(L"(sub)(.*)"))); - wstring reWStr(L"subject"); - wregex reW(L"(sub)(.*)"); - AZ_TEST_ASSERT(regex_match(reWStr, reW)); - AZ_TEST_ASSERT(regex_match(reWStr.begin(), reWStr.end(), reW)) + AZ_TEST_ASSERT(AZStd::regex_match(L"subject", AZStd::wregex(L"(sub)(.*)"))); + AZStd::wstring reWStr(L"subject"); + AZStd::wregex reW(L"(sub)(.*)"); + AZ_TEST_ASSERT(AZStd::regex_match(reWStr, reW)); + AZ_TEST_ASSERT(AZStd::regex_match(reWStr.begin(), reWStr.end(), reW)) } TEST_F(Regex, LongPatterns) { // test construction and destruction of a regex with a pattern long enough to require reallocation of buffers - regex longerThan16(".*\\/Presets\\/GeomCache\\/.*", regex::flag_type::icase | regex::flag_type::ECMAScript); - regex longerThan32(".*\\/Presets\\/GeomCache\\/Whatever\\/Much\\/Test\\/Very\\/Memory\\/.*", regex::flag_type::icase); + AZStd::regex longerThan16(".*\\/Presets\\/GeomCache\\/.*", AZStd::regex::flag_type::icase | AZStd::regex::flag_type::ECMAScript); + AZStd::regex longerThan32(".*\\/Presets\\/GeomCache\\/Whatever\\/Much\\/Test\\/Very\\/Memory\\/.*", AZStd::regex::flag_type::icase); } TEST_F(Regex, SmileyFaceParseRegression) { - regex smiley(":)"); + AZStd::regex smiley(":)"); EXPECT_TRUE(smiley.Empty()); EXPECT_TRUE(smiley.GetError() != nullptr); - EXPECT_FALSE(regex_match("wut", smiley)); - EXPECT_FALSE(regex_match(":)", smiley)); + EXPECT_FALSE(AZStd::regex_match("wut", smiley)); + EXPECT_FALSE(AZStd::regex_match(":)", smiley)); } TEST_F(Regex, ParseFailure) { - regex failed(")))/?!\\$"); + AZStd::regex failed(")))/?!\\$"); EXPECT_FALSE(failed.Valid()); - regex other = AZStd::move(failed); + AZStd::regex other = AZStd::move(failed); EXPECT_FALSE(other.Valid()); - regex other2; + AZStd::regex other2; other2.swap(other); EXPECT_TRUE(other.Empty()); EXPECT_TRUE(other.GetError() == nullptr); @@ -1139,69 +1134,69 @@ namespace UnitTest TEST_F(String, ConstString) { - string_view cstr1; - AZ_TEST_ASSERT(cstr1.data()==nullptr); - AZ_TEST_ASSERT(cstr1.size() == 0); - AZ_TEST_ASSERT(cstr1.length() == 0); - AZ_TEST_ASSERT(cstr1.begin() == cstr1.end()); - AZ_TEST_ASSERT(cstr1 == string_view()); - AZ_TEST_ASSERT(cstr1.empty()); + AZStd::string_view cstr1; + EXPECT_EQ(nullptr, cstr1.data()); + EXPECT_EQ(0, cstr1.size()); + EXPECT_EQ(0, cstr1.length()); + EXPECT_EQ(cstr1.begin(), cstr1.end()); + EXPECT_EQ(cstr1, AZStd::string_view()); + EXPECT_TRUE(cstr1.empty()); - string_view cstr2("Test"); - AZ_TEST_ASSERT(cstr2.data() != nullptr); - AZ_TEST_ASSERT(cstr2.size() == 4); - AZ_TEST_ASSERT(cstr2.length() == 4); - AZ_TEST_ASSERT(cstr2.begin() != cstr2.end()); - AZ_TEST_ASSERT(cstr2 != cstr1); - AZ_TEST_ASSERT(cstr2 == string_view("Test")); - AZ_TEST_ASSERT(cstr2 == "Test"); - AZ_TEST_ASSERT(cstr2 != "test"); - AZ_TEST_ASSERT(cstr2[2] == 's'); - AZ_TEST_ASSERT(cstr2.at(2) == 's'); + AZStd::string_view cstr2("Test"); + EXPECT_NE(nullptr, cstr2.data()); + EXPECT_EQ(4, cstr2.size()); + EXPECT_EQ(4, cstr2.length()); + EXPECT_NE(cstr2.begin(), cstr2.end()); + EXPECT_NE(cstr2, cstr1); + EXPECT_EQ(cstr2, AZStd::string_view("Test")); + EXPECT_EQ(cstr2, "Test"); + EXPECT_NE(cstr2, "test"); + EXPECT_EQ(cstr2[2], 's'); + EXPECT_EQ(cstr2.at(2), 's'); AZ_TEST_START_TRACE_SUPPRESSION; - AZ_TEST_ASSERT(cstr2.at(7) == 0); + EXPECT_EQ(0, cstr2.at(7)); AZ_TEST_STOP_TRACE_SUPPRESSION(1); - AZ_TEST_ASSERT(!cstr2.empty()); - AZ_TEST_ASSERT(cstr2.data() == string("Test")); - AZ_TEST_ASSERT((string)cstr2 == string("Test")); + EXPECT_FALSE(cstr2.empty()); + EXPECT_EQ(cstr2.data(), AZStd::string("Test")); + EXPECT_EQ(cstr2, AZStd::string("Test")); - string_view cstr3 = cstr2; - AZ_TEST_ASSERT(cstr3 == cstr2); + AZStd::string_view cstr3 = cstr2; + EXPECT_EQ(cstr3, cstr2); cstr3.swap(cstr1); - AZ_TEST_ASSERT(cstr3 == string_view()); - AZ_TEST_ASSERT(cstr1 == cstr2); + EXPECT_EQ(cstr3, AZStd::string_view()); + EXPECT_EQ(cstr1, cstr2); cstr1 = {}; - AZ_TEST_ASSERT(cstr1 == string_view()); - AZ_TEST_ASSERT(cstr1.size() == 0); - AZ_TEST_ASSERT(cstr1.length() == 0); + EXPECT_EQ(cstr1, AZStd::string_view()); + EXPECT_EQ(0, cstr1.size()); + EXPECT_EQ(0, cstr1.length()); AZStd::string str1("Test"); - AZ_TEST_ASSERT(cstr2 == str1); + EXPECT_EQ(cstr2, str1); cstr1 = str1; - AZ_TEST_ASSERT(cstr1 == cstr2); + EXPECT_EQ(cstr1, cstr2); // check hashing - AZStd::hash h; + AZStd::hash h; AZStd::size_t value = h(cstr1); - AZ_TEST_ASSERT(value != 0); + EXPECT_NE(0, value); // testing empty string AZStd::string emptyString; - string_view cstr4; + AZStd::string_view cstr4; cstr4 = emptyString; - AZ_TEST_ASSERT(cstr4.data() != nullptr); - AZ_TEST_ASSERT(cstr4.size() == 0); - AZ_TEST_ASSERT(cstr4.length() == 0); - AZ_TEST_ASSERT(cstr4.begin() == cstr4.end()); - AZ_TEST_ASSERT(cstr4.empty()); + EXPECT_NE(nullptr, cstr4.data()); + EXPECT_EQ(0, cstr4.size()); + EXPECT_EQ(0, cstr4.length()); + EXPECT_EQ(cstr4.begin(), cstr4.end()); + EXPECT_TRUE(cstr4.empty()); } TEST_F(String, StringViewModifierTest) { - string_view emptyView1; - string_view view2("Needle in Haystack"); + AZStd::string_view emptyView1; + AZStd::string_view view2("Needle in Haystack"); // front EXPECT_EQ('N', view2.front()); @@ -1209,7 +1204,7 @@ namespace UnitTest EXPECT_EQ('k', view2.back()); AZStd::string findStr("Hay"); - string_view view3(findStr); + AZStd::string_view view3(findStr); // copy const size_t destBufferSize = 32; @@ -1223,17 +1218,17 @@ namespace UnitTest AZ_TEST_STOP_TRACE_SUPPRESSION(1); // substr - string_view subView2 = view2.substr(10); + AZStd::string_view subView2 = view2.substr(10); EXPECT_EQ("Haystack", subView2); AZ_TEST_START_TRACE_SUPPRESSION; - [[maybe_unused]] string_view assertSubView = view2.substr(view2.size() + 1); + [[maybe_unused]] AZStd::string_view assertSubView = view2.substr(view2.size() + 1); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // compare AZStd::size_t compareResult = view2.compare(1, view2.size() - 1, dest, copyResult); EXPECT_EQ(0, compareResult); - string_view compareView = "Stackhay in Needle"; + AZStd::string_view compareView = "Stackhay in Needle"; compareResult = compareView.compare(view2); EXPECT_NE(0, compareResult); @@ -1252,7 +1247,7 @@ namespace UnitTest EXPECT_EQ(10, findResult); findResult = compareView.find("Random String"); - EXPECT_EQ(string_view::npos, findResult); + EXPECT_EQ(AZStd::string_view::npos, findResult); findResult = view3.find('y', 2); EXPECT_EQ(2, findResult); @@ -1262,13 +1257,13 @@ namespace UnitTest EXPECT_EQ(1, rfindResult); rfindResult = emptyView1.rfind(""); - EXPECT_EQ(string_view::npos, rfindResult); + EXPECT_EQ(AZStd::string_view::npos, rfindResult); rfindResult = view2.rfind("z"); - EXPECT_EQ(string_view::npos, rfindResult); + EXPECT_EQ(AZStd::string_view::npos, rfindResult); // find_first_of - string_view repeatString = "abcdefabcfedghiabcdef"; + AZStd::string_view repeatString = "abcdefabcfedghiabcdef"; AZStd::size_t findFirstOfResult = repeatString.find_first_of('f'); EXPECT_EQ(5, findFirstOfResult); @@ -1281,7 +1276,7 @@ namespace UnitTest AZStd::string notFoundStr = "zzz"; AZStd::string foundStr = "ghi"; findFirstOfResult = repeatString.find_first_of(notFoundStr); - EXPECT_EQ(string_view::npos, findFirstOfResult); + EXPECT_EQ(AZStd::string_view::npos, findFirstOfResult); findFirstOfResult = repeatString.find_first_of(foundStr); EXPECT_EQ(12, findFirstOfResult); @@ -1297,7 +1292,7 @@ namespace UnitTest EXPECT_EQ(3, findLastOfResult); findLastOfResult = repeatString.find_last_of(notFoundStr); - EXPECT_EQ(string_view::npos, findLastOfResult); + EXPECT_EQ(AZStd::string_view::npos, findLastOfResult); findLastOfResult = repeatString.find_last_of(foundStr); EXPECT_EQ(14, findLastOfResult); @@ -1335,12 +1330,12 @@ namespace UnitTest EXPECT_EQ(11, findLastNotOfResult); // remove_prefix - string_view prefixRemovalView = view2; + AZStd::string_view prefixRemovalView = view2; prefixRemovalView.remove_prefix(6); EXPECT_EQ(" in Haystack", prefixRemovalView); // remove_suffix - string_view suffixRemovalView = view2; + AZStd::string_view suffixRemovalView = view2; suffixRemovalView.remove_suffix(8); EXPECT_EQ("Needle in ", suffixRemovalView); @@ -1365,10 +1360,10 @@ namespace UnitTest TEST_F(String, StringViewCmpOperatorTest) { - string_view view1("The quick brown fox jumped over the lazy dog"); - string_view view2("Needle in Haystack"); - string_view emptyBeaverView; - string_view superEmptyBeaverView(""); + AZStd::string_view view1("The quick brown fox jumped over the lazy dog"); + AZStd::string_view view2("Needle in Haystack"); + AZStd::string_view emptyBeaverView; + AZStd::string_view superEmptyBeaverView(""); EXPECT_EQ("", emptyBeaverView); EXPECT_EQ("", superEmptyBeaverView); @@ -1378,13 +1373,13 @@ namespace UnitTest EXPECT_EQ(view2, "Needle in Haystack"); EXPECT_NE(view2, "Needle in Hayqueue"); - string_view compareView(view2); + AZStd::string_view compareView(view2); EXPECT_EQ(view2, compareView); EXPECT_NE(view2, view1); AZStd::string compareStr("Busy Beaver"); - string_view notBeaverView("Lumber Beaver"); - string_view beaverView("Busy Beaver"); + AZStd::string_view notBeaverView("Lumber Beaver"); + AZStd::string_view beaverView("Busy Beaver"); EXPECT_EQ(compareStr, beaverView); EXPECT_NE(compareStr, notBeaverView); @@ -1528,8 +1523,8 @@ namespace UnitTest TYPED_TEST_CASE(BasicStringViewConstexprFixture, StringViewElementTypes); TYPED_TEST(BasicStringViewConstexprFixture, StringView_DefaultConstructorsIsConstexpr) { - constexpr basic_string_view defaultView1; - constexpr basic_string_view defaultView2; + constexpr AZStd::basic_string_view defaultView1; + constexpr AZStd::basic_string_view defaultView2; static_assert(defaultView1 == defaultView2, "string_view constructor should be constexpr"); } @@ -1549,7 +1544,7 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view charTView1(compileTimeString); + constexpr AZStd::basic_string_view charTView1(compileTimeString); static_assert(charTView1.size() == 10, "string_view constructor should be constexpr"); // non-null terminated compile time string constexpr const TypeParam* compileTimeString2 = []() constexpr -> const TypeParam* @@ -1565,7 +1560,7 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view charTViewWithLength(compileTimeString2, 7); + constexpr AZStd::basic_string_view charTViewWithLength(compileTimeString2, 7); static_assert(charTViewWithLength.size() == 7, "string_view constructor should be constexpr"); } @@ -1585,8 +1580,8 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view copyView1(compileTimeString); - constexpr basic_string_view copyView2(copyView1); + constexpr AZStd::basic_string_view copyView1(compileTimeString); + constexpr AZStd::basic_string_view copyView2(copyView1); static_assert(copyView1 == copyView2, "string_view constructor should be constexpr"); } @@ -1606,8 +1601,8 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view assignView1(compileTimeString1); - auto assignment_test_func = [](basic_string_view sourceView) constexpr -> basic_string_view + constexpr AZStd::basic_string_view assignView1(compileTimeString1); + auto assignment_test_func = [](AZStd::basic_string_view sourceView) constexpr -> AZStd::basic_string_view { constexpr const TypeParam* const compileTimeString2 = []() constexpr-> const TypeParam* { @@ -1622,7 +1617,7 @@ namespace UnitTest return {}; }(); - basic_string_view assignView2(compileTimeString2); + AZStd::basic_string_view assignView2(compileTimeString2); assignView2 = sourceView; return assignView2; }; @@ -1646,15 +1641,15 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view iteratorView(compileTimeString1); - constexpr typename basic_string_view::iterator beginIt = iteratorView.begin(); - constexpr typename basic_string_view::const_iterator cbeginIt = iteratorView.cbegin(); - constexpr typename basic_string_view::iterator endIt = iteratorView.end(); - constexpr typename basic_string_view::const_iterator cendIt = iteratorView.cend(); - constexpr typename basic_string_view::reverse_iterator rbeginIt = iteratorView.rbegin(); - constexpr typename basic_string_view::const_reverse_iterator crbeginIt = iteratorView.crbegin(); - constexpr typename basic_string_view::reverse_iterator rendIt = iteratorView.rend(); - constexpr typename basic_string_view::const_reverse_iterator crendIt = iteratorView.crend(); + constexpr AZStd::basic_string_view iteratorView(compileTimeString1); + constexpr typename AZStd::basic_string_view::iterator beginIt = iteratorView.begin(); + constexpr typename AZStd::basic_string_view::const_iterator cbeginIt = iteratorView.cbegin(); + constexpr typename AZStd::basic_string_view::iterator endIt = iteratorView.end(); + constexpr typename AZStd::basic_string_view::const_iterator cendIt = iteratorView.cend(); + constexpr typename AZStd::basic_string_view::reverse_iterator rbeginIt = iteratorView.rbegin(); + constexpr typename AZStd::basic_string_view::const_reverse_iterator crbeginIt = iteratorView.crbegin(); + constexpr typename AZStd::basic_string_view::reverse_iterator rendIt = iteratorView.rend(); + constexpr typename AZStd::basic_string_view::const_reverse_iterator crendIt = iteratorView.crend(); static_assert(beginIt != endIt, "begin and iterators should be different"); static_assert(cbeginIt != cendIt, "begin and iterators should be different"); static_assert(rbeginIt != rendIt, "begin and iterators should be different"); @@ -1679,7 +1674,7 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view elementView1(compileTimeString1); + constexpr AZStd::basic_string_view elementView1(compileTimeString1); static_assert(elementView1[4] == 'o', "character at index 4 in string_view should be 'o'"); static_assert(elementView1.at(5) == 'W', "character at index 5 in string_view should be 'W'"); } @@ -1700,7 +1695,7 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view elementView1(compileTimeString1); + constexpr AZStd::basic_string_view elementView1(compileTimeString1); static_assert(elementView1.front() == 'H', "Fourth character in string_view should be 'H'"); static_assert(elementView1.back() == 'd', "Fifth character in string_view should be 'd'"); } @@ -1734,8 +1729,8 @@ namespace UnitTest return {}; }(); - static constexpr basic_string_view elementView1(compileTimeString1); - static constexpr basic_string_view elementView2(compileTimeString2); + static constexpr AZStd::basic_string_view elementView1(compileTimeString1); + static constexpr AZStd::basic_string_view elementView2(compileTimeString2); static_assert(elementView1.data(), "string_view.data() should be non-nullptr"); static_assert(elementView2.data(), "string_view.data() should be non-nullptr"); } @@ -1756,7 +1751,7 @@ namespace UnitTest return {}; }(); - constexpr basic_string_view sizeView1(compileTimeString1); + constexpr AZStd::basic_string_view sizeView1(compileTimeString1); static_assert(sizeView1.size() == sizeView1.length(), "string_views size and length function should return the same value"); static_assert(!sizeView1.empty(), "string_views should not be empty"); static_assert(sizeView1.max_size() != 0, "string_views max_size should be greater than 0"); @@ -1770,21 +1765,21 @@ namespace UnitTest { return "HelloWorld"; }; - constexpr basic_string_view modifierView("HelloWorld"); + constexpr AZStd::basic_string_view modifierView("HelloWorld"); // A constexpr lambda is used to evaluate non constexpr string_view instances' member functions which // have been marked as constexpr at compile time // The google test function being run is not a constexpr function and therefore will evaulate // non-constexpr string_view variables at runtime. This would cause static_assert to state // that the expression is evaluated at runtime - auto remove_prefix_test_func = [](basic_string_view sourceView) constexpr -> basic_string_view + auto remove_prefix_test_func = [](AZStd::basic_string_view sourceView) constexpr -> AZStd::basic_string_view { - basic_string_view lstripView(sourceView); + AZStd::basic_string_view lstripView(sourceView); lstripView.remove_prefix(5); return lstripView; }; - auto remove_suffix_test_func = [](basic_string_view sourceView) constexpr -> basic_string_view + auto remove_suffix_test_func = [](AZStd::basic_string_view sourceView) constexpr -> AZStd::basic_string_view { - basic_string_view rstripView(sourceView); + AZStd::basic_string_view rstripView(sourceView); rstripView.remove_suffix(5); return rstripView; }; @@ -1801,8 +1796,8 @@ namespace UnitTest return "HelloWorld"; }; constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();; - constexpr basic_string_view fullView(compileTimeString1); - auto substr_test_func = [](basic_string_view sourceView) constexpr -> basic_string_view + constexpr AZStd::basic_string_view fullView(compileTimeString1); + auto substr_test_func = [](AZStd::basic_string_view sourceView) constexpr -> AZStd::basic_string_view { return sourceView.substr(3, 5); }; @@ -1818,7 +1813,7 @@ namespace UnitTest return "elloGovernor"; }; constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1(); - constexpr basic_string_view withView(compileTimeString1); + constexpr AZStd::basic_string_view withView(compileTimeString1); static_assert(withView.starts_with("ello"), "string_view should start with \"ello\""); // Regression in VS2017 15.8 and 15.9 where __builtin_memcmp fails in valid checks #if AZ_COMPILER_MSVC < 1915 && AZ_COMPILER_MSVC > 1916 @@ -1854,9 +1849,9 @@ namespace UnitTest TYPED_TEST(BasicStringViewConstexprFixture, StringView_FindOperationsAreConstexpr) { constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1; - constexpr basic_string_view quickFoxView(compileTimeString1); + constexpr AZStd::basic_string_view quickFoxView(compileTimeString1); constexpr const TypeParam* searchString = MakeSearchString; - constexpr basic_string_view searchView(searchString); + constexpr AZStd::basic_string_view searchView(searchString); constexpr const TypeParam* testString1 = MakeTestString1; constexpr const TypeParam* testString2 = MakeTestString2; @@ -1893,10 +1888,10 @@ namespace UnitTest static_assert(quickFoxView.find_last_of('o') == 42, "string_view find_last_of should result in index 42"); static_assert(quickFoxView.find_last_of(testString6) == 40, "string_view find_last_of should result in index 40"); static_assert(quickFoxView.find_last_of(testString7, 31) == 29, "string_view find_last_of should result in index 29"); - static_assert(quickFoxView.find_last_of(testString8, basic_string_view::npos, 1) == 7, "string_view find_last_of should result in index 7"); + static_assert(quickFoxView.find_last_of(testString8, AZStd::basic_string_view::npos, 1) == 7, "string_view find_last_of should result in index 7"); // find_first_not_of test - constexpr basic_string_view firstNotOfView(testString9); + constexpr AZStd::basic_string_view firstNotOfView(testString9); static_assert(quickFoxView.find_first_not_of(firstNotOfView) == 4, "string_view find_first_not_of should result in index 0"); static_assert(quickFoxView.find_first_not_of('t') == 1, "string_view find_first_not_of should result in index 1"); static_assert(quickFoxView.find_first_not_of(testString9) == 4, "string_view find_first_not_of should result in index 4"); @@ -1904,12 +1899,12 @@ namespace UnitTest static_assert(quickFoxView.find_first_not_of(testString9, 0, 1) == 1, "string_view find_first_not_of should result in index 1"); // find_last_not_of test - constexpr basic_string_view lastNotOfView(testString10); + constexpr AZStd::basic_string_view lastNotOfView(testString10); static_assert(quickFoxView.find_last_not_of(lastNotOfView) == 39, "string_view find_last_not_of should result in index 39"); static_assert(quickFoxView.find_last_not_of('g') == 42, "string_view find_last_not_of should result in index 42"); static_assert(quickFoxView.find_last_not_of(testString10) == 39, "string_view find_last_not_of should result in index 39"); static_assert(quickFoxView.find_last_not_of(testString10, 27) == 24, "string_view find_last_not_of should result in index 24"); - static_assert(quickFoxView.find_last_not_of(testString10, basic_string_view::npos, 1) == 43, "string_view find_last_not_of should result in index 43"); + static_assert(quickFoxView.find_last_not_of(testString10, AZStd::basic_string_view::npos, 1) == 43, "string_view find_last_not_of should result in index 43"); } TEST_F(String, StringView_CompareIsConstexpr) @@ -1925,8 +1920,8 @@ namespace UnitTest }; constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1(); constexpr const TypeParam* compileTimeString2 = MakeCompileTimeString2(); - constexpr basic_string_view lhsView(compileTimeString1); - constexpr basic_string_view rhsView(compileTimeString2); + constexpr AZStd::basic_string_view lhsView(compileTimeString1); + constexpr AZStd::basic_string_view rhsView(compileTimeString2); static_assert(lhsView.compare(rhsView) > 0, R"("HelloWorld" > "HelloPearl")"); static_assert(lhsView.compare(0, 5, rhsView) < 0, R"("Hello" < HelloPearl")"); static_assert(lhsView.compare(2, 3, rhsView, 2, 3) == 0, R"("llo" == llo")"); @@ -1943,7 +1938,7 @@ namespace UnitTest return "HelloWorld"; }; constexpr const TypeParam* compileTimeString1 = TestMakeCompileTimeString1(); - constexpr basic_string_view compareView(compileTimeString1); + constexpr AZStd::basic_string_view compareView(compileTimeString1); static_assert(compareView == "HelloWorld", "string_view operator== comparison has failed"); static_assert(compareView != "MadWorld", "string_view operator!= comparison has failed"); static_assert(compareView < "JelloWorld", "string_view operator< comparison has failed"); @@ -1954,7 +1949,7 @@ namespace UnitTest TYPED_TEST(BasicStringViewConstexprFixture, StringView_SwapIsConstexpr) { - auto swap_test_func = []() constexpr -> basic_string_view + auto swap_test_func = []() constexpr -> AZStd::basic_string_view { constexpr auto ThisTestMakeCompileTimeString1 = []() constexpr -> const TypeParam* { @@ -1980,8 +1975,8 @@ namespace UnitTest }; constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1(); constexpr const TypeParam* compileTimeString2 = MakeCompileTimeString2(); - basic_string_view lhsView(compileTimeString1); - basic_string_view rhsView(compileTimeString2); + AZStd::basic_string_view lhsView(compileTimeString1); + AZStd::basic_string_view rhsView(compileTimeString2); lhsView.swap(rhsView); return lhsView; }; @@ -2014,13 +2009,14 @@ namespace UnitTest } }; constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1(); - constexpr basic_string_view hashView(compileTimeString1); - constexpr size_t compileHash = AZStd::hash>{}(hashView); + constexpr AZStd::basic_string_view hashView(compileTimeString1); + constexpr size_t compileHash = AZStd::hash>{}(hashView); static_assert(compileHash != 0, "Hash of \"HelloWorld\" should not be 0"); } TEST_F(String, StringView_UserLiteralsSucceed) { + using namespace AZStd::string_view_literals; constexpr auto charView{ "Test"_sv }; constexpr auto wcharView{ L"Super Test"_sv }; static_assert(charView == "Test", "char string literal should be \"Test\""); @@ -2291,21 +2287,21 @@ namespace UnitTest { AZStd::fixed_string<32> filter1; AZStd::string testValue{ "test" }; - EXPECT_FALSE(wildcard_match(filter1, testValue)); + EXPECT_FALSE(AZStd::wildcard_match(filter1, testValue)); } TEST_F(String, WildcardMatch_EmptyFilterWithEmptyValue_Succeeds) { AZStd::fixed_string<32> filter1; AZStd::fixed_string<32> emptyValue; - EXPECT_TRUE(wildcard_match(filter1, emptyValue)); + EXPECT_TRUE(AZStd::wildcard_match(filter1, emptyValue)); } TEST_F(String, WildcardMatch_AsteriskOnlyFilterWithEmptyValue_Succeeds) { const char* filter1{ "*" }; const char* filter2{ "**" }; const char* emptyValue{ "" }; - EXPECT_TRUE(wildcard_match(filter1, emptyValue)); - EXPECT_TRUE(wildcard_match(filter2, emptyValue)); + EXPECT_TRUE(AZStd::wildcard_match(filter1, emptyValue)); + EXPECT_TRUE(AZStd::wildcard_match(filter2, emptyValue)); } TEST_F(String, WildcardMatch_AsteriskQuestionMarkFilterWithEmptyValue_Failes) { @@ -2313,60 +2309,60 @@ namespace UnitTest const char* filter1{ "*?" }; const char* filter2{ "?*" }; const char* emptyValue{ "" }; - EXPECT_FALSE(wildcard_match(filter1, emptyValue)); - EXPECT_FALSE(wildcard_match(filter2, emptyValue)); + EXPECT_FALSE(AZStd::wildcard_match(filter1, emptyValue)); + EXPECT_FALSE(AZStd::wildcard_match(filter2, emptyValue)); } TEST_F(String, WildcardMatch_DotValue_Succeeds) { const char* filter1{ "?" }; const char* dotValue{ "." }; - EXPECT_TRUE(wildcard_match(filter1, dotValue)); + EXPECT_TRUE(AZStd::wildcard_match(filter1, dotValue)); } TEST_F(String, WildcardMatch_DoubleDotValue_Succeeds) { const char* filter1{ "??" }; const char* dotValue{ ".." }; - EXPECT_TRUE(wildcard_match(filter1, dotValue)); + EXPECT_TRUE(AZStd::wildcard_match(filter1, dotValue)); } TEST_F(String, WildcardMatch_GlobFilters_Succeeds) { const char* filter1{ "*" }; const char* filter2{ "*?" }; const char* filter3{ "?*" }; - EXPECT_TRUE(wildcard_match(filter1, "Hello")); - EXPECT_TRUE(wildcard_match(filter1, "?")); - EXPECT_TRUE(wildcard_match(filter1, "*")); - EXPECT_TRUE(wildcard_match(filter1, "Q")); + EXPECT_TRUE(AZStd::wildcard_match(filter1, "Hello")); + EXPECT_TRUE(AZStd::wildcard_match(filter1, "?")); + EXPECT_TRUE(AZStd::wildcard_match(filter1, "*")); + EXPECT_TRUE(AZStd::wildcard_match(filter1, "Q")); - EXPECT_TRUE(wildcard_match(filter2, "Hello")); - EXPECT_TRUE(wildcard_match(filter2, "?")); - EXPECT_TRUE(wildcard_match(filter2, "*")); - EXPECT_TRUE(wildcard_match(filter2, "Q")); + EXPECT_TRUE(AZStd::wildcard_match(filter2, "Hello")); + EXPECT_TRUE(AZStd::wildcard_match(filter2, "?")); + EXPECT_TRUE(AZStd::wildcard_match(filter2, "*")); + EXPECT_TRUE(AZStd::wildcard_match(filter2, "Q")); - EXPECT_TRUE(wildcard_match(filter3, "Hello")); - EXPECT_TRUE(wildcard_match(filter3, "?")); - EXPECT_TRUE(wildcard_match(filter3, "*")); - EXPECT_TRUE(wildcard_match(filter3, "Q")); + EXPECT_TRUE(AZStd::wildcard_match(filter3, "Hello")); + EXPECT_TRUE(AZStd::wildcard_match(filter3, "?")); + EXPECT_TRUE(AZStd::wildcard_match(filter3, "*")); + EXPECT_TRUE(AZStd::wildcard_match(filter3, "Q")); } TEST_F(String, WildcardMatch_NormalString_Succeeds) { constexpr AZStd::string_view jpgFilter{ "**/*.jpg" }; - EXPECT_FALSE(wildcard_match(jpgFilter, "Test.jpg")); - EXPECT_FALSE(wildcard_match(jpgFilter, "Test.jpfg")); - EXPECT_TRUE(wildcard_match(jpgFilter, "Images/Other.jpg")); - EXPECT_FALSE(wildcard_match(jpgFilter, "Pictures/Other.gif")); + EXPECT_FALSE(AZStd::wildcard_match(jpgFilter, "Test.jpg")); + EXPECT_FALSE(AZStd::wildcard_match(jpgFilter, "Test.jpfg")); + EXPECT_TRUE(AZStd::wildcard_match(jpgFilter, "Images/Other.jpg")); + EXPECT_FALSE(AZStd::wildcard_match(jpgFilter, "Pictures/Other.gif")); constexpr AZStd::string_view tempDirFilter{ "temp/*" }; - EXPECT_TRUE(wildcard_match(tempDirFilter, "temp/")); - EXPECT_TRUE(wildcard_match(tempDirFilter, "temp/f")); - EXPECT_FALSE(wildcard_match(tempDirFilter, "tem1/")); + EXPECT_TRUE(AZStd::wildcard_match(tempDirFilter, "temp/")); + EXPECT_TRUE(AZStd::wildcard_match(tempDirFilter, "temp/f")); + EXPECT_FALSE(AZStd::wildcard_match(tempDirFilter, "tem1/")); constexpr AZStd::string_view xmlFilter{ "test.xml" }; - EXPECT_TRUE(wildcard_match(xmlFilter, "Test.xml")); - EXPECT_TRUE(wildcard_match(xmlFilter, "test.xml")); - EXPECT_FALSE(wildcard_match(xmlFilter, "test.xmlschema")); - EXPECT_FALSE(wildcard_match(xmlFilter, "Xtest.xml")); + EXPECT_TRUE(AZStd::wildcard_match(xmlFilter, "Test.xml")); + EXPECT_TRUE(AZStd::wildcard_match(xmlFilter, "test.xml")); + EXPECT_FALSE(AZStd::wildcard_match(xmlFilter, "test.xmlschema")); + EXPECT_FALSE(AZStd::wildcard_match(xmlFilter, "Xtest.xml")); } TEST_F(String, WildcardMatchCase_CanBeCompileTimeEvaluated_Succeeds) @@ -2424,6 +2420,31 @@ namespace UnitTest EXPECT_EQ("oWord", eraseIfTest); } + TEST_F(String, StringWithStatelessAllocator_HasSizeOf_PointerPlus2IntTypes_Compiles) + { + // The expected size of a basic_string with a stateless allocator + // Is the size of the pointer (used for storing the memory address of the string) + // + the size of the string "size" member used to store the size of the string + // + the size of the string "capacity" member used to store the capacity of the string + size_t constexpr ExpectedBasicStringSize = sizeof(void*) + 2 * sizeof(size_t); + using StringStatelessAllocator = AZStd::basic_string, AZStd::stateless_allocator>; + static_assert(ExpectedBasicStringSize == sizeof(StringStatelessAllocator), + "Stateless allocator is counting against the size of the basic_string class" + " A change has made to break the empty base optimization of the basic_string class"); + } + + TEST_F(String, StringWithStatefulAllocator_HasSizeOf_PointerPlus2IntTypesPlusAllocator_Compiles) + { + // The expected size of a basic_string with a stateless allocator + // Is the size of the pointer (used for storing the memory address of the string) + // + the size of the string "size" member used to store the size of the string + // + the size of the string "capacity" member used to store the capacity of the string + size_t constexpr ExpectedBasicStringSize = sizeof(void*) + 2 * sizeof(size_t) + sizeof(AZStd::allocator); + static_assert(ExpectedBasicStringSize == sizeof(AZStd::string), + "Using Stateful allocator with basic_string class should result in a 32-byte string class" + " on 64-bit platforms "); + } + template class ImmutableStringFunctionsFixture : public ScopedAllocatorSetupFixture @@ -2473,5 +2494,296 @@ namespace UnitTest EXPECT_EQ(str, formatted); } -#endif // AZ_UNIT_TEST_SKIP_STD_STRING_TESTS } + +#if defined(HAVE_BENCHMARK) +namespace Benchmark +{ + class StringBenchmarkFixture + : public ::UnitTest::AllocatorsBenchmarkFixture + { + protected: + template + void SwapStringViaMemcpy(AZStd::basic_string& left, + AZStd::basic_string& right) + { + // Test Swapping the storage container for the string class + // Use aligned_storage to prevent constructors from slowing operation + AZStd::aligned_storage_for_t tempStorage; + ::memcpy(&tempStorage, &left.m_storage.first(), sizeof(left.m_storage.first())); + ::memcpy(&left.m_storage.first(), &right.m_storage.first(), sizeof(right.m_storage.first())); + ::memcpy(&right.m_storage.first(), &tempStorage, sizeof(tempStorage)); + } + + + template + void SwapStringViaPointerSizedSwaps(AZStd::basic_string& left, + AZStd::basic_string& right) + { + using String = AZStd::basic_string; + using PointerAlignedData = typename String::PointerAlignedData; + // Use pointer sized swaps to swap the string storage + auto& leftAlignedPointers = reinterpret_cast(left.m_storage.first()); + auto& rightAlignedPointers = reinterpret_cast(right.m_storage.first()); + constexpr size_t alignedPointerCount{ AZStd::size(PointerAlignedData{}.m_alignedValues) }; + for (size_t i = 0; i < alignedPointerCount; ++i) + { + AZStd::swap(leftAlignedPointers.m_alignedValues[i], rightAlignedPointers.m_alignedValues[i]); + } + } + }; + + BENCHMARK_F(StringBenchmarkFixture, BM_StringPointerSwapShortString)(benchmark::State& state) + { + AZStd::string test1{ "foo bar"}; + AZStd::string test2{ "bar foo" }; + for (auto _ : state) + { + SwapStringViaPointerSizedSwaps(test1, test2); + } + } + + BENCHMARK_F(StringBenchmarkFixture, BM_StringPointerSwapLongString)(benchmark::State& state) + { + AZStd::string test1{ "The brown quick wolf jumped over the hyperactive cat" }; + AZStd::string test2{ "The quick brown fox jumped over the lazy dog" }; + for (auto _ : state) + { + SwapStringViaPointerSizedSwaps(test1, test2); + } + } + + BENCHMARK_F(StringBenchmarkFixture, BM_StringMemcpySwapShortString)(benchmark::State& state) + { + AZStd::string test1{ "foo bar" }; + AZStd::string test2{ "bar foo" }; + for (auto _ : state) + { + SwapStringViaMemcpy(test1, test2); + } + } + + BENCHMARK_F(StringBenchmarkFixture, BM_StringMemcpySwapLongString)(benchmark::State& state) + { + AZStd::string test1{ "The brown quick wolf jumped over the hyperactive cat" }; + AZStd::string test2{ "The quick brown fox jumped over the lazy dog" }; + for (auto _ : state) + { + SwapStringViaMemcpy(test1, test2); + } + } + + template + class StringTemplateBenchmarkFixture + : public ::UnitTest::AllocatorsBenchmarkFixture + {}; + + // AZStd::string assign benchmarks + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignConstPointer_NullDelimited, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + const char* sourceAddress = sourceString.c_str(); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(sourceAddress); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignConstPointer_NullDelimited) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignConstPointer_WithSize, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + const char* sourceAddress = sourceString.c_str(); + const size_t sourceSize = sourceString.size(); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(sourceAddress, sourceSize); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignConstPointer_WithSize) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromIterators, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + auto sourceBegin = sourceString.begin(); + auto sourceEnd = sourceString.end(); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(sourceBegin, sourceEnd); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignFromIterators) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromStringView, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + AZStd::string_view sourceView(sourceString); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(sourceView); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignFromStringView) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromString_LValue, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(sourceString); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignFromString_LValue) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromString_RValue, AZStd::string)(benchmark::State& state) + { + AZStd::string sourceString(state.range(0), 'a'); + + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(AZStd::move(sourceString)); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignFromString_RValue) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromSingleCharacter, AZStd::string)(benchmark::State& state) + { + for (auto _ : state) + { + AZStd::string assignString; + assignString.assign(state.range(0), 'a'); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_StringAssignFromSingleCharacter) + ->RangeMultiplier(2)->Range(8, 32); + + // AZStd::fixed_string assign benchmarks + // NOTE: This is a copy-and-paste of above because Google Benchmark doesn't support real templated benchmarks like Googletest + // https://github.com/google/benchmark/issues/541 + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignConstPointer_NullDelimited, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + const char* sourceAddress = sourceString.c_str(); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(sourceAddress); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignConstPointer_NullDelimited) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignConstPointer_WithSize, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + const char* sourceAddress = sourceString.c_str(); + const size_t sourceSize = sourceString.size(); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(sourceAddress, sourceSize); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignConstPointer_WithSize) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromIterators, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + auto sourceBegin = sourceString.begin(); + auto sourceEnd = sourceString.end(); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(sourceBegin, sourceEnd); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromIterators) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromStringView, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + AZStd::string_view sourceView(sourceString); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(sourceView); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromStringView) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromString_LValue, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(sourceString); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromString_LValue) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromString_RValue, AZStd::fixed_string<1024>)(benchmark::State& state) + { + AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); + + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(AZStd::move(sourceString)); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromString_RValue) + ->RangeMultiplier(2)->Range(8, 32); + + BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromSingleCharacter, AZStd::fixed_string<1024>)(benchmark::State& state) + { + for (auto _ : state) + { + AZStd::fixed_string<1024> assignString; + assignString.assign(state.range(0), 'a'); + } + } + + BENCHMARK_REGISTER_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromSingleCharacter) + ->RangeMultiplier(2)->Range(8, 32); +} +#endif diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp index 7ce0290ea3..e17d5c1fbf 100644 --- a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp @@ -72,12 +72,11 @@ namespace AWSCoreUnitTest AWSCore::RequestBuilder requestBuilder{}; EXPECT_TRUE(request.parameters.BuildRequest(requestBuilder)); std::shared_ptr bodyContent = requestBuilder.GetBodyContent(); - EXPECT_TRUE(bodyContent != nullptr); + EXPECT_NE(nullptr, bodyContent); - AZStd::string bodyString; std::istreambuf_iterator eos; - bodyString = AZStd::string{ std::istreambuf_iterator(*bodyContent), eos }; - AZ_Printf("AWSAttributionServiceApiTest", bodyString.c_str()); - EXPECT_TRUE(bodyString.find(AZStd::string::format("{\"%s\":\"1.1\"", AwsAttributionAttributeKeyVersion)) != AZStd::string::npos); + AZStd::string bodyString{ std::istreambuf_iterator(*bodyContent), eos }; + AZ_Printf("AWSAttributionServiceApiTest", "%s", bodyString.c_str()); + EXPECT_TRUE(bodyString.contains(AZStd::string::format("{\"%s\":\"1.1\"", AwsAttributionAttributeKeyVersion))); } } diff --git a/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp b/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp index 8844e727b6..b7e7527b20 100644 --- a/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp +++ b/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp @@ -100,11 +100,10 @@ namespace AWSMetrics AWSCore::RequestBuilder requestBuilder{}; EXPECT_TRUE(request.parameters.BuildRequest(requestBuilder)); std::shared_ptr bodyContent = requestBuilder.GetBodyContent(); - EXPECT_TRUE(bodyContent != nullptr); + ASSERT_NE(nullptr, bodyContent); - AZStd::string bodyString; std::istreambuf_iterator eos; - bodyString = AZStd::string{ std::istreambuf_iterator(*bodyContent), eos }; - EXPECT_TRUE(bodyString.find(AZStd::string::format("{\"%s\":[{\"event_timestamp\":", AwsMetricsRequestParameterKeyEvents)) != AZStd::string::npos); + AZStd::string bodyString{ std::istreambuf_iterator(*bodyContent), eos }; + EXPECT_TRUE(bodyString.contains(AZStd::string::format("{\"%s\":[{\"event_timestamp\":", AwsMetricsRequestParameterKeyEvents))); } } diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphEventTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphEventTests.cpp index bd3fa10b24..11865674c8 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphEventTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphEventTests.cpp @@ -49,7 +49,7 @@ namespace EMotionFX for (int i = 0; i < params.m_numStates; ++i) { AnimGraphNode* state = aznew AnimGraphMotionNode(); - state->SetName(AZStd::string(1, startChar + i).c_str()); + state->SetName(AZStd::string(1, static_cast(startChar + i)).c_str()); m_rootStateMachine->AddChildNode(state); AddTransitionWithTimeCondition(prevState, state, /*blendTime*/params.m_transitionBlendTime, /*countDownTime*/params.m_conditionCountDownTime); prevState = state; diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphRefCountTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphRefCountTests.cpp index 54f945d95f..c4e6462fff 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphRefCountTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphRefCountTests.cpp @@ -90,7 +90,7 @@ namespace EMotionFX for (int i = 0; i < param.m_numStates; ++i) { AnimGraphBindPoseNode* state = aznew AnimGraphBindPoseNode(); - state->SetName(AZStd::string(1, startChar + i).c_str()); + state->SetName(AZStd::string(1, static_cast(startChar + i)).c_str()); m_rootStateMachine->AddChildNode(state); AddTransitionWithTimeCondition(prevState, state, /*blendTime*/param.m_blendTime, /*countDownTime*/param.m_countDownTime); prevState = state; From 93996bfb3fc97de17f9127686114ac4fece3fb55 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:59:35 -0800 Subject: [PATCH 124/272] Moves LmbrCentral Test targets into a different folder to prevent MSB8028 (#6742) * Moves Test targets into a different folder to prevent MSB8028 Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Simplifies an if that was affecting the whole file Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Gems/LmbrCentral/Code/CMakeLists.txt | 73 +---------------- Gems/LmbrCentral/Code/Tests/CMakeLists.txt | 79 +++++++++++++++++++ .../lmbrcentral_editor_tests_files.cmake | 28 +++++++ .../{ => Tests}/lmbrcentral_mocks_files.cmake | 2 +- .../Code/Tests/lmbrcentral_tests_files.cmake | 32 ++++++++ .../Code/lmbrcentral_editor_tests_files.cmake | 28 ------- .../Code/lmbrcentral_tests_files.cmake | 29 ------- 7 files changed, 141 insertions(+), 130 deletions(-) create mode 100644 Gems/LmbrCentral/Code/Tests/CMakeLists.txt create mode 100644 Gems/LmbrCentral/Code/Tests/lmbrcentral_editor_tests_files.cmake rename Gems/LmbrCentral/Code/{ => Tests}/lmbrcentral_mocks_files.cmake (83%) create mode 100644 Gems/LmbrCentral/Code/Tests/lmbrcentral_tests_files.cmake delete mode 100644 Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake delete mode 100644 Gems/LmbrCentral/Code/lmbrcentral_tests_files.cmake diff --git a/Gems/LmbrCentral/Code/CMakeLists.txt b/Gems/LmbrCentral/Code/CMakeLists.txt index 2df0bd0632..4401d3b752 100644 --- a/Gems/LmbrCentral/Code/CMakeLists.txt +++ b/Gems/LmbrCentral/Code/CMakeLists.txt @@ -121,75 +121,4 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) endif() -################################################################################ -# Tests -################################################################################ -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_add_target( - NAME LmbrCentral.Mocks HEADERONLY - NAMESPACE Gem - FILES_CMAKE - lmbrcentral_mocks_files.cmake - INCLUDE_DIRECTORIES - INTERFACE - Mocks - ) - - ly_add_target( - NAME LmbrCentral.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - lmbrcentral_tests_files.cmake - lmbrcentral_shared_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Source - Tests - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - AZ::AzTestShared - Legacy::CryCommon - AZ::AzFramework - Gem::LmbrCentral.Static - Gem::LmbrCentral.Mocks - ) - ly_add_googletest( - NAME Gem::LmbrCentral.Tests - ) - - if (PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_target( - NAME LmbrCentral.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - lmbrcentral_editor_tests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - Source - Tests - COMPILE_DEFINITIONS - PRIVATE - LMBR_CENTRAL_EDITOR - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Gui - 3rdParty::Qt::Widgets - Legacy::CryCommon - Legacy::Editor.Headers - AZ::AzTest - AZ::AzCore - AZ::AzTestShared - AZ::AzToolsFramework - AZ::AzToolsFrameworkTestCommon - AZ::AssetBuilderSDK - AZ::AzManipulatorTestFramework.Static - Gem::LmbrCentral.Static - Gem::LmbrCentral.Editor.Static - ) - ly_add_googletest( - NAME Gem::LmbrCentral.Editor.Tests - ) - endif() -endif() +add_subdirectory(Tests) diff --git a/Gems/LmbrCentral/Code/Tests/CMakeLists.txt b/Gems/LmbrCentral/Code/Tests/CMakeLists.txt new file mode 100644 index 0000000000..52928cc5db --- /dev/null +++ b/Gems/LmbrCentral/Code/Tests/CMakeLists.txt @@ -0,0 +1,79 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +if(NOT PAL_TRAIT_BUILD_TESTS_SUPPORTED) + return() +endif() + +ly_add_target( + NAME LmbrCentral.Mocks HEADERONLY + NAMESPACE Gem + FILES_CMAKE + lmbrcentral_mocks_files.cmake + INCLUDE_DIRECTORIES + INTERFACE + ../Mocks +) + +ly_add_target( + NAME LmbrCentral.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + lmbrcentral_tests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + ../Source + . + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + AZ::AzTestShared + Legacy::CryCommon + AZ::AzFramework + Gem::LmbrCentral.Static + Gem::LmbrCentral.Mocks +) +ly_add_googletest( + NAME Gem::LmbrCentral.Tests +) + +if (PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_target( + NAME LmbrCentral.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + lmbrcentral_editor_tests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + .. + ../Source + . + COMPILE_DEFINITIONS + PRIVATE + LMBR_CENTRAL_EDITOR + BUILD_DEPENDENCIES + PRIVATE + 3rdParty::Qt::Gui + 3rdParty::Qt::Widgets + Legacy::CryCommon + Legacy::Editor.Headers + AZ::AzTest + AZ::AzCore + AZ::AzTestShared + AZ::AzToolsFramework + AZ::AzToolsFrameworkTestCommon + AZ::AssetBuilderSDK + AZ::AzManipulatorTestFramework.Static + Gem::LmbrCentral.Static + Gem::LmbrCentral.Editor.Static + ) + ly_add_googletest( + NAME Gem::LmbrCentral.Editor.Tests + ) +endif() + diff --git a/Gems/LmbrCentral/Code/Tests/lmbrcentral_editor_tests_files.cmake b/Gems/LmbrCentral/Code/Tests/lmbrcentral_editor_tests_files.cmake new file mode 100644 index 0000000000..72a26c2884 --- /dev/null +++ b/Gems/LmbrCentral/Code/Tests/lmbrcentral_editor_tests_files.cmake @@ -0,0 +1,28 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + LmbrCentralEditorTest.cpp + LmbrCentralReflectionTest.h + LmbrCentralReflectionTest.cpp + EditorBoxShapeComponentTests.cpp + EditorSphereShapeComponentTests.cpp + EditorCapsuleShapeComponentTests.cpp + EditorCompoundShapeComponentTests.cpp + EditorCylinderShapeComponentTests.cpp + EditorPolygonPrismShapeComponentTests.cpp + EditorTubeShapeComponentTests.cpp + SpawnerComponentTest.cpp + Builders/CopyDependencyBuilderTest.cpp + Builders/SliceBuilderTests.cpp + Builders/LevelBuilderTest.cpp + Builders/LuaBuilderTests.cpp + Builders/SeedBuilderTests.cpp + ../Source/LmbrCentral.cpp + ../Source/LmbrCentralEditor.cpp +) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_mocks_files.cmake b/Gems/LmbrCentral/Code/Tests/lmbrcentral_mocks_files.cmake similarity index 83% rename from Gems/LmbrCentral/Code/lmbrcentral_mocks_files.cmake rename to Gems/LmbrCentral/Code/Tests/lmbrcentral_mocks_files.cmake index c3a5cca3f8..1e510747f2 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_mocks_files.cmake +++ b/Gems/LmbrCentral/Code/Tests/lmbrcentral_mocks_files.cmake @@ -7,5 +7,5 @@ # set(FILES - Mocks/LmbrCentral/Shape/MockShapes.h + ../Mocks/LmbrCentral/Shape/MockShapes.h ) diff --git a/Gems/LmbrCentral/Code/Tests/lmbrcentral_tests_files.cmake b/Gems/LmbrCentral/Code/Tests/lmbrcentral_tests_files.cmake new file mode 100644 index 0000000000..1555ff53d8 --- /dev/null +++ b/Gems/LmbrCentral/Code/Tests/lmbrcentral_tests_files.cmake @@ -0,0 +1,32 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + AudioComponentTests.cpp + AxisAlignedBoxShapeTest.cpp + BoxShapeTest.cpp + BundlingSystemComponentTests.cpp + SphereShapeTest.cpp + CylinderShapeTest.cpp + CapsuleShapeTest.cpp + PolygonPrismShapeTest.cpp + QuadShapeTest.cpp + TubeShapeTest.cpp + LmbrCentralReflectionTest.h + LmbrCentralReflectionTest.cpp + LmbrCentralTest.cpp + ShapeGeometryUtilTest.cpp + SpawnerComponentTest.cpp + SplineComponentTests.cpp + DiskShapeTest.cpp + ReferenceShapeTests.cpp + ../Source/LmbrCentral.cpp + ../Source/Ai/NavigationComponent.cpp + ../Source/Scripting/SpawnerComponent.cpp + ../Source/Shape/TubeShape.cpp +) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake deleted file mode 100644 index afba79e566..0000000000 --- a/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - Tests/LmbrCentralEditorTest.cpp - Tests/LmbrCentralReflectionTest.h - Tests/LmbrCentralReflectionTest.cpp - Tests/EditorBoxShapeComponentTests.cpp - Tests/EditorSphereShapeComponentTests.cpp - Tests/EditorCapsuleShapeComponentTests.cpp - Tests/EditorCompoundShapeComponentTests.cpp - Tests/EditorCylinderShapeComponentTests.cpp - Tests/EditorPolygonPrismShapeComponentTests.cpp - Tests/EditorTubeShapeComponentTests.cpp - Tests/SpawnerComponentTest.cpp - Tests/Builders/CopyDependencyBuilderTest.cpp - Tests/Builders/SliceBuilderTests.cpp - Tests/Builders/LevelBuilderTest.cpp - Tests/Builders/LuaBuilderTests.cpp - Tests/Builders/SeedBuilderTests.cpp - Source/LmbrCentral.cpp - Source/LmbrCentralEditor.cpp -) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_tests_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_tests_files.cmake deleted file mode 100644 index 97e5d87829..0000000000 --- a/Gems/LmbrCentral/Code/lmbrcentral_tests_files.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - Tests/AudioComponentTests.cpp - Tests/AxisAlignedBoxShapeTest.cpp - Tests/BoxShapeTest.cpp - Tests/BundlingSystemComponentTests.cpp - Tests/SphereShapeTest.cpp - Tests/CylinderShapeTest.cpp - Tests/CapsuleShapeTest.cpp - Tests/PolygonPrismShapeTest.cpp - Tests/QuadShapeTest.cpp - Tests/TubeShapeTest.cpp - Tests/LmbrCentralReflectionTest.h - Tests/LmbrCentralReflectionTest.cpp - Tests/LmbrCentralTest.cpp - Tests/ShapeGeometryUtilTest.cpp - Tests/SpawnerComponentTest.cpp - Tests/SplineComponentTests.cpp - Tests/DiskShapeTest.cpp - Tests/ReferenceShapeTests.cpp - Source/LmbrCentral.cpp -) From 0f7e55cf59c633249a6e83a675a4334598856044 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:00:29 -0800 Subject: [PATCH 125/272] Some fixes for paths with spaces (#6757) * Some fixes for paths with spaces Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * PR comments Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../tests/run_python_tests.bat | 59 ------------------- cmake/CommandExecution.cmake | 10 ++-- .../runtime_dependencies_common.cmake.in | 6 +- .../Linux/runtime_dependencies_linux.cmake.in | 4 +- cmake/Platform/Mac/InstallUtils_mac.cmake.in | 58 +++++++++--------- .../Mac/runtime_dependencies_mac.cmake.in | 50 ++++++++-------- python/python.cmd | 3 +- scripts/build/Platform/Linux/build_linux.sh | 2 +- scripts/build/Platform/Mac/build_mac.sh | 2 +- .../build/Platform/Windows/build_windows.cmd | 5 +- scripts/build/ci_build.py | 2 +- 11 files changed, 71 insertions(+), 130 deletions(-) delete mode 100644 Code/Tools/PythonBindingsExample/tests/run_python_tests.bat diff --git a/Code/Tools/PythonBindingsExample/tests/run_python_tests.bat b/Code/Tools/PythonBindingsExample/tests/run_python_tests.bat deleted file mode 100644 index 216f2dd0da..0000000000 --- a/Code/Tools/PythonBindingsExample/tests/run_python_tests.bat +++ /dev/null @@ -1,59 +0,0 @@ -@echo off - -REM -REM Copyright (c) Contributors to the Open 3D Engine Project. -REM For complete copyright and license terms please see the LICENSE at the root of this distribution. -REM -REM SPDX-License-Identifier: Apache-2.0 OR MIT -REM -REM - -PUSHD "%~dp0" - -SET CWD="%~dp0" -SET EXEPATH141="../../../../Bin64vc141/PythonBindingsExample.exe" -SET EXEPATH142="../../../../Bin64vc142/PythonBindingsExample.exe" -SET EXEPATH="" - -IF EXIST %EXEPATH141% ( - SET EXEPATH=%EXEPATH141% -) ELSE ( - IF EXIST %EXEPATH142% ( - SET EXEPATH=%EXEPATH142% - ) ELSE ( - ECHO PythonBindingsExample.exe not found. - ) -) -IF /I %EXEPATH% EQU "" ( - ECHO [FAILED] Could not run tests since a build of PythonBindingsExample.exe is missing - GOTO exit_app -) - -ECHO Testing basics of tool Python bindings in %CWD% - -%EXEPATH% --file test_hello_tool.py -IF %ERRORLEVEL% EQU 0 ( - ECHO [WORKED] test_hello_tool.py -) ELSE ( - ECHO [FAILED] test_hello_tool.py with %ERRORLEVEL% - GOTO exit_app -) - -%EXEPATH% --file test_framework.py --arg entity -IF %ERRORLEVEL% EQU 0 ( - ECHO [WORKED] test_framework.py --arg entity -) ELSE ( - ECHO [FAILED] test_framework.py --arg entity with %ERRORLEVEL% - GOTO exit_app -) - -%EXEPATH% --file test_framework.py --arg math -IF %ERRORLEVEL% EQU 0 ( - ECHO [WORKED] test_framework.py --arg math -) ELSE ( - ECHO [FAILED] test_framework.py --arg math with %ERRORLEVEL% - GOTO exit_app -) - -:exit_app -POPD diff --git a/cmake/CommandExecution.cmake b/cmake/CommandExecution.cmake index 91f043ee9f..a8c21a22a2 100644 --- a/cmake/CommandExecution.cmake +++ b/cmake/CommandExecution.cmake @@ -38,13 +38,13 @@ endif() # Check for timestamp if(LY_TIMESTAMP_REFERENCE) - if(NOT EXISTS ${LY_TIMESTAMP_REFERENCE}) + if(NOT EXISTS "${LY_TIMESTAMP_REFERENCE}") message(FATAL_ERROR "File LY_TIMESTAMP_REFERENCE=${LY_TIMESTAMP_REFERENCE} does not exists") endif() if(NOT LY_TIMESTAMP_FILE) - set(LY_TIMESTAMP_FILE ${LY_TIMESTAMP_REFERENCE}.stamp) + set(LY_TIMESTAMP_FILE "${LY_TIMESTAMP_REFERENCE}.stamp") endif() - if(EXISTS ${LY_TIMESTAMP_FILE} AND NOT ${LY_TIMESTAMP_REFERENCE} IS_NEWER_THAN ${LY_TIMESTAMP_FILE}) + if(EXISTS "${LY_TIMESTAMP_FILE}" AND NOT "${LY_TIMESTAMP_REFERENCE}" IS_NEWER_THAN "${LY_TIMESTAMP_FILE}") # Stamp newer, nothing to do return() endif() @@ -52,7 +52,7 @@ endif() if(LY_LOCK_FILE) # Lock the file - file(LOCK ${LY_LOCK_FILE} TIMEOUT 1200 RESULT_VARIABLE lock_result) + file(LOCK "${LY_LOCK_FILE}" TIMEOUT 1200 RESULT_VARIABLE lock_result) if(NOT ${lock_result} EQUAL 0) message(FATAL_ERROR "Lock failure ${lock_result}") endif() @@ -83,5 +83,5 @@ endif() if(LY_TIMESTAMP_REFERENCE) # Touch the timestamp file - file(TOUCH ${LY_TIMESTAMP_FILE}) + file(TOUCH "${LY_TIMESTAMP_FILE}") endif() diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in index 8717710a3b..a2c3e26ed0 100644 --- a/cmake/Platform/Common/runtime_dependencies_common.cmake.in +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -13,7 +13,7 @@ function(ly_copy source_file target_directory) cmake_path(APPEND target_file "${target_directory}" "${target_filename}") cmake_path(COMPARE "${source_file}" EQUAL "${target_file}" same_location) if(NOT ${same_location}) - file(LOCK ${target_file}.lock GUARD FUNCTION TIMEOUT 300) + file(LOCK "${target_file}.lock" GUARD FUNCTION TIMEOUT 300) file(SIZE "${source_file}" source_file_size) if(EXISTS "${target_file}") file(SIZE "${target_file}" target_file_size) @@ -24,11 +24,11 @@ function(ly_copy source_file target_directory) message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(MAKE_DIRECTORY "${full_target_directory}") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) - file(TOUCH_NOCREATE ${target_file}) + file(TOUCH_NOCREATE "${target_file}") endif() endif() endfunction() @LY_COPY_COMMANDS@ -file(TOUCH @STAMP_OUTPUT_FILE@) +file(TOUCH "@STAMP_OUTPUT_FILE@") diff --git a/cmake/Platform/Linux/runtime_dependencies_linux.cmake.in b/cmake/Platform/Linux/runtime_dependencies_linux.cmake.in index 16445ef8d9..e5d56d1b56 100644 --- a/cmake/Platform/Linux/runtime_dependencies_linux.cmake.in +++ b/cmake/Platform/Linux/runtime_dependencies_linux.cmake.in @@ -14,7 +14,7 @@ function(ly_copy source_file target_directory) cmake_path(APPEND target_file "${target_directory}" "${target_filename}") cmake_path(COMPARE "${source_file}" EQUAL "${target_file}" same_location) if(NOT ${same_location}) - file(LOCK ${target_file}.lock GUARD FUNCTION TIMEOUT 300) + file(LOCK "${target_file}.lock" GUARD FUNCTION TIMEOUT 300) file(SIZE "${source_file}" source_file_size) if(EXISTS "${target_file}") file(SIZE "${target_file}" target_file_size) @@ -39,4 +39,4 @@ endfunction() @LY_COPY_COMMANDS@ -file(TOUCH @STAMP_OUTPUT_FILE@) +file(TOUCH "@STAMP_OUTPUT_FILE@") diff --git a/cmake/Platform/Mac/InstallUtils_mac.cmake.in b/cmake/Platform/Mac/InstallUtils_mac.cmake.in index 89ce4a59f2..3db9903e48 100644 --- a/cmake/Platform/Mac/InstallUtils_mac.cmake.in +++ b/cmake/Platform/Mac/InstallUtils_mac.cmake.in @@ -31,36 +31,36 @@ endfunction() function(fixup_python_framework framework_path) file(REMOVE_RECURSE - ${framework_path}/Versions/Current - ${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/Headers - ${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/Python - ${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/python@LY_PYTHON_VERSION_MAJOR_MINOR@/test - ${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/python@LY_PYTHON_VERSION_MAJOR_MINOR@/site-packages/scipy/io/tests - ${framework_path}/Python - ${framework_path}/Resources - ${framework_path}/Headers + "${framework_path}/Versions/Current" + "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/Headers" + "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/Python" + "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/python@LY_PYTHON_VERSION_MAJOR_MINOR@/test" + "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/lib/python@LY_PYTHON_VERSION_MAJOR_MINOR@/site-packages/scipy/io/tests" + "${framework_path}/Python" + "${framework_path}/Resources" + "${framework_path}/Headers" ) file(GLOB_RECURSE exe_file_list "${framework_path}/**/*.exe") if(exe_file_list) - file(REMOVE_RECURSE ${exe_file_list}) + file(REMOVE_RECURSE "${exe_file_list}") endif() - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink include/python@LY_PYTHON_VERSION_MAJOR_MINOR@m Headers - WORKING_DIRECTORY ${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@ + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink include/python@LY_PYTHON_VERSION_MAJOR_MINOR@m Headers + WORKING_DIRECTORY "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink @LY_PYTHON_VERSION_MAJOR_MINOR@ Current - WORKING_DIRECTORY ${framework_path}/Versions/ + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink @LY_PYTHON_VERSION_MAJOR_MINOR@ Current + WORKING_DIRECTORY "${framework_path}/Versions/" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Python Python - WORKING_DIRECTORY ${framework_path} + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Python Python + WORKING_DIRECTORY "${framework_path}" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers - WORKING_DIRECTORY ${framework_path} + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Headers Headers + WORKING_DIRECTORY "${framework_path}" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources Resources - WORKING_DIRECTORY ${framework_path} + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Resources Resources + WORKING_DIRECTORY "${framework_path}" ) - file(CHMOD ${framework_path}/Versions/Current/Python + file(CHMOD "${framework_path}/Versions/Current/Python" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) @@ -72,7 +72,7 @@ function(codesign_file file entitlement_file) return() endif() - if(EXISTS ${entitlement_file}) + if(EXISTS "${entitlement_file}") execute_process(COMMAND "/usr/bin/codesign" "--force" "--sign" "@LY_CODE_SIGN_IDENTITY@" "--deep" "-o" "runtime" "--timestamp" "--entitlements" "${entitlement_file}" "${file}" TIMEOUT 300 @@ -108,8 +108,8 @@ function(codesign_python_framework_binaries framework_path) "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@/Resources/**") foreach(file ${files}) - if(NOT EXISTS ${file}) - file(REMOVE ${file}) + if(NOT EXISTS "${file}") + file(REMOVE "${file}") continue() endif() cmake_path(SET path_var "${file}") @@ -164,16 +164,16 @@ function(ly_copy source_file target_directory) endfunction() function(ly_download_and_codesign_sdk_python) - execute_process(COMMAND ${CMAKE_COMMAND} -DPAL_PLATFORM_NAME=Mac -DLY_3RDPARTY_PATH=${CMAKE_INSTALL_PREFIX}/python -P ${CMAKE_INSTALL_PREFIX}/python/get_python.cmake - WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX} + execute_process(COMMAND "${CMAKE_COMMAND}" -DPAL_PLATFORM_NAME=Mac "-DLY_3RDPARTY_PATH=${CMAKE_INSTALL_PREFIX}/python" -P "${CMAKE_INSTALL_PREFIX}/python/get_python.cmake" + WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" ) - fixup_python_framework(${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework) - codesign_python_framework_binaries(${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework) - codesign_file(${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework @LY_ROOT_FOLDER@/python/Platform/Mac/PythonEntitlements.plist) + fixup_python_framework("${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework") + codesign_python_framework_binaries("${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework") + codesign_file("${CMAKE_INSTALL_PREFIX}/python/runtime/@LY_PYTHON_PACKAGE_NAME@/Python.framework" "@LY_ROOT_FOLDER@/python/Platform/Mac/PythonEntitlements.plist") endfunction() function(ly_codesign_sdk) - codesign_file(${LY_INSTALL_PATH_ORIGINAL}/O3DE_SDK.app "none") + codesign_file("${LY_INSTALL_PATH_ORIGINAL}/O3DE_SDK.app" "none") endfunction() diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 892a90640f..51e6e5830c 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -127,7 +127,7 @@ function(ly_copy source_file target_directory) if(NOT is_framework) # if it is a bundle, there is no contention about the files in the destination, each bundle target will copy everything # we dont want these files to invalidate the bundle and cause a new signature - file(LOCK ${target_file}.lock GUARD FUNCTION TIMEOUT 300) + file(LOCK "${target_file}.lock" GUARD FUNCTION TIMEOUT 300) file(SIZE "${source_file}" source_file_size) if(EXISTS "${target_file}") file(SIZE "${target_file}" target_file_size) @@ -176,35 +176,35 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") message(STATUS "Fixing ${bundle_path}/Contents/Frameworks/Python.framework...") list(APPEND fixup_bundle_ignore Python python3.7m python3.7) file(REMOVE_RECURSE - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Headers - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/Python - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests - ${bundle_path}/Contents/Frameworks/Python.framework/Python - ${bundle_path}/Contents/Frameworks/Python.framework/Resources - ${bundle_path}/Contents/Frameworks/Python.framework/Headers + "${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current" + "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Headers" + "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/Python" + "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test" + "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests" + "${bundle_path}/Contents/Frameworks/Python.framework/Python" + "${bundle_path}/Contents/Frameworks/Python.framework/Resources" + "${bundle_path}/Contents/Frameworks/Python.framework/Headers" ) file(GLOB_RECURSE exe_file_list "${bundle_path}/Contents/Frameworks/Python.framework/**/*.exe") if(exe_file_list) - file(REMOVE_RECURSE ${exe_file_list}) + file(REMOVE_RECURSE "${exe_file_list}") endif() - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink include/python3.7m Headers - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7 + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink include/python3.7m Headers + WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink 3.7 Current + WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework/Versions/" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Python Python - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Python Python + WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Headers Headers + WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework" ) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources Resources - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink Versions/Current/Resources Resources + WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework" ) - file(CHMOD ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current/Python + file(CHMOD "${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current/Python" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) endif() @@ -215,8 +215,8 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") file(TOUCH "${fixup_timestamp_file}") # fixup bundle ends up removing the rpath of dxc (despite we exclude it) - if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) - execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) + if(EXISTS "${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7") + execute_process(COMMAND $"{LY_INSTALL_NAME_TOOL}" -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) endif() # misplaced .DS_Store files can cause signing to fail @@ -226,7 +226,7 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") "${bundle_path/}**/*.cstemp" ) if(remove_file_list) - file(REMOVE_RECURSE ${remove_file_list}) + file(REMOVE_RECURSE "${remove_file_list}") endif() endif() @@ -235,7 +235,7 @@ else() # Non-bundle case if(depends_on_python) # RPATH fix python - execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -change @rpath/Python @rpath/Python.framework/Versions/Current/Python @target_file@) + execute_process(COMMAND "${LY_INSTALL_NAME_TOOL}" -change @rpath/Python @rpath/Python.framework/Versions/Current/Python "@target_file@") endif() endif() diff --git a/python/python.cmd b/python/python.cmd index 70c79e6789..28138fd699 100644 --- a/python/python.cmd +++ b/python/python.cmd @@ -21,7 +21,8 @@ SET PYTHONHOME=%CMD_DIR%\runtime\python-3.7.10-rev2-windows\python IF EXIST "%PYTHONHOME%" GOTO PYTHONHOME_EXISTS -ECHO Could not find Python for Windows in %CMD_DIR%\.. +ECHO Python not found in %CMD_DIR% +ECHO Try running %CMD_DIR%\get_python.bat first. exit /B 1 :PYTHONHOME_EXISTS diff --git a/scripts/build/Platform/Linux/build_linux.sh b/scripts/build/Platform/Linux/build_linux.sh index 2f33827c5b..ce84ec1749 100755 --- a/scripts/build/Platform/Linux/build_linux.sh +++ b/scripts/build/Platform/Linux/build_linux.sh @@ -17,7 +17,7 @@ SOURCE_DIRECTORY=${PWD} pushd $OUTPUT_DIRECTORY LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS}" +CONFIGURE_CMD="cmake '${SOURCE_DIRECTORY}' ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS}" if [[ -n "$CMAKE_LY_PROJECTS" ]]; then CONFIGURE_CMD="${CONFIGURE_CMD} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" fi diff --git a/scripts/build/Platform/Mac/build_mac.sh b/scripts/build/Platform/Mac/build_mac.sh index d6a66fc6c6..e0cb1ba889 100755 --- a/scripts/build/Platform/Mac/build_mac.sh +++ b/scripts/build/Platform/Mac/build_mac.sh @@ -17,7 +17,7 @@ SOURCE_DIRECTORY=${PWD} pushd $OUTPUT_DIRECTORY LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS}" +CONFIGURE_CMD="cmake '${SOURCE_DIRECTORY}' ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS}" if [[ -n "$CMAKE_LY_PROJECTS" ]]; then CONFIGURE_CMD="${CONFIGURE_CMD} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" fi diff --git a/scripts/build/Platform/Windows/build_windows.cmd b/scripts/build/Platform/Windows/build_windows.cmd index 9e9b124adb..798550370f 100644 --- a/scripts/build/Platform/Windows/build_windows.cmd +++ b/scripts/build/Platform/Windows/build_windows.cmd @@ -8,8 +8,7 @@ REM REM SETLOCAL EnableDelayedExpansion - -CALL %~dp0env_windows.cmd +CALL "%~dp0env_windows.cmd" IF NOT EXIST "%OUTPUT_DIRECTORY%" ( MKDIR %OUTPUT_DIRECTORY%. @@ -29,7 +28,7 @@ REM Compute half the amount of processors so some jobs can run SET /a HALF_PROCESSORS = NUMBER_OF_PROCESSORS / 2 SET LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -SET CONFIGURE_CMD=cmake %SOURCE_DIRECTORY% %CMAKE_OPTIONS% %EXTRA_CMAKE_OPTIONS% +SET CONFIGURE_CMD=cmake "%SOURCE_DIRECTORY%" %CMAKE_OPTIONS% %EXTRA_CMAKE_OPTIONS% IF NOT "%CMAKE_LY_PROJECTS%"=="" ( SET CONFIGURE_CMD=!CONFIGURE_CMD! -DLY_PROJECTS="%CMAKE_LY_PROJECTS%" ) diff --git a/scripts/build/ci_build.py b/scripts/build/ci_build.py index c35a5e9dbf..78978349c3 100755 --- a/scripts/build/ci_build.py +++ b/scripts/build/ci_build.py @@ -88,7 +88,7 @@ def build(build_config_filename, build_platform, build_type): env_params[v] = build_params[v] print(' {} = {} {}'.format(v, env_params[v], '(environment override)' if existing_param else '')) print('--------------------------------------------------------------------------------', flush=True) - process_return = subprocess.run(build_cmd_path, cwd=cwd_dir, env=env_params) + process_return = subprocess.run([build_cmd_path], cwd=cwd_dir, env=env_params) print('--------------------------------------------------------------------------------') if process_return.returncode != 0: print('[ci_build] FAIL: Command {} returned {}'.format(build_cmd_path, process_return.returncode), flush=True) From 5c0ba0253d25a9a12f91d23e36a0dc10f95de0c7 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:01:17 -0800 Subject: [PATCH 126/272] git.ignore cleanup (#6760) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .gitignore | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 9012ec7576..2820d1e1c1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,18 +2,14 @@ .vs/ .vscode/ __pycache__ -AssetProcessorTemp/** [Bb]uild/ [Oo]ut/** CMakeUserPresets.json [Cc]ache/ /[Ii]nstall/ -Editor/EditorEventLog.xml -Editor/EditorLayout.xml **/*egg-info/** **/*egg-link **/[Rr]estricted -UserSettings.xml [Uu]ser/ FrameCapture/** .DS_Store @@ -22,9 +18,6 @@ client*.cfg server*.cfg .mayaSwatches/ _savebackup/ -#Output folder for test results when running Automated Tests -TestResults/** *.swatches /imgui.ini -/scripts/project_manager/logs/ -/AutomatedTesting/Gem/PythonTests/scripting/TestResults + From e4c04c1915c05aad3e1305f2b6aeac015de9131e Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:03:32 -0600 Subject: [PATCH 127/272] Removing redundant Editor test Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/smoke/CMakeLists.txt | 13 -- .../smoke/Editor_NewExistingLevels_Works.py | 143 ------------------ .../test_Editor_NewExistingLevels_Works.py | 34 ----- 3 files changed, 190 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py delete mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index 5d0808adb6..69d411536f 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -31,19 +31,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) Smoke ) - ly_add_pytest( - NAME AutomatedTesting::EditorTestWithGPU - TEST_REQUIRES gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/test_Editor_NewExistingLevels_Works.py - TIMEOUT 100 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - AZ::PythonBindingsExample - Legacy::Editor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - ) - ly_add_pytest( NAME AutomatedTesting::GameLauncherWithGPU TEST_SUITE sandbox diff --git a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py deleted file mode 100644 index 71956488fc..0000000000 --- a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT - - -Test Case Title: Create Test for UI apps- Editor -""" - - -class Tests(): - level_created = ("Level created", "Failed to create level") - entity_found = ("New Entity created in level", "Failed to create New Entity in level") - mesh_added = ("Mesh Component added", "Failed to add Mesh Component") - enter_game_mode = ("Game Mode successfully entered", "Failed to enter in Game Mode") - exit_game_mode = ("Game Mode successfully exited", "Failed to exit in Game Mode") - level_opened = ("Level opened successfully", "Failed to open level") - level_exported = ("Level exported successfully", "Failed to export level") - mesh_removed = ("Mesh Component removed", "Failed to remove Mesh Component") - entity_deleted = ("Entity deleted", "Failed to delete Entity") - level_edits_present = ("Level edits persist after saving", "Failed to save level edits after saving") - - -def Editor_NewExistingLevels_Works(): - """ - Summary: Perform the below operations on Editor - - 1) Launch & Close editor - 2) Create new level - 3) Saving and loading levels - 4) Level edits persist after saving - 5) Export Level - 6) Can switch to play mode (ctrl+g) and exit that - 7) Run editor python bindings test - 8) Create an Entity - 9) Delete an Entity - 10) Add a component to an Entity - - Expected Behavior: - All operations succeed and do not cause a crash - - Test Steps: - 1) Launch editor and Create a new level - 2) Create a new entity - 3) Add Mesh component - 4) Verify enter/exit game mode - 5) Save, Load and Export level - 6) Remove Mesh component - 7) Delete entity - 8) Open an existing level - 9) Create a new entity in an existing level - 10) Save, Load and Export an existing level and close editor - - Note: - - This test file must be called from the O3DE Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - import os - import editor_python_test_tools.hydra_editor_utils as hydra - from editor_python_test_tools.utils import TestHelper as helper - from editor_python_test_tools.utils import Report - import azlmbr.bus as bus - import azlmbr.editor as editor - import azlmbr.legacy.general as general - import azlmbr.math as math - - # 1) Launch editor and Create a new level - helper.init_idle() - test_level_name = "temp_level" - general.create_level_no_prompt(test_level_name, 128, 1, 128, False) - helper.wait_for_condition(lambda: general.get_current_level_name() == test_level_name, 2.0) - Report.result(Tests.level_created, general.get_current_level_name() == test_level_name) - - # 2) Create a new entity - entity_position = math.Vector3(200.0, 200.0, 38.0) - new_entity = hydra.Entity("Entity1") - new_entity.create_entity(entity_position, []) - test_entity = hydra.find_entity_by_name("Entity1") - Report.result(Tests.entity_found, test_entity.IsValid()) - - # 3) Add Mesh component - new_entity.add_component("Mesh") - Report.result(Tests.mesh_added, hydra.has_components(new_entity.id, ["Mesh"])) - - # 4) Verify enter/exit game mode - helper.enter_game_mode(Tests.enter_game_mode) - helper.exit_game_mode(Tests.exit_game_mode) - - # 5) Save, Load and Export level - # Save Level - general.save_level() - # Open Level - general.open_level(test_level_name) - Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) - # Export Level - general.export_to_engine() - level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak") - Report.result(Tests.level_exported, os.path.exists(level_pak_file)) - - # 6) Remove Mesh component - new_entity.remove_component("Mesh") - Report.result(Tests.mesh_removed, not hydra.has_components(new_entity.id, ["Mesh"])) - - # 7) Delete entity - editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", new_entity.id) - test_entity = hydra.find_entity_by_name("Entity1") - Report.result(Tests.entity_deleted, len(test_entity) == 0) - - # 8) Open an existing level - general.open_level(test_level_name) - Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) - - # 9) Create a new entity in an existing level - entity_position = math.Vector3(200.0, 200.0, 38.0) - new_entity_2 = hydra.Entity("Entity2") - new_entity_2.create_entity(entity_position, []) - test_entity = hydra.find_entity_by_name("Entity2") - Report.result(Tests.entity_found, test_entity.IsValid()) - - # 10) Save, Load and Export an existing level - # Save Level - general.save_level() - # Open Level - general.open_level(test_level_name) - Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) - entity_id = hydra.find_entity_by_name(new_entity_2.name) - Report.result(Tests.level_edits_present, entity_id == new_entity_2.id) - # Export Level - general.export_to_engine() - level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak") - Report.result(Tests.level_exported, os.path.exists(level_pak_file)) - - -if __name__ == "__main__": - - from editor_python_test_tools.utils import Report - - Report.start_test(Editor_NewExistingLevels_Works) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py deleted file mode 100644 index 5caf7744c4..0000000000 --- a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT - - -Test should run in both gpu and non gpu -""" - -import pytest -import os -from automatedtesting_shared.base import TestAutomationBase - -import ly_test_tools -import ly_test_tools.environment.file_system as file_system - - -@pytest.mark.SUITE_smoke -@pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Only succeeds on windows https://github.com/o3de/o3de/issues/5539") -@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("level", ["temp_level"]) -class TestAutomation(TestAutomationBase): - def test_Editor_NewExistingLevels_Works(self, request, workspace, editor, level, project, launcher_platform): - def teardown(): - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) - - from . import Editor_NewExistingLevels_Works as test_module - - self._run_test(request, workspace, editor, test_module, enable_prefab_system=False) From 5aa7d56f1a75a0f3bdc0fef569d0f421a868d1da Mon Sep 17 00:00:00 2001 From: LesaelR <89800757+LesaelR@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:15:43 -0800 Subject: [PATCH 128/272] LYN-8935 Bundle Mode Test Update (#6606) * Updating Bundle_Mode_Tests to replace level.pak for .spawnable Signed-off-by: Rosario Cox * Removing old TestDependenciesLevel files and replacing for TestDepencenciesLevel.prefab Signed-off-by: Rosario Cox * Adding missing file Signed-off-by: Rosario Cox --- .../bundle_mode_tests.py | 5 +- .../LevelData/Environment.xml | 14 - .../LevelData/TerrainTexture.xml | 7 - .../LevelData/TimeOfDay.xml | 356 ----------- .../LevelData/VegetationMap.dat | 3 - .../TestDependenciesLevel/TerrainTexture.pak | 3 - .../TestDependenciesLevel.ly | 3 - .../TestDependenciesLevel.prefab | 555 ++++++++++++++++++ .../Levels/TestDependenciesLevel/filelist.xml | 6 - .../Levels/TestDependenciesLevel/level.pak | 3 - 10 files changed, 557 insertions(+), 398 deletions(-) delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly create mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml delete mode 100644 AutomatedTesting/Levels/TestDependenciesLevel/level.pak diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py index af92bb1773..b2252567b6 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py @@ -23,12 +23,11 @@ from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeo @pytest.mark.SUITE_periodic @pytest.mark.parametrize('launcher_platform', ['windows_editor']) @pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['auto_test']) +@pytest.mark.parametrize('level', ['TestDependenciesLevel']) class TestBundleMode(object): def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform, asset_processor, workspace, bundler_batch_helper): - level_pak = os.path.join("levels", level, "level.pak") - + level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable") bundles_folder = os.path.join(workspace.paths.project(), "Bundles") bundle_request_path = os.path.join(bundles_folder, "bundle.pak") bundle_result_path = os.path.join(bundles_folder, diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml deleted file mode 100644 index 4ba36f66ae..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Environment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml deleted file mode 100644 index f43df05b22..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TerrainTexture.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml deleted file mode 100644 index c5b404318e..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/TimeOfDay.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat deleted file mode 100644 index dce5631cd0..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/VegetationMap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9 -size 63 diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak b/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak deleted file mode 100644 index fe3604a050..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/TerrainTexture.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85 -size 22 diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly deleted file mode 100644 index 95cc91cd6b..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.ly +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:825828fe7c183e765315f933a8b1eb25283739d34d62cb84c34e2dcb56591d6e -size 12415 diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab new file mode 100644 index 0000000000..cf30cb178c --- /dev/null +++ b/AutomatedTesting/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab @@ -0,0 +1,555 @@ +{ + "ContainerEntity": { + "Id": "Entity_[1146574390643]", + "Name": "Level", + "Components": { + "Component_[10641544592923449938]": { + "$type": "EditorInspectorComponent", + "Id": 10641544592923449938 + }, + "Component_[12039882709170782873]": { + "$type": "EditorOnlyEntityComponent", + "Id": 12039882709170782873 + }, + "Component_[12265484671603697631]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12265484671603697631 + }, + "Component_[14126657869720434043]": { + "$type": "EditorEntitySortComponent", + "Id": 14126657869720434043, + "Child Entity Order": [ + "Entity_[1176639161715]" + ] + }, + "Component_[15230859088967841193]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 15230859088967841193, + "Parent Entity": "" + }, + "Component_[16239496886950819870]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 16239496886950819870 + }, + "Component_[5688118765544765547]": { + "$type": "EditorEntityIconComponent", + "Id": 5688118765544765547 + }, + "Component_[6545738857812235305]": { + "$type": "SelectionComponent", + "Id": 6545738857812235305 + }, + "Component_[7247035804068349658]": { + "$type": "EditorPrefabComponent", + "Id": 7247035804068349658 + }, + "Component_[9307224322037797205]": { + "$type": "EditorLockComponent", + "Id": 9307224322037797205 + }, + "Component_[9562516168917670048]": { + "$type": "EditorVisibilityComponent", + "Id": 9562516168917670048 + } + } + }, + "Entities": { + "Entity_[1155164325235]": { + "Id": "Entity_[1155164325235]", + "Name": "Sun", + "Components": { + "Component_[10440557478882592717]": { + "$type": "SelectionComponent", + "Id": 10440557478882592717 + }, + "Component_[13620450453324765907]": { + "$type": "EditorLockComponent", + "Id": 13620450453324765907 + }, + "Component_[2134313378593666258]": { + "$type": "EditorInspectorComponent", + "Id": 2134313378593666258 + }, + "Component_[234010807770404186]": { + "$type": "EditorVisibilityComponent", + "Id": 234010807770404186 + }, + "Component_[2970359110423865725]": { + "$type": "EditorEntityIconComponent", + "Id": 2970359110423865725 + }, + "Component_[3722854130373041803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3722854130373041803 + }, + "Component_[5992533738676323195]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5992533738676323195 + }, + "Component_[7378860763541895402]": { + "$type": "AZ::Render::EditorDirectionalLightComponent", + "Id": 7378860763541895402, + "Controller": { + "Configuration": { + "Intensity": 1.0, + "CameraEntityId": "", + "ShadowFilterMethod": 1 + } + } + }, + "Component_[7892834440890947578]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7892834440890947578, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 13.487043380737305 + ], + "Rotate": [ + -76.13099670410156, + -0.847000002861023, + -15.8100004196167 + ] + } + }, + "Component_[8599729549570828259]": { + "$type": "EditorEntitySortComponent", + "Id": 8599729549570828259 + }, + "Component_[952797371922080273]": { + "$type": "EditorPendingCompositionComponent", + "Id": 952797371922080273 + } + } + }, + "Entity_[1159459292531]": { + "Id": "Entity_[1159459292531]", + "Name": "Ground", + "Components": { + "Component_[11701138785793981042]": { + "$type": "SelectionComponent", + "Id": 11701138785793981042 + }, + "Component_[12260880513256986252]": { + "$type": "EditorEntityIconComponent", + "Id": 12260880513256986252 + }, + "Component_[13711420870643673468]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 13711420870643673468 + }, + "Component_[138002849734991713]": { + "$type": "EditorOnlyEntityComponent", + "Id": 138002849734991713 + }, + "Component_[16578565737331764849]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16578565737331764849, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[16919232076966545697]": { + "$type": "EditorInspectorComponent", + "Id": 16919232076966545697 + }, + "Component_[5182430712893438093]": { + "$type": "EditorMaterialComponent", + "Id": 5182430712893438093 + }, + "Component_[5675108321710651991]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 5675108321710651991, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}", + "subId": 277889906 + }, + "assetHint": "objects/groudplane/groundplane_512x512m.azmodel" + } + } + } + }, + "Component_[5681893399601237518]": { + "$type": "EditorEntitySortComponent", + "Id": 5681893399601237518 + }, + "Component_[592692962543397545]": { + "$type": "EditorPendingCompositionComponent", + "Id": 592692962543397545 + }, + "Component_[7090012899106946164]": { + "$type": "EditorLockComponent", + "Id": 7090012899106946164 + }, + "Component_[9410832619875640998]": { + "$type": "EditorVisibilityComponent", + "Id": 9410832619875640998 + } + } + }, + "Entity_[1163754259827]": { + "Id": "Entity_[1163754259827]", + "Name": "Camera", + "Components": { + "Component_[11895140916889160460]": { + "$type": "EditorEntityIconComponent", + "Id": 11895140916889160460 + }, + "Component_[16880285896855930892]": { + "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent", + "Id": 16880285896855930892, + "Controller": { + "Configuration": { + "Field of View": 55.0, + "EditorEntityId": 3342481886060234850 + } + } + }, + "Component_[17187464423780271193]": { + "$type": "EditorLockComponent", + "Id": 17187464423780271193 + }, + "Component_[17495696818315413311]": { + "$type": "EditorEntitySortComponent", + "Id": 17495696818315413311 + }, + "Component_[18086214374043522055]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18086214374043522055, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + -2.3000001907348633, + -3.9368600845336914, + 1.0 + ], + "Rotate": [ + -2.050307512283325, + 1.9552897214889526, + -43.623355865478516 + ] + } + }, + "Component_[18387556550380114975]": { + "$type": "SelectionComponent", + "Id": 18387556550380114975 + }, + "Component_[2654521436129313160]": { + "$type": "EditorVisibilityComponent", + "Id": 2654521436129313160 + }, + "Component_[5265045084611556958]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5265045084611556958 + }, + "Component_[7169798125182238623]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7169798125182238623 + }, + "Component_[7255796294953281766]": { + "$type": "GenericComponentWrapper", + "Id": 7255796294953281766, + "m_template": { + "$type": "FlyCameraInputComponent" + } + }, + "Component_[8866210352157164042]": { + "$type": "EditorInspectorComponent", + "Id": 8866210352157164042 + }, + "Component_[9129253381063760879]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9129253381063760879 + } + } + }, + "Entity_[1168049227123]": { + "Id": "Entity_[1168049227123]", + "Name": "Grid", + "Components": { + "Component_[11443347433215807130]": { + "$type": "EditorEntityIconComponent", + "Id": 11443347433215807130 + }, + "Component_[11779275529534764488]": { + "$type": "SelectionComponent", + "Id": 11779275529534764488 + }, + "Component_[14249419413039427459]": { + "$type": "EditorInspectorComponent", + "Id": 14249419413039427459 + }, + "Component_[15448581635946161318]": { + "$type": "AZ::Render::EditorGridComponent", + "Id": 15448581635946161318, + "Controller": { + "Configuration": { + "primarySpacing": 4.0, + "primaryColor": [ + 0.501960813999176, + 0.501960813999176, + 0.501960813999176 + ], + "secondarySpacing": 0.5, + "secondaryColor": [ + 0.250980406999588, + 0.250980406999588, + 0.250980406999588 + ] + } + } + }, + "Component_[1843303322527297409]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 1843303322527297409 + }, + "Component_[380249072065273654]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 380249072065273654, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[7476660583684339787]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7476660583684339787 + }, + "Component_[7557626501215118375]": { + "$type": "EditorEntitySortComponent", + "Id": 7557626501215118375 + }, + "Component_[7984048488947365511]": { + "$type": "EditorVisibilityComponent", + "Id": 7984048488947365511 + }, + "Component_[8118181039276487398]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8118181039276487398 + }, + "Component_[9189909764215270515]": { + "$type": "EditorLockComponent", + "Id": 9189909764215270515 + } + } + }, + "Entity_[1172344194419]": { + "Id": "Entity_[1172344194419]", + "Name": "Shader Ball", + "Components": { + "Component_[10789351944715265527]": { + "$type": "EditorOnlyEntityComponent", + "Id": 10789351944715265527 + }, + "Component_[12037033284781049225]": { + "$type": "EditorEntitySortComponent", + "Id": 12037033284781049225 + }, + "Component_[13759153306105970079]": { + "$type": "EditorPendingCompositionComponent", + "Id": 13759153306105970079 + }, + "Component_[14135560884830586279]": { + "$type": "EditorInspectorComponent", + "Id": 14135560884830586279 + }, + "Component_[16247165675903986673]": { + "$type": "EditorVisibilityComponent", + "Id": 16247165675903986673 + }, + "Component_[18082433625958885247]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 18082433625958885247 + }, + "Component_[6472623349872972660]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6472623349872972660, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Rotate": [ + 0.0, + 0.10000000149011612, + 180.0 + ] + } + }, + "Component_[6495255223970673916]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 6495255223970673916, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}", + "subId": 281415304 + }, + "assetHint": "objects/shaderball/shaderball_default_1m.azmodel" + } + } + } + }, + "Component_[8056625192494070973]": { + "$type": "SelectionComponent", + "Id": 8056625192494070973 + }, + "Component_[8550141614185782969]": { + "$type": "EditorEntityIconComponent", + "Id": 8550141614185782969 + }, + "Component_[9439770997198325425]": { + "$type": "EditorLockComponent", + "Id": 9439770997198325425 + } + } + }, + "Entity_[1176639161715]": { + "Id": "Entity_[1176639161715]", + "Name": "Atom Default Environment", + "Components": { + "Component_[10757302973393310045]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 10757302973393310045, + "Parent Entity": "Entity_[1146574390643]" + }, + "Component_[14505817420424255464]": { + "$type": "EditorInspectorComponent", + "Id": 14505817420424255464, + "ComponentOrderEntryArray": [ + { + "ComponentId": 10757302973393310045 + } + ] + }, + "Component_[14988041764659020032]": { + "$type": "EditorLockComponent", + "Id": 14988041764659020032 + }, + "Component_[15808690248755038124]": { + "$type": "SelectionComponent", + "Id": 15808690248755038124 + }, + "Component_[15900837685796817138]": { + "$type": "EditorVisibilityComponent", + "Id": 15900837685796817138 + }, + "Component_[3298767348226484884]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3298767348226484884 + }, + "Component_[4076975109609220594]": { + "$type": "EditorPendingCompositionComponent", + "Id": 4076975109609220594 + }, + "Component_[5679760548946028854]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5679760548946028854 + }, + "Component_[5855590796136709437]": { + "$type": "EditorEntitySortComponent", + "Id": 5855590796136709437, + "Child Entity Order": [ + "Entity_[1155164325235]", + "Entity_[1180934129011]", + "Entity_[1172344194419]", + "Entity_[1168049227123]", + "Entity_[1163754259827]", + "Entity_[1159459292531]" + ] + }, + "Component_[9277695270015777859]": { + "$type": "EditorEntityIconComponent", + "Id": 9277695270015777859 + } + } + }, + "Entity_[1180934129011]": { + "Id": "Entity_[1180934129011]", + "Name": "Global Sky", + "Components": { + "Component_[11231930600558681245]": { + "$type": "AZ::Render::EditorHDRiSkyboxComponent", + "Id": 11231930600558681245, + "Controller": { + "Configuration": { + "CubemapAsset": { + "assetId": { + "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}", + "subId": 1000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage" + } + } + } + }, + "Component_[11980494120202836095]": { + "$type": "SelectionComponent", + "Id": 11980494120202836095 + }, + "Component_[1428633914413949476]": { + "$type": "EditorLockComponent", + "Id": 1428633914413949476 + }, + "Component_[14936200426671614999]": { + "$type": "AZ::Render::EditorImageBasedLightComponent", + "Id": 14936200426671614999, + "Controller": { + "Configuration": { + "diffuseImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 3000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage" + }, + "specularImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 2000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage" + } + } + } + }, + "Component_[14994774102579326069]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 14994774102579326069 + }, + "Component_[15417479889044493340]": { + "$type": "EditorPendingCompositionComponent", + "Id": 15417479889044493340 + }, + "Component_[15826613364991382688]": { + "$type": "EditorEntitySortComponent", + "Id": 15826613364991382688 + }, + "Component_[1665003113283562343]": { + "$type": "EditorOnlyEntityComponent", + "Id": 1665003113283562343 + }, + "Component_[3704934735944502280]": { + "$type": "EditorEntityIconComponent", + "Id": 3704934735944502280 + }, + "Component_[5698542331457326479]": { + "$type": "EditorVisibilityComponent", + "Id": 5698542331457326479 + }, + "Component_[6644513399057217122]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6644513399057217122, + "Parent Entity": "Entity_[1176639161715]" + }, + "Component_[931091830724002070]": { + "$type": "EditorInspectorComponent", + "Id": 931091830724002070 + } + } + } + }, + "Instances": { + "Instance_[425258647110]": { + "Source": "assets/simple_pot_fbx.procprefab" + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml b/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml deleted file mode 100644 index b5164a4aee..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/filelist.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/level.pak b/AutomatedTesting/Levels/TestDependenciesLevel/level.pak deleted file mode 100644 index dfba7fb4e3..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/level.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2611b691998640a0e802461f47b5b876f6832fbece62d34cc25da53e135e1c38 -size 44525 From 8e2e2d96c50bca2a9210f13df1fdd910193e80be Mon Sep 17 00:00:00 2001 From: LesaelR <89800757+LesaelR@users.noreply.github.com> Date: Mon, 10 Jan 2022 10:15:51 -0800 Subject: [PATCH 129/272] Updating asset_bundler_batch_tests to Prefab/Spawnables instead of Level.pak (#6679) * Replaced TestDependenciesLevel's level.pak for TestDependenciesLevel.prefab to fix asset_bundler_batch_tests failure Updated asset_bundler_batch_tests to reflect the update. Signed-off-by: Rosario Cox * Missed one of the .spawnables changes Signed-off-by: Rosario Cox --- .../asset_processor_tests/asset_bundler_batch_tests.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py index f5e5642573..f64427f6df 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py @@ -108,7 +108,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ helper = bundler_batch_helper seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list - asset = r"levels\testdependencieslevel\level.pak" + asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable" # Create Asset list helper.call_assetLists( @@ -191,7 +191,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ helper = bundler_batch_helper seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list - asset = r"levels\testdependencieslevel\level.pak" + asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable" # Useful bundle locations / names (2 for comparing contents) # fmt:off @@ -924,7 +924,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # Create a seed file helper.call_seeds( seedListFile=helper["seed_list_file"], - addSeed=r"levels\testdependencieslevel\level.pak", + addSeed=r"levels\testdependencieslevel\testdependencieslevel.spawnable", platform="pc", ) @@ -947,9 +947,9 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # Specifying platform but not "add" or "remove" should fail result, _ = helper.call_assetLists( assetListFile=helper["asset_info_file_request"], + allowOverwrites="", seedListFile=helper["seed_list_file"], platform="pc", - allowOverwrites="", ) assert result, "Overwriting with override threw an error" @@ -982,7 +982,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False)) bundles_folder = os.path.join(workspace.paths.project(), "Bundles") - level_pak = r"levels\testdependencieslevel\level.pak" + level_pak = r"levels\testdependencieslevel\testdependencieslevel.spawnable" bundle_request_path = os.path.join(bundles_folder, "bundle.pak") bundle_result_path = os.path.join(bundles_folder, helper.platform_file_name("bundle.pak", workspace.asset_processor_platform)) From df7a2fbd9d8e07f2d6786c1927eeddab2f05513e Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:11:15 -0800 Subject: [PATCH 130/272] Add better error handling for failed loading of the LyShine shader (#6761) Signed-off-by: abrmich --- .../DynamicDraw/DynamicDrawContext.cpp | 6 ++- Gems/LyShine/Code/Source/Draw2d.cpp | 47 +++++++++++-------- Gems/LyShine/Code/Source/UiRenderer.cpp | 4 +- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp index 3b3473a2da..47791d3002 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/DynamicDraw/DynamicDrawContext.cpp @@ -141,6 +141,7 @@ namespace AZ void DynamicDrawContext::InitVertexFormat(const AZStd::vector& vertexChannels) { AZ_Assert(!m_initialized, "Can't call InitVertexFormat after context was initialized (EndInit was called)"); + AZ_Assert(m_pipelineState, "Can't call InitVertexFormat before InitShader is called with a valid shader"); m_perVertexDataSize = 0; RHI::InputStreamLayoutBuilder layoutBuilder; @@ -150,7 +151,10 @@ namespace AZ bufferBuilder->Channel(channel.m_channel, channel.m_format); m_perVertexDataSize += RHI::GetFormatSize(channel.m_format); } - m_pipelineState->InputStreamLayout() = layoutBuilder.End(); + if (m_pipelineState) + { + m_pipelineState->InputStreamLayout() = layoutBuilder.End(); + } } void DynamicDrawContext::InitDrawListTag(RHI::DrawListTag drawListTag) diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index 917c1bb168..2838ed4877 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -122,27 +122,34 @@ void CDraw2d::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) } m_dynamicDraw->EndInit(); - // Cache draw srg input indices for later use - static const char textureIndexName[] = "m_texture"; - static const char worldToProjIndexName[] = "m_worldToProj"; - AZ::Data::Instance drawSrg = m_dynamicDraw->NewDrawSrg(); - const AZ::RHI::ShaderResourceGroupLayout* layout = drawSrg->GetLayout(); - m_shaderData.m_imageInputIndex = layout->FindShaderInputImageIndex(AZ::Name(textureIndexName)); - AZ_Error("Draw2d", m_shaderData.m_imageInputIndex.IsValid(), "Failed to find shader input constant %s.", - textureIndexName); - m_shaderData.m_viewProjInputIndex = layout->FindShaderInputConstantIndex(AZ::Name(worldToProjIndexName)); - AZ_Error("Draw2d", m_shaderData.m_viewProjInputIndex.IsValid(), "Failed to find shader input constant %s.", - worldToProjIndexName); + // Check that the dynamic draw context has been initialized appropriately + if (m_dynamicDraw->IsReady()) + { + // Cache draw srg input indices for later use + static const char textureIndexName[] = "m_texture"; + static const char worldToProjIndexName[] = "m_worldToProj"; + AZ::Data::Instance drawSrg = m_dynamicDraw->NewDrawSrg(); + if (drawSrg) + { + const AZ::RHI::ShaderResourceGroupLayout* layout = drawSrg->GetLayout(); + m_shaderData.m_imageInputIndex = layout->FindShaderInputImageIndex(AZ::Name(textureIndexName)); + AZ_Error("Draw2d", m_shaderData.m_imageInputIndex.IsValid(), "Failed to find shader input constant %s.", + textureIndexName); + m_shaderData.m_viewProjInputIndex = layout->FindShaderInputConstantIndex(AZ::Name(worldToProjIndexName)); + AZ_Error("Draw2d", m_shaderData.m_viewProjInputIndex.IsValid(), "Failed to find shader input constant %s.", + worldToProjIndexName); + } - // Cache shader variants that will be used - AZ::RPI::ShaderOptionList shaderOptionsClamp; - shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true"))); - shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); - m_shaderData.m_shaderOptionsClamp = m_dynamicDraw->UseShaderVariant(shaderOptionsClamp); - AZ::RPI::ShaderOptionList shaderOptionsWrap; - shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false"))); - shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); - m_shaderData.m_shaderOptionsWrap = m_dynamicDraw->UseShaderVariant(shaderOptionsWrap); + // Cache shader variants that will be used + AZ::RPI::ShaderOptionList shaderOptionsClamp; + shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true"))); + shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); + m_shaderData.m_shaderOptionsClamp = m_dynamicDraw->UseShaderVariant(shaderOptionsClamp); + AZ::RPI::ShaderOptionList shaderOptionsWrap; + shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false"))); + shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); + m_shaderData.m_shaderOptionsWrap = m_dynamicDraw->UseShaderVariant(shaderOptionsWrap); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index acf17049ad..3b835dec92 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -76,7 +76,7 @@ void UiRenderer::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) // Create a dynamic draw context for UI Canvas drawing for the scene m_dynamicDraw = CreateDynamicDrawContext(uiShader); - if (m_dynamicDraw) + if (m_dynamicDraw && m_dynamicDraw->IsReady()) { // Cache shader data such as input indices for later use CacheShaderData(m_dynamicDraw); @@ -85,7 +85,7 @@ void UiRenderer::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) } else { - AZ_Error(LogName, false, "Failed to create a dynamic draw context for LyShine. \ + AZ_Error(LogName, false, "Failed to create or initialize a dynamic draw context for LyShine. \ This can happen if the LyShine pass hasn't been added to the main render pipeline."); } } From 10497fe92c89486dd8ccd0a391aef624ed5abac3 Mon Sep 17 00:00:00 2001 From: Sergey Pereslavtsev Date: Mon, 10 Jan 2022 20:43:33 +0000 Subject: [PATCH 131/272] LYN-9183 Fix Terrain Heightfield Collider component to list physics materials from the library Signed-off-by: Sergey Pereslavtsev --- .../TerrainPhysicsColliderComponent.cpp | 15 +++++++++++++++ .../Components/TerrainPhysicsColliderComponent.h | 1 + 2 files changed, 16 insertions(+) diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index 8c2c0e80b6..916dd800e2 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -17,6 +17,7 @@ #include #include +#include #include namespace Terrain @@ -43,11 +44,25 @@ namespace Terrain AZ::Edit::UIHandlers::ComboBox, &TerrainPhysicsSurfaceMaterialMapping::m_surfaceTag, "Surface Tag", "Surface type to map to a physics material.") ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsSurfaceMaterialMapping::m_materialId, "Material ID", "") + ->ElementAttribute(Physics::Attributes::MaterialLibraryAssetId, &TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true); } } } + + AZ::Data::AssetId TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId() + { + if (auto* physicsSystem = AZ::Interface::Get()) + { + if (const auto* physicsConfiguration = physicsSystem->GetConfiguration()) + { + return physicsConfiguration->m_materialLibraryAsset.GetId(); + } + } + return {}; + } + void TerrainPhysicsColliderConfig::Reflect(AZ::ReflectContext* context) { TerrainPhysicsSurfaceMaterialMapping::Reflect(context); diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h index 1a7fbf9c72..284bc74d88 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h @@ -33,6 +33,7 @@ namespace Terrain AZ_CLASS_ALLOCATOR(TerrainPhysicsSurfaceMaterialMapping, AZ::SystemAllocator, 0); AZ_RTTI(TerrainPhysicsSurfaceMaterialMapping, "{A88B5289-DFCD-4564-8395-E2177DFE5B18}"); static void Reflect(AZ::ReflectContext* context); + static AZ::Data::AssetId GetMaterialLibraryId(); SurfaceData::SurfaceTag m_surfaceTag; Physics::MaterialId m_materialId; From 18ea4ba6a8c2646b074f236eb03feab3ec037777 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Mon, 10 Jan 2022 15:21:04 -0600 Subject: [PATCH 132/272] Added a CriticalAssetsCompiled Lifecycle event (#6469) The CriticalAssetsCompiled event can be handled to detect when the AssetProcessor has finished processing Critical Assets Also with the new event, an audit has been performed over all the locations where the AssetCatalogEventBus OnCatalogLoaded event was being handle to make sure it was the proper event to use. If the handler was actually examing the enumerating over the full catalog or querying all assets within the catalog, then it was a proper use. For handlers that were interested in a particular asset it was not Moreover added implementations of `OnCatalogAssetChanged` and `OnCatalogAssetAdded` to the FileTagComponent and the MaterialViewportComponent. Any applications which uses the AtomToolsApplication class(MaterialEditor, AtomSampleViewerStandalone, ShaderMangementConsole) now signals a "CriticalAssetsCompiled" lifecycle event as well as loads the "assetcatalog.xml" if it exists. The Launcher application signals the "CrticalAssetsCompiled" event and reloads the "assetcatalog.xml" for the ${project}.GameLauncher and ${project}.ServerLauncher in Launcher.cpp Finally the Editor signals the "CriticalAssetsCompiled" and reloads the "assetcatalog.xml" in CryEdit.cpp resolves #6093 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Editor/CryEdit.cpp | 23 ++++- .../AzFramework/FileTag/FileTagComponent.cpp | 35 +++++-- .../AzFramework/FileTag/FileTagComponent.h | 2 + .../Spawnable/SpawnableSystemComponent.cpp | 38 ++++---- .../Spawnable/SpawnableSystemComponent.h | 10 +- Code/LauncherUnified/Launcher.cpp | 96 ++++++++++++------- .../SerializeContextTools/SliceConverter.cpp | 4 - .../Code/Source/BootstrapSystemComponent.cpp | 2 +- .../Atom/RPI.Public/RPISystemInterface.h | 3 +- .../Application/AtomToolsApplication.cpp | 19 +++- .../Viewport/MaterialViewportComponent.cpp | 53 +++++++++- .../Viewport/MaterialViewportComponent.h | 3 + .../EditorCommonFeaturesSystemComponent.cpp | 20 ++-- .../EditorCommonFeaturesSystemComponent.h | 5 +- .../Editor/MultiplayerEditorConnection.cpp | 2 +- .../NetworkEntity/NetworkSpawnableLibrary.cpp | 18 ++-- .../NetworkEntity/NetworkSpawnableLibrary.h | 6 +- Gems/PhysX/Code/Source/System/PhysXSystem.cpp | 4 +- Registry/application_lifecycle_events.setreg | 3 +- 19 files changed, 233 insertions(+), 113 deletions(-) diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 77099761c1..1c4e22b99e 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -1352,8 +1352,27 @@ void CCryEditApp::CompileCriticalAssets() const } } assetsInQueueNotifcation.BusDisconnect(); - CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready.")); + // Signal the "CriticalAssetsCompiled" lifecycle event + // Also reload the "assetcatalog.xml" if it exists + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "CriticalAssetsCompiled", R"({})"); + // Reload the assetcatalog.xml at this point again + // Start Monitoring Asset changes over the network and load the AssetCatalog + auto LoadCatalog = [settingsRegistry](AZ::Data::AssetCatalogRequests* assetCatalogRequests) + { + if (AZ::IO::FixedMaxPath assetCatalogPath; + settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder)) + { + assetCatalogPath /= "assetcatalog.xml"; + assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str()); + } + }; + AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog)); + } + + CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready.")); } bool CCryEditApp::ConnectToAssetProcessor() const @@ -1669,7 +1688,7 @@ bool CCryEditApp::InitInstance() return false; } - if (AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get()) + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) { AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "LegacySystemInterfaceCreated", R"({})"); } diff --git a/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.cpp b/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.cpp index 1d09500415..f4831d1f8b 100644 --- a/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.cpp @@ -97,19 +97,38 @@ namespace AzFramework AZStd::vector registeredAssetPaths; AZ::Data::AssetCatalogRequestBus::BroadcastResult(registeredAssetPaths, &AZ::Data::AssetCatalogRequests::GetRegisteredAssetPaths); - const char* dependencyXmlPattern = "*_dependencies.xml"; + constexpr const char* dependencyXmlPattern = "_dependencies.xml"; for (const AZStd::string& assetPath : registeredAssetPaths) { - if (!AZStd::wildcard_match(dependencyXmlPattern, assetPath.c_str())) + if (assetPath.ends_with(dependencyXmlPattern)) { - continue; - } - - if (!m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath)) - { - AZ_Error("ExcludeFileComponent", false, "Failed to add assets referenced from %s to the blocked list", assetPath.c_str()); + AZ_VerifyError("ExcludeFileComponent", m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath), + "Failed to add assets referenced from %s to the blocked list", assetPath.c_str()); } } } + + void ExcludeFileComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) + { + // Reload any modified "_dependencies.xml" files + AZ::IO::Path assetPath; + auto GetAssetPath = [&assetId, &assetPath](AZ::Data::AssetCatalogRequests* assetCatalogRequests) + { + assetPath = assetCatalogRequests->GetAssetPathById(assetId); + }; + + AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(GetAssetPath)); + constexpr const char* dependencyXmlPattern = "_dependencies.xml"; + if (assetPath.Native().ends_with(dependencyXmlPattern)) + { + AZ_VerifyError("ExcludeFileComponent", m_excludeFileQueryManager.get()->LoadEngineDependencies(assetPath.Native()), + "Failed to add assets referenced from %s to the blocked list", assetPath.c_str()); + } + } + + void ExcludeFileComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) + { + OnCatalogAssetChanged(assetId); + } } } diff --git a/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.h b/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.h index d53e4e7a89..1bd0f46aa0 100644 --- a/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.h +++ b/Code/Framework/AzFramework/AzFramework/FileTag/FileTagComponent.h @@ -65,6 +65,8 @@ namespace AzFramework void Deactivate() override; void OnCatalogLoaded(const char* catalogFile) override; + void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override; + void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override; static void Reflect(AZ::ReflectContext* context); diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp index 6ca2f3a53a..4ba9c45a98 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -61,15 +62,6 @@ namespace AzFramework m_entitiesManager.ProcessQueue(SpawnableEntitiesManager::CommandQueuePriority::High); } - void SpawnableSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) - { - if (!m_catalogAvailable) - { - m_catalogAvailable = true; - LoadRootSpawnableFromSettingsRegistry(); - } - } - uint64_t SpawnableSystemComponent::AssignRootSpawnable(AZ::Data::Asset rootSpawnable) { uint32_t generation = 0; @@ -157,20 +149,29 @@ namespace AzFramework // Register with AssetDatabase AZ_Assert(AZ::Data::AssetManager::IsReady(), "Spawnables can't be registered because the Asset Manager is not ready yet."); AZ::Data::AssetManager::Instance().RegisterHandler(&m_assetHandler, AZ::AzTypeInfo::Uuid()); - + // Register with AssetCatalog AZ::Data::AssetCatalogRequestBus::Broadcast( &AZ::Data::AssetCatalogRequestBus::Events::EnableCatalogForAsset, AZ::AzTypeInfo::Uuid()); AZ::Data::AssetCatalogRequestBus::Broadcast( &AZ::Data::AssetCatalogRequestBus::Events::AddExtension, Spawnable::FileExtension); - AssetCatalogEventBus::Handler::BusConnect(); + // Register for the CriticalAssetsCompiled lifecycle event to trigger the loading of the root spawnable + auto settingsRegistry = AZ::SettingsRegistry::Get(); + AZ_Assert(settingsRegistry, "Unable to change root spawnable callback because Settings Registry is not available."); + + auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type) + { + LoadRootSpawnableFromSettingsRegistry(); + }; + AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler, + AZStd::move(LifecycleCallback), "CriticalAssetsCompiled"); + + RootSpawnableNotificationBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); - auto registry = AZ::SettingsRegistry::Get(); - AZ_Assert(registry, "Unable to change root spawnable callback because Settings Registry is not available."); - m_registryChangeHandler = registry->RegisterNotifier([this](AZStd::string_view path, AZ::SettingsRegistryInterface::Type /*type*/) + m_registryChangeHandler = settingsRegistry->RegisterNotifier([this](AZStd::string_view path, AZ::SettingsRegistryInterface::Type /*type*/) { if (path.starts_with(RootSpawnableRegistryKey)) { @@ -187,13 +188,14 @@ namespace AzFramework AZ::TickBus::Handler::BusDisconnect(); RootSpawnableNotificationBus::Handler::BusDisconnect(); - AssetCatalogEventBus::Handler::BusDisconnect(); + // Unregister Lifecycle event handler + m_criticalAssetsHandler = {}; - if (m_catalogAvailable) + if (m_rootSpawnableId.IsValid()) { ReleaseRootSpawnable(); - // The SpawnalbleSystemComponent needs to guarantee there's no more processing left to do by the + // The SpawnableSystemComponent needs to guarantee there's no more processing left to do by the // entity manager before it can safely destroy it on shutdown, but also to make sure that are no // more calls to the callback registered to the root spawnable as that accesses this component. m_rootSpawnableContainer.Clear(); @@ -210,8 +212,6 @@ namespace AzFramework void SpawnableSystemComponent::LoadRootSpawnableFromSettingsRegistry() { - AZ_Assert(m_catalogAvailable, "Attempting to load root spawnable while the catalog is not available yet."); - auto registry = AZ::SettingsRegistry::Get(); AZ_Assert(registry, "Unable to check for root spawnable because the Settings Registry is not available."); diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h index ecd2a9b728..712cd1529d 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -25,7 +24,6 @@ namespace AzFramework : public AZ::Component , public AZ::TickBus::Handler , public AZ::SystemTickBus::Handler - , public AssetCatalogEventBus::Handler , public RootSpawnableInterface::Registrar , public RootSpawnableNotificationBus::Handler { @@ -63,12 +61,6 @@ namespace AzFramework void OnSystemTick() override; - // - // AssetCatalogEventBus - // - - void OnCatalogLoaded(const char* catalogFile) override; - // // RootSpawnableInterface // @@ -97,6 +89,6 @@ namespace AzFramework AZ::SettingsRegistryInterface::NotifyEventHandler m_registryChangeHandler; AZ::Data::AssetId m_rootSpawnableId; - bool m_catalogAvailable{ false }; + AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler; }; } // namespace AzFramework diff --git a/Code/LauncherUnified/Launcher.cpp b/Code/LauncherUnified/Launcher.cpp index ed01a67f39..9dfd6213c4 100644 --- a/Code/LauncherUnified/Launcher.cpp +++ b/Code/LauncherUnified/Launcher.cpp @@ -229,33 +229,65 @@ namespace O3DELauncher void CreateRemoteFileIO(); - bool ConnectToAssetProcessor() + // This function make sure the launcher has signaled the "CriticalAssetsCompiled" + // lifecycle event as well as to load the "assetcatalog.xml" file if it exists + void CompileCriticalAssets() { - bool connectedToAssetProcessor{}; - // When the AssetProcessor is already launched it should take less than a second to perform a connection - // but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize - // and able to negotiate a connection when running a debug build - // and to negotiate a connection - // Setting the connectTimeout to 3 seconds if not set within the settings registry - - AzFramework::AssetSystem::ConnectionSettings connectionSettings; - AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); - - connectionSettings.m_launchAssetProcessorOnFailedConnection = true; - connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Game; - connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) { - AZ_TracePrintf("Launcher", "%.*s", aznumeric_cast(logData.size()), logData.data()); - }; + AZ::ComponentApplicationLifecycle::SignalEvent(*settingsRegistry, "CriticalAssetsCompiled", R"({})"); + // Reload the assetcatalog.xml at this point again + // Start Monitoring Asset changes over the network and load the AssetCatalog + auto LoadCatalog = [settingsRegistry](AZ::Data::AssetCatalogRequests* assetCatalogRequests) + { + if (AZ::IO::FixedMaxPath assetCatalogPath; + settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder)) + { + assetCatalogPath /= "assetcatalog.xml"; + assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str()); + } + }; + AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog)); + } + } - AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); - - if (connectedToAssetProcessor) + // If the connect option is false, this function will return true + // to make sure the Launcher passes the connected to AP check + // If REMOTE_ASSET_PROCESSOR is not defined, then the launcher doesn't need + // to connect to the AssetProcessor and therefore this function returns true + bool ConnectToAssetProcessor([[maybe_unused]] bool connect) + { + bool connectedToAssetProcessor = true; +#if defined(REMOTE_ASSET_PROCESSOR) + if (connect) { - AZ_TracePrintf("Launcher", "Connected to Asset Processor\n"); - CreateRemoteFileIO(); + // When the AssetProcessor is already launched it should take less than a second to perform a connection + // but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize + // and able to negotiate a connection when running a debug build + // and to negotiate a connection + // Setting the connectTimeout to 3 seconds if not set within the settings registry + + AzFramework::AssetSystem::ConnectionSettings connectionSettings; + AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); + + connectionSettings.m_launchAssetProcessorOnFailedConnection = true; + connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Game; + connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) + { + AZ_TracePrintf("Launcher", "%.*s", aznumeric_cast(logData.size()), logData.data()); + }; + + AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); + + if (connectedToAssetProcessor) + { + AZ_TracePrintf("Launcher", "Connected to Asset Processor\n"); + CreateRemoteFileIO(); + } } +#endif + CompileCriticalAssets(); return connectedToAssetProcessor; } @@ -403,25 +435,21 @@ namespace O3DELauncher gameApplication.Start({}, gameApplicationStartupParams); -#if defined(REMOTE_ASSET_PROCESSOR) - bool allowedEngineConnection = !systemInitParams.bToolMode && !systemInitParams.bTestMode && bg_ConnectToAssetProcessor; //connect to the asset processor using the bootstrap values - if (allowedEngineConnection) + const bool allowedEngineConnection = !systemInitParams.bToolMode && !systemInitParams.bTestMode && bg_ConnectToAssetProcessor; + if (!ConnectToAssetProcessor(allowedEngineConnection)) { - if (!ConnectToAssetProcessor()) + AZ::s64 waitForConnect{}; + AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect, + AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "wait_for_connect"); + if (waitForConnect != 0) { - AZ::s64 waitForConnect{}; - AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect, - AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "wait_for_connect"); - if (waitForConnect != 0) - { - AZ_Error("Launcher", false, "Failed to connect to AssetProcessor."); - return ReturnCode::ErrAssetProccessor; - } + AZ_Error("Launcher", false, "Failed to connect to AssetProcessor."); + return ReturnCode::ErrAssetProccessor; } } -#endif + AZ_Assert(AZ::AllocatorInstance::IsReady(), "System allocator was not created or creation failed."); //Initialize the Debug trace instance to create necessary environment variables AZ::Debug::Trace::Instance().Init(); diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp index d0528a9cad..cfb1998f48 100644 --- a/Code/Tools/SerializeContextTools/SliceConverter.cpp +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -79,10 +79,6 @@ namespace AZ return false; } - // Load the asset catalog so that we can find any nested assets successfully. We also need to tick the tick bus - // so that the OnCatalogLoaded event gets processed now, instead of during application shutdown. - application.Tick(); - AZStd::string logggingScratchBuffer; SetupLogging(logggingScratchBuffer, convertSettings.m_reporting, *commandLine); diff --git a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp index 84fc58718c..ef03a839d7 100644 --- a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp +++ b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp @@ -155,7 +155,7 @@ namespace AZ { Initialize(); }, - "LegacySystemInterfaceCreated"); + "CriticalAssetsCompiled"); } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h index 3f30d498cf..693185b6d2 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h @@ -34,8 +34,7 @@ namespace AZ RPISystemInterface() = default; virtual ~RPISystemInterface() = default; - //! Pre-load some system assets. This should be called once the asset catalog is ready and before create any RPI instances. - //! Note: can't rely on the AzFramework::AssetCatalogEventBus's OnCatalogLoaded since the order of calling handlers is undefined. + //! Pre-load some system assets. This should be called once Critical Asset have compiled ready and before create any RPI instances. virtual void InitializeSystemAssets() = 0; //! Was the RPI system initialized properly diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index ec365d7a6a..02248fffd4 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -295,10 +296,24 @@ namespace AtomToolsFramework QMessageBox::critical( activeWindow(), QString("Failed to compile critical assets"), QString("Failed to compile the following critical assets:\n%1\n%2") - .arg(failedAssets.join(",\n")) - .arg("Make sure this is an Atom project.")); + .arg(failedAssets.join(",\n")) + .arg("Make sure this is an Atom project.")); ExitMainLoop(); } + + AZ::ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "CriticalAssetsCompiled", R"({})"); + // Reload the assetcatalog.xml at this point again + // Start Monitoring Asset changes over the network and load the AssetCatalog + auto LoadCatalog = [settingsRegistry = m_settingsRegistry.get()](AZ::Data::AssetCatalogRequests* assetCatalogRequests) + { + if (AZ::IO::FixedMaxPath assetCatalogPath; + settingsRegistry->Get(assetCatalogPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder)) + { + assetCatalogPath /= "assetcatalog.xml"; + assetCatalogRequests->LoadCatalog(assetCatalogPath.c_str()); + } + }; + AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(LoadCatalog)); } void AtomToolsApplication::SaveSettings() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index 35f5067cd0..9cf714b40e 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -165,12 +165,12 @@ namespace MaterialEditor // AssetCatalogRequestBus::EnumerateAssets can lead to deadlocked) AZ::Data::AssetCatalogRequests::AssetEnumerationCB enumerateCB = [this]([[maybe_unused]] const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info) { - if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".lightingpreset.azasset")) + if (AZ::StringFunc::EndsWith(info.m_relativePath.c_str(), ".lightingpreset.azasset")) { m_lightingPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType }; AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId); } - else if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".modelpreset.azasset")) + else if (AZ::StringFunc::EndsWith(info.m_relativePath.c_str(), ".modelpreset.azasset")) { m_modelPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType }; AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId); @@ -429,4 +429,51 @@ namespace MaterialEditor ReloadContent(); }); } + + void MaterialViewportComponent::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) + { + auto ReloadLightingAndModelPresets = [this, &assetId](AZ::Data::AssetCatalogRequests* assetCatalogRequests) + { + AZ::Data::AssetInfo assetInfo = assetCatalogRequests->GetAssetInfoById(assetId); + AZ::Data::Asset* modifiedPresetAsset{}; + if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".lightingpreset.azasset")) + { + m_lightingPresetAssets[assetInfo.m_assetId] = { assetInfo.m_assetId, assetInfo.m_assetType }; + AZ::Data::AssetBus::MultiHandler::BusConnect(assetInfo.m_assetId); + modifiedPresetAsset = &m_lightingPresetAssets[assetInfo.m_assetId]; + } + else if (AzFramework::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".modelpreset.azasset")) + { + m_modelPresetAssets[assetInfo.m_assetId] = { assetInfo.m_assetId, assetInfo.m_assetType }; + AZ::Data::AssetBus::MultiHandler::BusConnect(assetInfo.m_assetId); + modifiedPresetAsset = &m_modelPresetAssets[assetInfo.m_assetId]; + } + + // Queue a load on the changed asset + if (modifiedPresetAsset != nullptr) + { + modifiedPresetAsset->QueueLoad(); + } + }; + AZ::Data::AssetCatalogRequestBus::Broadcast(AZStd::move(ReloadLightingAndModelPresets)); + } + + void MaterialViewportComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) + { + OnCatalogAssetChanged(assetId); + } + + void MaterialViewportComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) + { + if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".lightingpreset.azasset")) + { + AZ::Data::AssetBus::MultiHandler::BusDisconnect(assetInfo.m_assetId); + m_lightingPresetAssets.erase(assetId); + } + if (AZ::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), ".modelpreset.azasset")) + { + AZ::Data::AssetBus::MultiHandler::BusDisconnect(assetInfo.m_assetId); + m_modelPresetAssets.erase(assetId); + } + } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h index 07385d842d..68668bd804 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h @@ -95,6 +95,9 @@ namespace MaterialEditor //////////////////////////////////////////////////////////////////////// // AzFramework::AssetCatalogEventBus::Handler overrides ... void OnCatalogLoaded(const char* catalogFile) override; + void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override; + void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override; + void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override; //////////////////////////////////////////////////////////////////////// AZStd::unordered_map> m_lightingPresetAssets; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.cpp index 2bf428bd2d..0250640d65 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.cpp @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -88,14 +89,22 @@ namespace AZ AzToolsFramework::EditorLevelNotificationBus::Handler::BusConnect(); AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusConnect(); - AzFramework::AssetCatalogEventBus::Handler::BusConnect(); + if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr) + { + auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type) + { + SetupThumbnails(); + }; + AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler, + AZStd::move(LifecycleCallback), "CriticalAssetsCompiled"); + } AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect(); } void EditorCommonFeaturesSystemComponent::Deactivate() { AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect(); - AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); + m_criticalAssetsHandler = {}; AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusDisconnect(); @@ -192,13 +201,6 @@ namespace AZ } } - void EditorCommonFeaturesSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) - { - AZ::TickBus::QueueFunction([this](){ - SetupThumbnails(); - }); - } - const AzToolsFramework::AssetBrowser::PreviewerFactory* EditorCommonFeaturesSystemComponent::GetPreviewerFactory( const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const { diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.h index 82bb93a808..dff9e68814 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/EditorCommonFeaturesSystemComponent.h @@ -28,7 +28,6 @@ namespace AZ , public AzToolsFramework::EditorLevelNotificationBus::Handler , public AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler , public AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler - , public AzFramework::AssetCatalogEventBus::Handler , public AzFramework::ApplicationLifecycleEvents::Bus::Handler { public: @@ -58,9 +57,6 @@ namespace AZ const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override; void OnSliceInstantiationFailed(const AZ::Data::AssetId&, const AzFramework::SliceInstantiationTicket&) override; - // AzFramework::AssetCatalogEventBus::Handler overrides ... - void OnCatalogLoaded(const char* catalogFile) override; - // AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler overrides... const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory( const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override; @@ -80,6 +76,7 @@ namespace AZ AZStd::unique_ptr m_thumbnailRenderer; AZStd::unique_ptr m_previewerFactory; + AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler; }; } // namespace Render } // namespace AZ diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index f112098eae..c8c1ed15bd 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -58,7 +58,7 @@ namespace Multiplayer { ActivateDedicatedEditorServer(); }, - "LegacySystemInterfaceCreated"); + "CriticalAssetsCompiled"); } } } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp index ba8836b6e6..f60778dbb4 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -17,12 +18,20 @@ namespace Multiplayer NetworkSpawnableLibrary::NetworkSpawnableLibrary() { AZ::Interface::Register(this); - AzFramework::AssetCatalogEventBus::Handler::BusConnect(); + if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr) + { + auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type) + { + BuildSpawnablesList(); + }; + AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler, + AZStd::move(LifecycleCallback), "CriticalAssetsCompiled"); + } } NetworkSpawnableLibrary::~NetworkSpawnableLibrary() { - AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); + m_criticalAssetsHandler = {}; AZ::Interface::Unregister(this); } @@ -50,11 +59,6 @@ namespace Multiplayer m_spawnablesReverseLookup[id] = name; } - void NetworkSpawnableLibrary::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) - { - BuildSpawnablesList(); - } - AZ::Name NetworkSpawnableLibrary::GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId) { if (assetId.IsValid()) diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h index 1cec63f81d..0fc3ae07cc 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h @@ -9,14 +9,13 @@ #pragma once #include -#include +#include namespace Multiplayer { /// Implementation of the network prefab library interface. class NetworkSpawnableLibrary final : public INetworkSpawnableLibrary - , private AzFramework::AssetCatalogEventBus::Handler { public: AZ_RTTI(NetworkSpawnableLibrary, "{65E15F33-E893-49C2-A8E2-B6A8A6EF31E0}", INetworkSpawnableLibrary); @@ -30,11 +29,10 @@ namespace Multiplayer AZ::Name GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId) override; AZ::Data::AssetId GetAssetIdByName(AZ::Name name) override; - /// AssetCatalogEventBus overrides. - void OnCatalogLoaded(const char* catalogFile) override; private: AZStd::unordered_map m_spawnables; AZStd::unordered_map m_spawnablesReverseLookup; + AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler; }; } diff --git a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp index 168adc8910..39c0dfc686 100644 --- a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp +++ b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp @@ -103,15 +103,13 @@ namespace PhysX if (auto* settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) { - // Automatically register the event if it's not registered, because - // this system is initialized before the settings registry has loaded the event list. AZ::ComponentApplicationLifecycle::RegisterHandler( *settingsRegistry, m_componentApplicationLifecycleHandler, [this]([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZ::SettingsRegistryInterface::Type type) { InitializeMaterialLibrary(); }, - "LegacySystemInterfaceCreated"); // LegacySystemInterfaceCreated is signaled after critical assets have been processed + "CriticalAssetsCompiled"); } m_state = State::Initialized; diff --git a/Registry/application_lifecycle_events.setreg b/Registry/application_lifecycle_events.setreg index 0d9cd0f170..c52c93c0c0 100644 --- a/Registry/application_lifecycle_events.setreg +++ b/Registry/application_lifecycle_events.setreg @@ -23,7 +23,8 @@ "GemsUnloaded": {}, "FileIOAvailable": {}, "FileIOUnavailable": {}, - "LegacySystemInterfaceCreated": {} + "LegacySystemInterfaceCreated": {}, + "CriticalAssetsCompiled": {} } } } From bcc83aaaf2473ff1ee8fd9f9629e830df48ae222 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 10 Jan 2022 16:04:21 -0800 Subject: [PATCH 133/272] Found actual issue where the logs were being routed to the artifact folder Signed-off-by: evanchia --- .../LyTestTools/ly_test_tools/o3de/editor_test.py | 13 +++++++++++-- .../ly_test_tools/o3de/editor_test_utils.py | 14 ++++---------- .../tests/unit/test_editor_test_utils.py | 7 +++++-- .../tests/unit/test_o3de_editor_test.py | 13 +++++++++++++ 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py index fd2157d1cc..c97298573e 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py @@ -771,7 +771,8 @@ class EditorTestSuite(): output = editor.get_output() return_code = editor.get_returncode() editor_log_content = editor_utils.retrieve_editor_log_content(run_id, log_name, workspace) - + # Save the editor log + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), log_name)) if return_code == 0: test_result = Result.Pass.create(test_spec, output, editor_log_content) else: @@ -779,6 +780,9 @@ class EditorTestSuite(): if has_crashed: test_result = Result.Crash.create(test_spec, output, return_code, editor_utils.retrieve_crash_output (run_id, workspace, self._TIMEOUT_CRASH_LOG), None) + # Save the crash log + crash_file_name = os.path.basename(workspace.paths.crash_log()) + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), crash_file_name)) editor_utils.cycle_crash_report(run_id, workspace) else: test_result = Result.Fail.create(test_spec, output, editor_log_content) @@ -842,7 +846,8 @@ class EditorTestSuite(): output = editor.get_output() return_code = editor.get_returncode() editor_log_content = editor_utils.retrieve_editor_log_content(run_id, log_name, workspace) - + # Save the editor log + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), log_name)) if return_code == 0: # No need to scrap the output, as all the tests have passed for test_spec in test_spec_list: @@ -863,6 +868,10 @@ class EditorTestSuite(): # The first test with "Unknown" result (no data in output) is likely the one that crashed crash_error = editor_utils.retrieve_crash_output(run_id, workspace, self._TIMEOUT_CRASH_LOG) + # Save the crash log + crash_file_name = os.path.basename(workspace.paths.crash_log()) + workspace.artifact_manager.save_artifact( + os.path.join(editor_utils.retrieve_log_path(), crash_file_name)) editor_utils.cycle_crash_report(run_id, workspace) results[test_spec_name] = Result.Crash.create(result.test_spec, output, return_code, crash_error, result.editor_log) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py index 69c6eda2ee..246fba16aa 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test_utils.py @@ -71,15 +71,9 @@ def retrieve_crash_output(run_id: int, workspace: AbstractWorkspaceManager, time :return str: The contents of the editor crash file (error.log) """ crash_info = "-- No crash log available --" - error_log_regex = "" - log_path = retrieve_log_path(run_id, workspace) - # Gather all of the files in the log directory - dir_files = [f for f in os.listdir(log_path) if os.path.isfile(os.path.join(log_path, f))] - for file_name in dir_files: - # Search for all .log files with either "crash" or "error" because they could be renamed - if ("error" in file_name.lower() or "crash" in file_name.lower()) and (file_name.endswith(".log")): - crash_log = os.path.join(log_path, file_name) - break + # Grab the file name of the crash log which can be different depending on platform + crash_file_name = os.path.basename(workspace.paths.crash_log()) + crash_log = os.path.join(retrieve_log_path(run_id, workspace), crash_file_name) try: waiter.wait_for(lambda: os.path.exists(crash_log), timeout=timeout) except AssertionError: @@ -100,7 +94,7 @@ def cycle_crash_report(run_id: int, workspace: AbstractWorkspaceManager) -> None :param workspace: Workspace fixture """ log_path = retrieve_log_path(run_id, workspace) - files_to_cycle = ['error.log', 'error.dmp'] + files_to_cycle = ['crash.log', 'error.log', 'error.dmp'] for filename in files_to_cycle: filepath = os.path.join(log_path, filename) name, ext = os.path.splitext(filename) diff --git a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py index f7678c44c0..6e2ec59721 100644 --- a/Tools/LyTestTools/tests/unit/test_editor_test_utils.py +++ b/Tools/LyTestTools/tests/unit/test_editor_test_utils.py @@ -61,6 +61,8 @@ class TestEditorTestUtils(unittest.TestCase): @mock.patch('os.listdir') @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') + @mock.patch('os.path.join', mock.MagicMock()) + @mock.patch('os.path.basename', mock.MagicMock()) @mock.patch('os.path.isfile', mock.MagicMock()) @mock.patch('ly_test_tools.environment.waiter.wait_for', mock.MagicMock()) def test_RetrieveCrashOutput_CrashLogExists_ReturnsLogInfo(self, mock_retrieve_log_path, mock_listdir): @@ -79,6 +81,7 @@ class TestEditorTestUtils(unittest.TestCase): def test_RetrieveCrashOutput_CrashLogNotExists_ReturnsError(self, mock_retrieve_log_path, mock_listdir): mock_retrieve_log_path.return_value = 'mock_log_path' mock_workspace = mock.MagicMock() + mock_workspace.paths.crash_log.return_value = 'mock_file.log' error_message = "No crash log available" mock_listdir.return_value = ['mock_file.log'] @@ -91,7 +94,7 @@ class TestEditorTestUtils(unittest.TestCase): @mock.patch('os.path.exists') def test_CycleCrashReport_DmpExists_NamedCorrectly(self, mock_exists, mock_retrieve_log_path, mock_strftime, mock_rename): - mock_exists.side_effect = [False, True] + mock_exists.side_effect = [False, False, True] mock_retrieve_log_path.return_value = 'mock_log_path' mock_workspace = mock.MagicMock() mock_strftime.return_value = 'mock_strftime' @@ -107,7 +110,7 @@ class TestEditorTestUtils(unittest.TestCase): @mock.patch('os.path.exists') def test_CycleCrashReport_LogExists_NamedCorrectly(self, mock_exists, mock_retrieve_log_path, mock_strftime, mock_rename): - mock_exists.side_effect = [True, False] + mock_exists.side_effect = [False, True, False] mock_retrieve_log_path.return_value = 'mock_log_path' mock_workspace = mock.MagicMock() mock_strftime.return_value = 'mock_strftime' diff --git a/Tools/LyTestTools/tests/unit/test_o3de_editor_test.py b/Tools/LyTestTools/tests/unit/test_o3de_editor_test.py index 2b6ae5b471..054159cd16 100644 --- a/Tools/LyTestTools/tests/unit/test_o3de_editor_test.py +++ b/Tools/LyTestTools/tests/unit/test_o3de_editor_test.py @@ -589,6 +589,7 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) def test_ExecEditorTest_TestSucceeds_ReturnsPass(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_output_results, mock_create): @@ -616,6 +617,7 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) def test_ExecEditorTest_TestFails_ReturnsFail(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_output_results, mock_create): @@ -644,6 +646,8 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) + @mock.patch('os.path.basename', mock.MagicMock()) def test_ExecEditorTest_TestCrashes_ReturnsCrash(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_output_results, mock_retrieve_crash, mock_create): @@ -699,10 +703,14 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) def test_ExecEditorMultitest_AllTestsPass_ReturnsPasses(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_create): mock_test_suite = ly_test_tools.o3de.editor_test.EditorTestSuite() mock_workspace = mock.MagicMock() + mock_artifact_manager = mock.MagicMock() + mock_artifact_manager.save_artifact.return_value = mock.MagicMock() + mock_workspace.artifact_manager = mock_artifact_manager mock_workspace.paths.engine_root.return_value = "" mock_editor = mock.MagicMock() mock_editor.get_returncode.return_value = 0 @@ -727,6 +735,7 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) def test_ExecEditorMultitest_OneFailure_CallsCorrectFunc(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_results): mock_test_suite = ly_test_tools.o3de.editor_test.EditorTestSuite() @@ -752,6 +761,8 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) + @mock.patch('os.path.basename', mock.MagicMock()) def test_ExecEditorMultitest_OneCrash_ReportsOnUnknownResult(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_results, mock_retrieve_crash, mock_create): @@ -787,6 +798,8 @@ class TestRunningTests(unittest.TestCase): @mock.patch('ly_test_tools.o3de.editor_test_utils.retrieve_log_path') @mock.patch('ly_test_tools.o3de.editor_test_utils.get_testcase_module_filepath') @mock.patch('ly_test_tools.o3de.editor_test_utils.cycle_crash_report') + @mock.patch('os.path.join', mock.MagicMock()) + @mock.patch('os.path.basename', mock.MagicMock()) def test_ExecEditorMultitest_ManyUnknown_ReportsUnknownResults(self, mock_cycle_crash, mock_get_testcase_filepath, mock_retrieve_log, mock_retrieve_editor_log, mock_get_results, mock_retrieve_crash, mock_create): From ba9731bec60e084ec5675073ee6dfc3e5daac396 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 10 Jan 2022 16:13:14 -0800 Subject: [PATCH 134/272] added missing params Signed-off-by: evanchia --- Tools/LyTestTools/ly_test_tools/o3de/editor_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py index c97298573e..eaa285a81e 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py @@ -772,7 +772,7 @@ class EditorTestSuite(): return_code = editor.get_returncode() editor_log_content = editor_utils.retrieve_editor_log_content(run_id, log_name, workspace) # Save the editor log - workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), log_name)) + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(run_id, workspace), log_name)) if return_code == 0: test_result = Result.Pass.create(test_spec, output, editor_log_content) else: @@ -782,7 +782,7 @@ class EditorTestSuite(): (run_id, workspace, self._TIMEOUT_CRASH_LOG), None) # Save the crash log crash_file_name = os.path.basename(workspace.paths.crash_log()) - workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), crash_file_name)) + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(run_id, workspace), crash_file_name)) editor_utils.cycle_crash_report(run_id, workspace) else: test_result = Result.Fail.create(test_spec, output, editor_log_content) @@ -847,7 +847,7 @@ class EditorTestSuite(): return_code = editor.get_returncode() editor_log_content = editor_utils.retrieve_editor_log_content(run_id, log_name, workspace) # Save the editor log - workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(), log_name)) + workspace.artifact_manager.save_artifact(os.path.join(editor_utils.retrieve_log_path(run_id, workspace), log_name)) if return_code == 0: # No need to scrap the output, as all the tests have passed for test_spec in test_spec_list: @@ -871,7 +871,7 @@ class EditorTestSuite(): # Save the crash log crash_file_name = os.path.basename(workspace.paths.crash_log()) workspace.artifact_manager.save_artifact( - os.path.join(editor_utils.retrieve_log_path(), crash_file_name)) + os.path.join(editor_utils.retrieve_log_path(run_id, workspace), crash_file_name)) editor_utils.cycle_crash_report(run_id, workspace) results[test_spec_name] = Result.Crash.create(result.test_spec, output, return_code, crash_error, result.editor_log) From 8fd6d534b3a7fc486315f7ab7c22578ae38f31d4 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 10 Jan 2022 16:27:07 -0800 Subject: [PATCH 135/272] forgot to change editor command line string Signed-off-by: evanchia --- Tools/LyTestTools/ly_test_tools/o3de/editor_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py index eaa285a81e..8bd4fbe29a 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py @@ -762,7 +762,7 @@ class EditorTestSuite(): cmdline = [ "--runpythontest", test_filename, "-logfile", f"@log@/{log_name}", - "-project-log-path", ly_test_tools._internal.pytest_plugin.output_path] + test_cmdline_args + "-project-log-path", editor_utils.retrieve_log_path(run_id, workspace)] + test_cmdline_args editor.args.extend(cmdline) editor.start(backupFiles = False, launch_ap = False, configure_settings=False) @@ -834,7 +834,7 @@ class EditorTestSuite(): cmdline = [ "--runpythontest", test_filenames_str, "-logfile", f"@log@/{log_name}", - "-project-log-path", ly_test_tools._internal.pytest_plugin.output_path] + test_cmdline_args + "-project-log-path", editor_utils.retrieve_log_path(run_id, workspace)] + test_cmdline_args editor.args.extend(cmdline) editor.start(backupFiles = False, launch_ap = False, configure_settings=False) From d3a99235aaa997688baebf3a1432090714f16765 Mon Sep 17 00:00:00 2001 From: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> Date: Mon, 10 Jan 2022 17:01:50 -0800 Subject: [PATCH 136/272] Fix undo for create editor entity (#6785) * Avoid undoing twice when undo is hit for CreateNewEditorEntity Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Moved an assert immediately after entity creation Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> --- .../Entity/EditorEntityContextComponent.cpp | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextComponent.cpp index 90657132ca..470ca8b9ea 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextComponent.cpp @@ -226,7 +226,15 @@ namespace AzToolsFramework AZ::EntityId EditorEntityContextComponent::CreateNewEditorEntity(const char* name) { AZ::Entity* entity = CreateEntity(name); - FinalizeEditorEntity(entity); + AZ_Assert(entity != nullptr, "Entity with name %s couldn't be created.", name); + if (m_isLegacySliceService) + { + FinalizeEditorEntity(entity); + } + else + { + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEditorEntityCreated, entity->GetId()); + } return entity->GetId(); } @@ -253,8 +261,16 @@ namespace AzToolsFramework return AZ::EntityId(); } entity = aznew AZ::Entity(entityId, name); + AZ_Assert(entity != nullptr, "Entity with name %s couldn't be created.", name); AddEntity(entity); - FinalizeEditorEntity(entity); + if (m_isLegacySliceService) + { + FinalizeEditorEntity(entity); + } + else + { + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEditorEntityCreated, entity->GetId()); + } return entity->GetId(); } From f09055af42af18dc75f709753da33940ae9c21f5 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Mon, 10 Jan 2022 19:11:00 -0600 Subject: [PATCH 137/272] Fixed CMake use with Android NDK 23 (#6460) * Fixed CMake use with Android NDK 23 This was done by only setting the `ANDROID_ARM_MODE` if the ANDROID_ABI starts with `armeabi`. The Android arm mode setting can't be used using non-`armeabi` ABIs. In O3DE we default to `arm64-v8a` `ANDROID_ABI` So `ANDROID_ARM_MODE` must not be set. The CMake [Android-Determine.cmake](https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/Platform/Android-Determine.cmake#L573-585) which is used to detect platform-wide information when the CMAKE_SYSTEM_NAME is set to android, enforces that if the `CMAKE_ANDROID_ARCH_ABI` doesn't start with `armeabi`, then it will fatal error if the CMAKE_ANDROID_ARM_MODE option is set. In Android NDK 21 the `ANDROID_ARM_MODE` variable is used to set the CMAKE_ANDROID_ARM_MODE variable if the [ANDROID_ABI](https://android.googlesource.com/platform/ndk/+/refs/tags/ndk-r21e/build/cmake/android.toolchain.cmake#700) starts with `armeabi`. This meant when using Android NDK 21, the CMake Android-Determine.cmake module would succeed, due to the CMAKE_ANDROID_ARM_MODE not being set. In Android NDK 23 the `ANDROID_ARM_MODE` now will set the `CMAKE_ANDROID_ARM_MODE` variable to `TRUE` if it isn't defined. Added an `--extra-cmake-configure-args` option to the `generate_android_project.py` script which can be used to append user specified CMake arguments to the cmake configure step (`cmake -B -S -DCMAKE_TOOLCHAIN_FILE= `) Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the O3DE Android toolchain wrapper to fatal error if the 64-bit arm ABI isn't used. Also removed the unneccessary setting of the ANDROID_ARM_MODE and ANDROID_ARM_NEON option option now that the armeabi cannot be specified as an ABI. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- cmake/Platform/Android/Toolchain_android.cmake | 9 ++++----- cmake/Tools/Platform/Android/android_support.py | 9 ++++++++- .../Tools/Platform/Android/generate_android_project.py | 6 +++++- scripts/build/Platform/Android/build_config.json | 10 +++++----- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/cmake/Platform/Android/Toolchain_android.cmake b/cmake/Platform/Android/Toolchain_android.cmake index b5c4a56fd6..75ff4554fd 100644 --- a/cmake/Platform/Android/Toolchain_android.cmake +++ b/cmake/Platform/Android/Toolchain_android.cmake @@ -31,11 +31,10 @@ endif() if(NOT ANDROID_ABI) set(ANDROID_ABI arm64-v8a) endif() -if(NOT ANDROID_ARM_MODE) - set(ANDROID_ARM_MODE arm) -endif() -if(NOT ANDROID_ARM_NEON) - set(ANDROID_ARM_NEON FALSE) + +# Only the 64-bit ANDROID ABIs arm supported +if(NOT ANDROID_ABI MATCHES "^arm64-") + message(FATAL_ERROR "Only the 64-bit ANDROID_ABI's are supported. arm64-v8a can be used if not set") endif() if(NOT ANDROID_NATIVE_API_LEVEL) set(ANDROID_NATIVE_API_LEVEL 21) diff --git a/cmake/Tools/Platform/Android/android_support.py b/cmake/Tools/Platform/Android/android_support.py index f52cc2736c..657ef3b3e4 100755 --- a/cmake/Tools/Platform/Android/android_support.py +++ b/cmake/Tools/Platform/Android/android_support.py @@ -471,7 +471,8 @@ class AndroidProjectGenerator(object): def __init__(self, engine_root, build_dir, android_sdk_path, build_tool, android_sdk_platform, android_native_api_level, android_ndk, project_path, third_party_path, cmake_version, override_cmake_path, override_gradle_path, gradle_version, gradle_plugin_version, - override_ninja_path, include_assets_in_apk, asset_mode, asset_type, signing_config, native_build_path, vulkan_validation_path, is_test_project=False, + override_ninja_path, include_assets_in_apk, asset_mode, asset_type, signing_config, native_build_path, vulkan_validation_path, + extra_cmake_configure_args, is_test_project=False, overwrite_existing=True, unity_build_enabled=False): """ Initialize the object with all the required parameters needed to create an Android Project. The parameters should be verified before initializing this object @@ -497,6 +498,7 @@ class AndroidProjectGenerator(object): :param signing_config: Optional signing configuration arguments :param native_build_path: Override the native build staging path in gradle :param vulkan_validation_path: Override the path to where the Vulkan Validation Layers libraries are (required when using NDK r23+) + :param extra_cmake_configure_args Additional arguments to supply cmake when configuring a project :param is_test_project: Flag to indicate if this is a unit test runner project. (If true, project_path, asset_mode, asset_type, and include_assets_in_apk are ignored) :param overwrite_existing: Flag to overwrite existing project files when being generated, or skip if they already exist. """ @@ -539,6 +541,8 @@ class AndroidProjectGenerator(object): self.vulkan_validation_path = vulkan_validation_path + self.extra_cmake_configure_args = extra_cmake_configure_args + self.asset_mode = asset_mode self.asset_type = asset_type @@ -844,6 +848,9 @@ class AndroidProjectGenerator(object): if self.override_ninja_path: cmake_argument_list.append(f'"-DCMAKE_MAKE_PROGRAM={common.normalize_path_for_settings(self.override_ninja_path)}"') + if self.extra_cmake_configure_args: + cmake_argument_list.extend(map(json.dumps, self.extra_cmake_configure_args)) + # Query the project_path from the project.json file project_name = common.read_project_name_from_project_json(self.project_path) # Prepare the config-specific section to place the cmake argument list in the build.gradle for the app diff --git a/cmake/Tools/Platform/Android/generate_android_project.py b/cmake/Tools/Platform/Android/generate_android_project.py index fe0d787d38..5e414e7738 100755 --- a/cmake/Tools/Platform/Android/generate_android_project.py +++ b/cmake/Tools/Platform/Android/generate_android_project.py @@ -227,6 +227,9 @@ def main(args): help='Override path to where the Vulkan Validation Layers libraries are. Required for use with NDK r23+', default=None, required=False) + parser.add_argument('--extra-cmake-configure-args', + help='Extra arguments to supply to the cmake configure step', + nargs='*') # Asset Options parser.add_argument(INCLUDE_APK_ASSETS_ARGUMENT_NAME, @@ -415,7 +418,8 @@ def main(args): overwrite_existing=parsed_args.overwrite_existing, unity_build_enabled=parsed_args.enable_unity_build, native_build_path=parsed_args.native_build_path, - vulkan_validation_path=parsed_args.vulkan_validation_path) + vulkan_validation_path=parsed_args.vulkan_validation_path, + extra_cmake_configure_args=parsed_args.extra_cmake_configure_args) generator.execute() diff --git a/scripts/build/Platform/Android/build_config.json b/scripts/build/Platform/Android/build_config.json index 7a7e90c0b0..c505d8e940 100644 --- a/scripts/build/Platform/Android/build_config.json +++ b/scripts/build/Platform/Android/build_config.json @@ -35,7 +35,7 @@ "PARAMETERS": { "CONFIGURATION":"debug", "OUTPUT_DIRECTORY":"build\\android", - "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", + "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"all", "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" @@ -50,7 +50,7 @@ "PARAMETERS": { "CONFIGURATION":"profile", "OUTPUT_DIRECTORY":"build\\android", - "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", + "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"all", "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" @@ -66,7 +66,7 @@ "PARAMETERS": { "CONFIGURATION":"profile", "OUTPUT_DIRECTORY":"build\\android", - "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\" -DLY_UNITY_BUILD=FALSE", + "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\" -DLY_UNITY_BUILD=FALSE", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"all", "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" @@ -102,7 +102,7 @@ "PARAMETERS": { "CONFIGURATION":"release", "OUTPUT_DIRECTORY":"build\\android", - "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", + "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\"", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"all", "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" @@ -118,7 +118,7 @@ "PARAMETERS": { "CONFIGURATION":"release", "OUTPUT_DIRECTORY":"build\\mono_android", - "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\" -DLY_MONOLITHIC_GAME=TRUE", + "CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_NDK_DIR!\" -DLY_MONOLITHIC_GAME=TRUE", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"all", "CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!" From 0e0ca7585ce348d5079f34eae371d97295cf6d61 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Tue, 11 Jan 2022 11:32:17 +0000 Subject: [PATCH 138/272] change default input color space to SRGB Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- .../Source/Utils/EditorLightingPreset.cpp | 2 +- .../Include/Atom/RPI.Edit/Common/ColorUtils.h | 2 ++ .../Source/RPI.Edit/Common/ColorUtils.cpp | 21 +++++++++++++------ .../DynamicProperty/DynamicProperty.cpp | 2 +- .../CoreLights/EditorAreaLightComponent.cpp | 2 +- .../EditorDirectionalLightComponent.cpp | 2 +- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp index e2a99668eb..120eaa84dc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp @@ -72,7 +72,7 @@ namespace AZ ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &LightConfig::m_direction, "Direction", "") ->DataElement(Edit::UIHandlers::Color, &LightConfig::m_color, "Color", "Color of the light") - ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) + ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetRgbEditorConfig()) ->DataElement(Edit::UIHandlers::Default, &LightConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.") ->ClassElement(AZ::Edit::ClassElements::Group, "Shadow") diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/ColorUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/ColorUtils.h index 393cae6ca2..38b6a0bb80 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/ColorUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/ColorUtils.h @@ -19,6 +19,8 @@ namespace AZ //[GFX TODO][ATOM-4462] Replace this to use data driven color management system //! Return a ColorEditorConfiguration for editing a Linear sRGB color in sRGB space. AzToolsFramework::ColorEditorConfiguration GetLinearRgbEditorConfig(); + //! Return a ColorEditorConfiguration for editing a sRGB color in sRGB space. + AzToolsFramework::ColorEditorConfiguration GetRgbEditorConfig(); } // namespace PropertyColorConfigs } // namespace RPI diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Common/ColorUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Common/ColorUtils.cpp index a6baa38a72..df88a530b9 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Common/ColorUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Common/ColorUtils.cpp @@ -14,14 +14,14 @@ namespace AZ { namespace ColorUtils { + enum ColorSpace : uint32_t + { + LinearSRGB, + SRGB + }; + AzToolsFramework::ColorEditorConfiguration GetLinearRgbEditorConfig() { - enum ColorSpace : uint32_t - { - LinearSRGB, - SRGB - }; - AzToolsFramework::ColorEditorConfiguration configuration; configuration.m_colorPickerDialogConfiguration = AzQtComponents::ColorPicker::Configuration::RGB; @@ -59,6 +59,15 @@ namespace AZ return configuration; } + AzToolsFramework::ColorEditorConfiguration GetRgbEditorConfig() + { + AzToolsFramework::ColorEditorConfiguration configuration = GetLinearRgbEditorConfig(); + + configuration.m_propertyColorSpaceId = ColorSpace::SRGB; + + return configuration; + } + } // namespace ColorPropertyEditorConfigurations } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp index 2054858726..d4599b68b7 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp @@ -160,7 +160,7 @@ namespace AtomToolsFramework ApplyRangeEditDataAttributes(); break; case DynamicPropertyType::Color: - AddEditDataAttribute(AZ_CRC("ColorEditorConfiguration", 0xc8b9510e), AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()); + AddEditDataAttribute(AZ_CRC("ColorEditorConfiguration", 0xc8b9510e), AZ::RPI::ColorUtils::GetRgbEditorConfig()); break; case DynamicPropertyType::Enum: m_editData.m_elementId = AZ::Edit::UIHandlers::ComboBox; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp index 02c9f77436..d15862451a 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp @@ -75,7 +75,7 @@ namespace AZ ->DataElement(Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected) - ->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetLinearRgbEditorConfig()) + ->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetRgbEditorConfig()) ->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying which photometric unit to work in.") ->Attribute(AZ::Edit::Attributes::EnumValues, &AreaLightComponentConfig::GetValidPhotometricUnits) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp index 2b1510b861..1759b830d2 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp @@ -59,7 +59,7 @@ namespace AZ ->ClassElement(Edit::ClassElements::EditorData, "") ->DataElement(Edit::UIHandlers::Color, &DirectionalLightComponentConfig::m_color, "Color", "Color of the light") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) + ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetRgbEditorConfig()) ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying light values in lux or Ev100") ->EnumAttribute(PhotometricUnit::Lux, "Lux") ->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100") From 2e577a8b14ddbd4b67ceed5311e8caf509b821df Mon Sep 17 00:00:00 2001 From: Sergey Pereslavtsev Date: Tue, 11 Jan 2022 12:11:51 +0000 Subject: [PATCH 139/272] PR feedback Signed-off-by: Sergey Pereslavtsev --- .../Source/Components/TerrainPhysicsColliderComponent.cpp | 2 +- .../Code/Source/Components/TerrainPhysicsColliderComponent.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index 916dd800e2..c51728a5c3 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -53,7 +53,7 @@ namespace Terrain AZ::Data::AssetId TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId() { - if (auto* physicsSystem = AZ::Interface::Get()) + if (const auto* physicsSystem = AZ::Interface::Get()) { if (const auto* physicsConfiguration = physicsSystem->GetConfiguration()) { diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h index 284bc74d88..8a70f282d0 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h @@ -33,10 +33,12 @@ namespace Terrain AZ_CLASS_ALLOCATOR(TerrainPhysicsSurfaceMaterialMapping, AZ::SystemAllocator, 0); AZ_RTTI(TerrainPhysicsSurfaceMaterialMapping, "{A88B5289-DFCD-4564-8395-E2177DFE5B18}"); static void Reflect(AZ::ReflectContext* context); - static AZ::Data::AssetId GetMaterialLibraryId(); SurfaceData::SurfaceTag m_surfaceTag; Physics::MaterialId m_materialId; + + private: + static AZ::Data::AssetId GetMaterialLibraryId(); }; class TerrainPhysicsColliderConfig From 71732c1f4539914b4ff8533deeb4b31c7ddca0a7 Mon Sep 17 00:00:00 2001 From: windbagjacket Date: Tue, 11 Jan 2022 13:21:12 +0000 Subject: [PATCH 140/272] Adding ray tracing toggle to mesh component UI Adding ray tracing toggle to mesh component UI Signed-off-by: windbagjacket --- .../CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp | 3 +++ .../Code/Source/Mesh/MeshComponentController.cpp | 4 +++- .../CommonFeatures/Code/Source/Mesh/MeshComponentController.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp index c89546264a..423145f838 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp @@ -79,6 +79,9 @@ namespace AZ ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MeshComponentConfig::m_useForwardPassIblSpecular, "Use Forward Pass IBL Specular", "Renders IBL specular reflections in the forward pass, using only the most influential probe (based on the position of the entity) and the global IBL cubemap. Can reduce rendering costs, but only recommended for static objects that are affected by at most one reflection probe.") ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MeshComponentConfig::m_isRayTracingEnabled, "Use ray tracing", + "Includes this mesh in ray tracing calculations.") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::EntireTree) ->DataElement(AZ::Edit::UIHandlers::ComboBox, &MeshComponentConfig::m_lodType, "Lod Type", "Lod Method.") ->EnumAttribute(RPI::Cullable::LodType::Default, "Default") ->EnumAttribute(RPI::Cullable::LodType::ScreenCoverage, "Screen Coverage") diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index 517ba90f89..b08670113b 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -76,6 +76,7 @@ namespace AZ ->Field("SortKey", &MeshComponentConfig::m_sortKey) ->Field("ExcludeFromReflectionCubeMaps", &MeshComponentConfig::m_excludeFromReflectionCubeMaps) ->Field("UseForwardPassIBLSpecular", &MeshComponentConfig::m_useForwardPassIblSpecular) + ->Field("IsRayTracingEnabled", &MeshComponentConfig::m_isRayTracingEnabled) ->Field("LodType", &MeshComponentConfig::m_lodType) ->Field("LodOverride", &MeshComponentConfig::m_lodOverride) ->Field("MinimumScreenCoverage", &MeshComponentConfig::m_minimumScreenCoverage) @@ -382,6 +383,7 @@ namespace AZ meshDescriptor.m_modelAsset = m_configuration.m_modelAsset; meshDescriptor.m_useForwardPassIblSpecular = m_configuration.m_useForwardPassIblSpecular; meshDescriptor.m_requiresCloneCallback = RequiresCloning; + meshDescriptor.m_isRayTracingEnabled = m_configuration.m_isRayTracingEnabled; m_meshHandle = m_meshFeatureProcessor->AcquireMesh(meshDescriptor, materials); m_meshFeatureProcessor->ConnectModelChangeEventHandler(m_meshHandle, m_changeEventHandler); @@ -392,7 +394,7 @@ namespace AZ m_meshFeatureProcessor->SetMeshLodConfiguration(m_meshHandle, GetMeshLodConfiguration()); m_meshFeatureProcessor->SetExcludeFromReflectionCubeMaps(m_meshHandle, m_configuration.m_excludeFromReflectionCubeMaps); m_meshFeatureProcessor->SetVisible(m_meshHandle, m_isVisible); - + m_meshFeatureProcessor->SetRayTracingEnabled(m_meshHandle, meshDescriptor.m_isRayTracingEnabled); // [GFX TODO] This should happen automatically. m_changeEventHandler should be passed to AcquireMesh // If the model instance or asset already exists, announce a model change to let others know it's loaded. HandleModelChange(m_meshFeatureProcessor->GetModel(m_meshHandle)); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h index 6b0731fbf7..4d09b0b7b6 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h @@ -50,7 +50,7 @@ namespace AZ RHI::DrawItemSortKey m_sortKey = 0; bool m_excludeFromReflectionCubeMaps = false; bool m_useForwardPassIblSpecular = false; - + bool m_isRayTracingEnabled = true; RPI::Cullable::LodType m_lodType = RPI::Cullable::LodType::Default; RPI::Cullable::LodOverride m_lodOverride = aznumeric_cast(0); float m_minimumScreenCoverage = 1.0f / 1080.0f; From 751caf5f7ccdddcf16f3ba63cbf1d21349ce3191 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Tue, 11 Jan 2022 10:01:02 -0600 Subject: [PATCH 141/272] Updated the Windows ScopedAutoTempDirectory creation logic to use a Uuid. (#6789) Previously it was using `GetTickCount()` for the creation of the directory which can collide if0 there are multiple processes creating a temporary directory via teh ScopedAutoTempDirectory constructor. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../ScopedAutoTempDirectory_Windows.cpp | 70 +++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp b/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp index fcda5d351a..b5314eda14 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp +++ b/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp @@ -8,57 +8,41 @@ #include +#include #include #include #include -#include +#include -namespace AZ +namespace AZ::Test { - namespace Test + ScopedAutoTempDirectory::ScopedAutoTempDirectory() { - ScopedAutoTempDirectory::ScopedAutoTempDirectory() + using UuidString = AZStd::fixed_string; + constexpr DWORD bufferSize = static_cast(AZ::IO::MaxPathLength); + + wchar_t tempDirW[AZ::IO::MaxPathLength]{}; + GetTempPathW(bufferSize, tempDirW); + + AZ::IO::FixedMaxPath tempDirectoryRoot; + AZStd::to_string(tempDirectoryRoot.Native(), tempDirW); + + constexpr int MaxAttempts = 255; + for (int i = 0; i < MaxAttempts; ++i) { - constexpr const DWORD bufferSize = static_cast(AZ::IO::MaxPathLength); - - char tempDir[bufferSize] = {0}; - GetTempPathA(bufferSize, tempDir); - - char workingTempPathBuffer[bufferSize] = {'\0'}; - - int maxAttempts = 2000; // Prevent an infinite loop by setting an arbitrary maximum attempts at finding an available temp folder name - while (maxAttempts > 0) + AZ::IO::FixedMaxPath testPath = tempDirectoryRoot / + AZ::IO::FixedMaxPathString::format("UnitTest-%s", + AZ::Uuid::CreateRandom().ToString().c_str()); + // Try to create the temp directory if it doesn't exist + if (!AZ::IO::SystemFile::Exists(testPath.c_str()) && AZ::IO::SystemFile::CreateDir(testPath.c_str())) { - // Use the system's tick count to base the folder name - ULONGLONG currentTick = GetTickCount64(); - azsnprintf(workingTempPathBuffer, bufferSize, "%sUnitTest-%X", tempDir, aznumeric_cast(currentTick)); - - // Check if the requested directory name is available and re-generate if it already exists - bool exists = AZ::IO::SystemFile::Exists(workingTempPathBuffer); - if (exists) - { - Sleep(1); - maxAttempts--; - continue; - } + azstrncpy(AZStd::data(m_tempDirectory), AZStd::size(m_tempDirectory), + testPath.c_str(), testPath.Native().size()); break; } - - AZ_Error("AzTest", maxAttempts > 0, "Unable to determine a temp directory"); - - if (maxAttempts > 0) - { - // Create the temp directory and track it for deletion - bool tempDirectoryCreated = AZ::IO::SystemFile::CreateDir(workingTempPathBuffer); - if (tempDirectoryCreated) - { - azstrncpy(m_tempDirectory, AZ::IO::MaxPathLength, workingTempPathBuffer, AZ::IO::MaxPathLength); - } - else - { - AZ_Error("AzTest", false, "Unable to create temp directory %s", workingTempPathBuffer); - } - } } - } // Test -} // AZ + + AZ_Error("AzTest", m_tempDirectory[0] != '\0', "Unable to create temp path within directory %s after %d attempts", + tempDirectoryRoot.c_str(), MaxAttempts); + } +} // AZ::Test From df511c1ae863f0854eff9fabaf04d4c0d21299dd Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 11 Jan 2022 10:05:05 -0600 Subject: [PATCH 142/272] Fixed tab order for default input focus on new level dialog Signed-off-by: Chris Galvan --- Code/Editor/NewLevelDialog.cpp | 1 - Code/Editor/NewLevelDialog.ui | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Editor/NewLevelDialog.cpp b/Code/Editor/NewLevelDialog.cpp index c773acdb6f..a97eb30f57 100644 --- a/Code/Editor/NewLevelDialog.cpp +++ b/Code/Editor/NewLevelDialog.cpp @@ -115,7 +115,6 @@ CNewLevelDialog::~CNewLevelDialog() void CNewLevelDialog::OnStartup() { UpdateData(false); - setFocus(); } void CNewLevelDialog::UpdateData(bool fromUi) diff --git a/Code/Editor/NewLevelDialog.ui b/Code/Editor/NewLevelDialog.ui index 14227fbb53..93a88dc897 100644 --- a/Code/Editor/NewLevelDialog.ui +++ b/Code/Editor/NewLevelDialog.ui @@ -133,6 +133,9 @@ 1 + + LEVEL + From 384e8aa863aa8f16b871f650a7b85c1046a30c38 Mon Sep 17 00:00:00 2001 From: smurly Date: Tue, 11 Jan 2022 09:47:04 -0800 Subject: [PATCH 143/272] Move Material Editor Basic test from sandbox to main suite (#6794) * moving material editor test from sandbox to main suite Signed-off-by: Scott Murray * define TEST_DIRECTORY and add logging Signed-off-by: Scott Murray --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 78 +++++++++++++++++++ .../Gem/PythonTests/Atom/TestSuite_Sandbox.py | 71 ----------------- .../Atom/atom_utils/material_editor_utils.py | 7 ++ .../hydra_AtomMaterialEditor_BasicTests.py | 5 ++ 4 files changed, 90 insertions(+), 71 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 905722d103..7051b9983c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -4,10 +4,18 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ +import logging +import os import pytest +import ly_test_tools.environment.file_system as file_system +import editor_python_test_tools.hydra_test_utils as hydra + from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite +logger = logging.getLogger(__name__) +TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") + @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @@ -114,3 +122,73 @@ class TestAutomation(EditorTestSuite): class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest): from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module + + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_generic']) +class TestMaterialEditorBasicTests(object): + @pytest.fixture(autouse=True) + def setup_teardown(self, request, workspace, project): + def delete_files(): + file_system.delete( + [ + os.path.join(workspace.paths.project(), "Materials", "test_material.material"), + os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"), + os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"), + ], + True, + True, + ) + # Cleanup our newly created materials + delete_files() + + def teardown(): + # Cleanup our newly created materials + delete_files() + + request.addfinalizer(teardown) + + @pytest.mark.parametrize("exe_file_name", ["MaterialEditor"]) + @pytest.mark.test_case_id("C34448113") # Creating a New Asset. + @pytest.mark.test_case_id("C34448114") # Opening an Existing Asset. + @pytest.mark.test_case_id("C34448115") # Closing Selected Material. + @pytest.mark.test_case_id("C34448116") # Closing All Materials. + @pytest.mark.test_case_id("C34448117") # Closing all but Selected Material. + @pytest.mark.test_case_id("C34448118") # Saving Material. + @pytest.mark.test_case_id("C34448119") # Saving as a New Material. + @pytest.mark.test_case_id("C34448120") # Saving as a Child Material. + @pytest.mark.test_case_id("C34448121") # Saving all Open Materials. + def test_MaterialEditorBasicTests( + self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name): + + expected_lines = [ + "Material opened: True", + "Test asset doesn't exist initially: True", + "New asset created: True", + "New Material opened: True", + "Material closed: True", + "All documents closed: True", + "Close All Except Selected worked as expected: True", + "Actual Document saved with changes: True", + "Document saved as copy is saved with changes: True", + "Document saved as child is saved with changes: True", + "Save All worked as expected: True", + ] + unexpected_lines = [ + "Traceback (most recent call last):" + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + generic_launcher, + "hydra_AtomMaterialEditor_BasicTests.py", + run_python="--runpython", + timeout=43, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + null_renderer=True, + log_file_name="MaterialEditor.log", + enable_prefab_system=False, + ) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index 29f90e6807..c9182070f6 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -83,77 +83,6 @@ class TestAtomEditorComponentsMain(object): ) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ['windows_generic']) -@pytest.mark.system -class TestMaterialEditorBasicTests(object): - @pytest.fixture(autouse=True) - def setup_teardown(self, request, workspace, project): - def delete_files(): - file_system.delete( - [ - os.path.join(workspace.paths.project(), "Materials", "test_material.material"), - os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"), - os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"), - ], - True, - True, - ) - # Cleanup our newly created materials - delete_files() - - def teardown(): - # Cleanup our newly created materials - delete_files() - - request.addfinalizer(teardown) - - @pytest.mark.parametrize("exe_file_name", ["MaterialEditor"]) - @pytest.mark.test_case_id("C34448113") # Creating a New Asset. - @pytest.mark.test_case_id("C34448114") # Opening an Existing Asset. - @pytest.mark.test_case_id("C34448115") # Closing Selected Material. - @pytest.mark.test_case_id("C34448116") # Closing All Materials. - @pytest.mark.test_case_id("C34448117") # Closing all but Selected Material. - @pytest.mark.test_case_id("C34448118") # Saving Material. - @pytest.mark.test_case_id("C34448119") # Saving as a New Material. - @pytest.mark.test_case_id("C34448120") # Saving as a Child Material. - @pytest.mark.test_case_id("C34448121") # Saving all Open Materials. - def test_MaterialEditorBasicTests( - self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name): - - expected_lines = [ - "Material opened: True", - "Test asset doesn't exist initially: True", - "New asset created: True", - "New Material opened: True", - "Material closed: True", - "All documents closed: True", - "Close All Except Selected worked as expected: True", - "Actual Document saved with changes: True", - "Document saved as copy is saved with changes: True", - "Document saved as child is saved with changes: True", - "Save All worked as expected: True", - ] - unexpected_lines = [ - "Traceback (most recent call last):" - ] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - generic_launcher, - "hydra_AtomMaterialEditor_BasicTests.py", - run_python="--runpython", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - log_file_name="MaterialEditor.log", - enable_prefab_system=False, - ) - - @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py index b21c74de19..f7ff970541 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py @@ -162,6 +162,13 @@ def select_model_config(configname): azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname) +def destroy_main_window(): + """ + Closes the Material Editor window + """ + azlmbr.atomtools.AtomToolsMainWindowFactoryRequestBus(azlmbr.bus.Broadcast, "DestroyMainWindow") + + def wait_for_condition(function, timeout_in_seconds=1.0): # type: (function, float) -> bool """ diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py index 9f8f6c44b2..baad02318d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py @@ -186,6 +186,11 @@ def run(): material_editor.set_property(document2_id, property2_name, initial_color) material_editor.save_all() material_editor.close_all_documents() + material_editor.wait_for_condition(lambda: + (not material_editor.is_open(document1_id)) and + (not material_editor.is_open(document2_id)) and + (not material_editor.is_open(document3_id)), 2.0) + material_editor.destroy_main_window() if __name__ == "__main__": From d09da902d660fa164620b1c72ef981a635adadbe Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 11 Jan 2022 11:26:44 -0800 Subject: [PATCH 144/272] Fixed test materials since all the "lucy" stuff was renamed to "hermanubis". Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../SkinTestCases/001_lucy_regression_test.material | 8 ++++---- .../SkinTestCases/002_wrinkle_regression_test.material | 4 ++-- .../101_DetailMaps_LucyBaseNoDetailMaps.material | 8 ++++---- .../StandardPbrTestCases/102_DetailMaps_All.material | 10 +++++----- .../105_DetailMaps_BlendMaskUsingDetailUVs.material | 8 ++++---- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material index bafb047be9..e6c032b0f9 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material @@ -11,7 +11,7 @@ 0.29372090101242068, 1.0 ], - "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", "useTexture": false }, "detailLayerGroup": { @@ -30,14 +30,14 @@ }, "normal": { "flipY": true, - "textureMap": "Objects/Lucy/Lucy_Normal.png" + "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png" }, "subsurfaceScattering": { "enableSubsurfaceScattering": true, - "influenceMap": "Objects/Lucy/Lucy_thickness.tif", + "influenceMap": "Objects/Hermanubis/Hermanubis_thickness.tif", "scatterDistance": 15.0, "subsurfaceScatterFactor": 0.4300000071525574, - "thicknessMap": "Objects/Lucy/Lucy_thickness.tif", + "thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", "transmissionAttenuation": 15.0, "transmissionDistortion": 0.3499999940395355, "transmissionMode": "ThickObject", diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material index 78f597b14f..9b955ddb1d 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material @@ -29,14 +29,14 @@ }, "normal": { "flipY": true, - "textureMap": "Objects/Lucy/Lucy_Normal.png" + "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png" }, "subsurfaceScattering": { "enableSubsurfaceScattering": true, "influenceMap": "TestData/Textures/checker8x8_gray_512.png", "scatterDistance": 15.0, "subsurfaceScatterFactor": 0.4300000071525574, - "thicknessMap": "Objects/Lucy/Lucy_thickness.tif", + "thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif", "transmissionAttenuation": 15.0, "transmissionDistortion": 0.3499999940395355, "transmissionMode": "ThickObject", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material index 6d77be5a49..82192bac41 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material @@ -5,7 +5,7 @@ "propertyLayoutVersion": 3, "properties": { "baseColor": { - "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", "textureMapUv": "Unwrapped" }, "detailUV": { @@ -15,16 +15,16 @@ ] }, "metallic": { - "textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", "textureMapUv": "Unwrapped" }, "normal": { "flipY": true, - "textureMap": "Objects/Lucy/Lucy_Normal.png", + "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", "textureMapUv": "Unwrapped" }, "roughness": { - "textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", "textureMapUv": "Unwrapped" } } diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material index 1a29f392c8..dd31d00db0 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material @@ -5,12 +5,12 @@ "propertyLayoutVersion": 3, "properties": { "baseColor": { - "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", "textureMapUv": "Unwrapped" }, "detailLayerGroup": { "baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg", - "blendDetailMask": "Objects/Lucy/Lucy_ao.tif", + "blendDetailMask": "Objects/Hermanubis/Hermanubis_ao.tif", "blendDetailMaskUv": "Unwrapped", "enableBaseColor": true, "enableDetailLayer": true, @@ -26,16 +26,16 @@ "scale": 10.0 }, "metallic": { - "textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", "textureMapUv": "Unwrapped" }, "normal": { "flipY": true, - "textureMap": "Objects/Lucy/Lucy_Normal.png", + "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", "textureMapUv": "Unwrapped" }, "roughness": { - "textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", "textureMapUv": "Unwrapped" } } diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material index a69b72b623..6964342447 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material @@ -5,7 +5,7 @@ "propertyLayoutVersion": 3, "properties": { "baseColor": { - "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", "textureMapUv": "Unwrapped" }, "detailLayerGroup": { @@ -25,16 +25,16 @@ "scale": 10.0 }, "metallic": { - "textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png", "textureMapUv": "Unwrapped" }, "normal": { "flipY": true, - "textureMap": "Objects/Lucy/Lucy_Normal.png", + "textureMap": "Objects/Hermanubis/Hermanubis_Normal.png", "textureMapUv": "Unwrapped" }, "roughness": { - "textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png", + "textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png", "textureMapUv": "Unwrapped" } } From 48a90e0668feb42328d775b5b57f4df48eb1b6b3 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 11 Jan 2022 13:37:55 -0600 Subject: [PATCH 145/272] Adding wait_for_condition checks for level save/export, and extending wait for slice creation test Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py | 3 ++- .../EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py | 3 ++- .../dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py | 3 ++- .../SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py index 86035bfbae..b4650c782e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py @@ -110,7 +110,8 @@ def DynamicSliceInstanceSpawner_Embedded_E2E(): general.save_level() general.export_to_engine() pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - Report.result(Tests.saved_and_exported, os.path.exists(pak_path)) + success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + Report.result(Tests.saved_and_exported, success) if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py index 2353095849..a5e7e90ce2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py @@ -132,7 +132,8 @@ def DynamicSliceInstanceSpawner_External_E2E(): general.save_level() general.export_to_engine() pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - Report.result(Tests.saved_and_exported, os.path.exists(pak_path)) + success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + Report.result(Tests.saved_and_exported, success) if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py index f2c7faae8a..6b5a80ee8e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py @@ -156,7 +156,8 @@ def LayerBlender_E2E_Editor(): general.save_level() general.export_to_engine() pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak") - Report.result(Tests.saved_and_exported, os.path.exists(pak_path)) + success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0) + Report.result(Tests.saved_and_exported, success) if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py index c36d1b5bc9..fc55080cec 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py @@ -73,7 +73,7 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks(): slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path) # 2.3) Verify if the slice has been created successfully - spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0) + spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0) Report.result(Tests.spawner_slice_created, spawner_slice_success) # 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport From f03c2885f0347aaa2d64a03e51d63727e84b2de2 Mon Sep 17 00:00:00 2001 From: SWMasterson Date: Tue, 11 Jan 2022 12:21:45 -0800 Subject: [PATCH 146/272] Moving AutomatedTesting Atom levels into the Graphics subfolder (#6791) Signed-off-by: Sean Masterson --- .../PbrMaterialChart/PbrMaterialChart.prefab | 88 +++++++++---------- .../PbrMaterialChart/materials/basic.material | 0 .../materials/basic_m00_r00.material | 0 .../materials/basic_m00_r01.material | 0 .../materials/basic_m00_r02.material | 0 .../materials/basic_m00_r03.material | 0 .../materials/basic_m00_r04.material | 0 .../materials/basic_m00_r05.material | 0 .../materials/basic_m00_r06.material | 0 .../materials/basic_m00_r07.material | 0 .../materials/basic_m00_r08.material | 0 .../materials/basic_m00_r09.material | 0 .../materials/basic_m00_r10.material | 0 .../materials/basic_m10_r00.material | 0 .../materials/basic_m10_r01.material | 0 .../materials/basic_m10_r02.material | 0 .../materials/basic_m10_r03.material | 0 .../materials/basic_m10_r04.material | 0 .../materials/basic_m10_r05.material | 0 .../materials/basic_m10_r06.material | 0 .../materials/basic_m10_r07.material | 0 .../materials/basic_m10_r08.material | 0 .../materials/basic_m10_r09.material | 0 .../materials/basic_m10_r10.material | 0 .../{ => Graphics}/PbrMaterialChart/tags.txt | 0 .../{ => Graphics}/Sponza/Sponza.prefab | 0 .../Levels/{ => Graphics}/Sponza/tags.txt | 0 .../macbeth_shaderballs.prefab | 0 .../macbeth_shaderballs/tags.txt | 0 29 files changed, 44 insertions(+), 44 deletions(-) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/PbrMaterialChart.prefab (97%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r00.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r01.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r02.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r03.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r04.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r05.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r06.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r07.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r08.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r09.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m00_r10.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r00.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r01.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r02.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r03.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r04.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r05.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r06.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r07.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r08.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r09.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/materials/basic_m10_r10.material (100%) rename AutomatedTesting/Levels/{ => Graphics}/PbrMaterialChart/tags.txt (100%) rename AutomatedTesting/Levels/{ => Graphics}/Sponza/Sponza.prefab (100%) rename AutomatedTesting/Levels/{ => Graphics}/Sponza/tags.txt (100%) rename AutomatedTesting/Levels/{ => Graphics}/macbeth_shaderballs/macbeth_shaderballs.prefab (100%) rename AutomatedTesting/Levels/{ => Graphics}/macbeth_shaderballs/tags.txt (100%) diff --git a/AutomatedTesting/Levels/PbrMaterialChart/PbrMaterialChart.prefab b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/PbrMaterialChart.prefab similarity index 97% rename from AutomatedTesting/Levels/PbrMaterialChart/PbrMaterialChart.prefab rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/PbrMaterialChart.prefab index faa93597de..2c0ee5cb1a 100644 --- a/AutomatedTesting/Levels/PbrMaterialChart/PbrMaterialChart.prefab +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/PbrMaterialChart.prefab @@ -1474,9 +1474,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{1FD47684-2E9E-5525-BBCA-251795F9033C}" + "guid": "{12B5A321-3D64-5DF6-9E15-D8F447229EC1}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r00.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r00.azmaterial" } } } @@ -1569,9 +1569,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{B5660D78-818E-5273-AF3D-EC8189E2E6CB}" + "guid": "{EB8B9C49-D6F4-5098-AC97-543381E2554A}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r01.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r01.azmaterial" } } } @@ -1824,9 +1824,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{512443BD-9511-5F13-A84A-3ED5DB9E9B5A}" + "guid": "{CAA9CAFC-8A48-5406-BE26-448E5AA1A5B0}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r02.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r02.azmaterial" } } } @@ -1926,9 +1926,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{E28A5CC5-4B8B-5B90-877A-3D92C75DC75A}" + "guid": "{2F338C0B-EF86-5AC4-AEE6-28A26BB9E97E}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r03.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r03.azmaterial" } } } @@ -2028,9 +2028,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{1495BCCF-3F96-5D0B-8176-228DB22CEC82}" + "guid": "{9BF4E656-0D4F-5746-A256-32740742712B}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r04.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r04.azmaterial" } } } @@ -2130,9 +2130,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{40494612-0ABF-55B5-9C56-E968763FCFDE}" + "guid": "{850398D7-386A-56C6-AEB2-95E4F64368B1}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r05.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r05.azmaterial" } } } @@ -2232,9 +2232,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{76CF9D4A-009F-5494-83AB-6E3D4D1B4A36}" + "guid": "{74784C2A-A713-5C6A-8B3D-B66CAE3DD055}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r06.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r06.azmaterial" } } } @@ -2334,9 +2334,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{8431B792-E6CC-51DD-B82E-F3E4A12FCB4A}" + "guid": "{4F9F91F7-7E22-5A14-856D-194CC258E70D}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r07.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r07.azmaterial" } } } @@ -2436,9 +2436,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{4B1F29FF-7971-5524-AA1B-0DC2392A33C4}" + "guid": "{842AE870-802B-5934-997F-0965F960ECB9}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r08.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r08.azmaterial" } } } @@ -2538,9 +2538,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{785BE6DE-C0EB-5B47-9438-4F9ECFC34A96}" + "guid": "{0184CF10-E675-5C33-B1B9-009C383AB463}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r09.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r09.azmaterial" } } } @@ -2640,9 +2640,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{C40DE9AE-6756-57E7-B3B4-FB0542B5CD0F}" + "guid": "{6DDA0761-C165-58CC-B45E-03C29F0CF598}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m00_r10.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r10.azmaterial" } } } @@ -2896,9 +2896,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{251C4C29-4ECD-5763-AF4F-20675EAC048B}" + "guid": "{101AB53A-3B3E-5ACF-841C-65DB2BFBF305}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r04.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r04.azmaterial" } } } @@ -2998,9 +2998,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{02D082C4-5032-57CC-A081-BC4D8518BCF0}" + "guid": "{B82B96D6-7511-5E22-A36E-FFF682B3236B}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r05.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r05.azmaterial" } } } @@ -3100,9 +3100,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{FA9D8842-95B2-5371-8352-CBEEEAABE676}" + "guid": "{DBED5292-3E17-5038-9974-80A8BB1F79E8}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r06.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r06.azmaterial" } } } @@ -3202,9 +3202,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{522A9626-FF4C-561A-A44A-64B68F7274D2}" + "guid": "{25F07733-365C-5826-AEE3-E92FBE807555}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r07.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r07.azmaterial" } } } @@ -3304,9 +3304,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{06DDFD66-D7F5-5D55-8972-6D61276E88F6}" + "guid": "{C9A7B916-CF71-5A34-B9B9-54FE8CB058DC}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r00.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r00.azmaterial" } } } @@ -3399,9 +3399,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{060EF1B7-1029-5227-B03B-1415C74E9D65}" + "guid": "{85C8DFC5-358D-579D-B922-14FA1B401571}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r08.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r08.azmaterial" } } } @@ -3501,9 +3501,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{7B7BC6F8-150A-518F-816E-2F7DBE786461}" + "guid": "{51924281-7A06-5654-B783-A4F5759063ED}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r01.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r01.azmaterial" } } } @@ -3603,9 +3603,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{270881B6-21E9-509D-A6CD-1046674FB0BE}" + "guid": "{7877F64E-26E3-558C-B6D9-B609ED6E43BF}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r09.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r09.azmaterial" } } } @@ -3705,9 +3705,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{C0538953-C56E-5C1A-BBE2-E6BE04764C20}" + "guid": "{6CC3C6B9-EE05-5A77-A12D-7085D93D89DB}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r02.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r02.azmaterial" } } } @@ -3874,9 +3874,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{5EA26E09-E3D6-5181-8E7A-F2E98A24247C}" + "guid": "{E6E15876-EEF3-555D-BD80-1B9D5A7ECC7D}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r10.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r10.azmaterial" } } } @@ -3976,9 +3976,9 @@ "{}": { "MaterialAsset": { "assetId": { - "guid": "{E1A5D708-7A49-5CCA-81C3-4CB337C47703}" + "guid": "{83179EEC-BAC7-5D39-9788-37D33E9584B1}" }, - "assetHint": "levels/pbrmaterialchart/materials/basic_m10_r03.azmaterial" + "assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r03.azmaterial" } } } diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r00.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r01.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r02.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r03.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r04.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r05.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r06.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r07.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r08.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r09.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m00_r10.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r00.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r01.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r02.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r03.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r04.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r05.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r06.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r07.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r08.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r09.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/materials/basic_m10_r10.material rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material diff --git a/AutomatedTesting/Levels/PbrMaterialChart/tags.txt b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/tags.txt similarity index 100% rename from AutomatedTesting/Levels/PbrMaterialChart/tags.txt rename to AutomatedTesting/Levels/Graphics/PbrMaterialChart/tags.txt diff --git a/AutomatedTesting/Levels/Sponza/Sponza.prefab b/AutomatedTesting/Levels/Graphics/Sponza/Sponza.prefab similarity index 100% rename from AutomatedTesting/Levels/Sponza/Sponza.prefab rename to AutomatedTesting/Levels/Graphics/Sponza/Sponza.prefab diff --git a/AutomatedTesting/Levels/Sponza/tags.txt b/AutomatedTesting/Levels/Graphics/Sponza/tags.txt similarity index 100% rename from AutomatedTesting/Levels/Sponza/tags.txt rename to AutomatedTesting/Levels/Graphics/Sponza/tags.txt diff --git a/AutomatedTesting/Levels/macbeth_shaderballs/macbeth_shaderballs.prefab b/AutomatedTesting/Levels/Graphics/macbeth_shaderballs/macbeth_shaderballs.prefab similarity index 100% rename from AutomatedTesting/Levels/macbeth_shaderballs/macbeth_shaderballs.prefab rename to AutomatedTesting/Levels/Graphics/macbeth_shaderballs/macbeth_shaderballs.prefab diff --git a/AutomatedTesting/Levels/macbeth_shaderballs/tags.txt b/AutomatedTesting/Levels/Graphics/macbeth_shaderballs/tags.txt similarity index 100% rename from AutomatedTesting/Levels/macbeth_shaderballs/tags.txt rename to AutomatedTesting/Levels/Graphics/macbeth_shaderballs/tags.txt From faf3255ea64ccd6524e7be0f048bfa6721a7eacd Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 11 Jan 2022 14:27:09 -0800 Subject: [PATCH 147/272] Renamed more files from "lucy" to "hermanubis" Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- ...sion_test.material => 001_hermanubis_regression_test.material} | 0 ...tailMaps.material => 101_DetailMaps_BaseNoDetailMaps.material} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Gems/Atom/TestData/TestData/Materials/SkinTestCases/{001_lucy_regression_test.material => 001_hermanubis_regression_test.material} (100%) rename Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/{101_DetailMaps_LucyBaseNoDetailMaps.material => 101_DetailMaps_BaseNoDetailMaps.material} (100%) diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material similarity index 100% rename from Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material rename to Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material similarity index 100% rename from Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material rename to Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material From 5cd8b0e1724eb93ad5c85cf2c34b414d9059ba75 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 11 Jan 2022 14:55:44 -0800 Subject: [PATCH 148/272] Renamed more files from "lucy" to "hermanubis" Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../StandardPbrTestCases/103_DetailMaps_BaseColor.material | 2 +- .../StandardPbrTestCases/104_DetailMaps_Normal.material | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material index 5bddeaa7e5..eda8ef12de 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material", + "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", "propertyLayoutVersion": 3, "properties": { "detailLayerGroup": { diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material index 4c64a696d2..291f0fc828 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", - "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material", + "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", "propertyLayoutVersion": 3, "properties": { "detailLayerGroup": { From 07e6b54ca5c76c95524563c8873a2948934b7f67 Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:49:16 -0800 Subject: [PATCH 149/272] Fix names display index and scripting dev gem (#6822) * Fix input/output params not being zero-based * Expose missing Dump Database developer command * Fix issue where developer gem name is not the same as the target * Let the user specify folder to write to Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Code/Editor/Nodes/NodeDisplayUtils.cpp | 77 +++++++------------ .../Code/Editor/Source/TSGenerateAction.cpp | 23 ++++++ Gems/ScriptCanvasDeveloper/gem.json | 2 +- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp index 31d012fd4a..60eaba24f8 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp @@ -376,60 +376,60 @@ namespace ScriptCanvasEditor::Nodes int paramIndex = 0; int outputIndex = 0; + int slotIndex = 0; auto busId = methodNode->GetBusSlotId(); for (const auto& slot : methodNode->GetSlots()) { GraphCanvas::TranslationKey slotKey = key; - int& index = (slot.IsData() && slot.IsInput()) ? paramIndex : outputIndex; + int& inputOutputIndex = slot.IsInput() ? paramIndex : outputIndex; + const bool isBusIdSlot = + methodNode->HasBusID() && busId == slot.GetId() && slot.GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn(); if (slot.IsVisible()) { - AZ::EntityId graphCanvasSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, index); + AZ::EntityId graphCanvasSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, slotIndex); details.m_name = slot.GetName(); details.m_tooltip = slot.GetToolTip(); - if (methodNode->HasBusID() && busId == slot.GetId() && slot.GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn()) + if (isBusIdSlot) { key = ::Translation::GlobalKeys::EBusSenderIDKey; - GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details); + GraphCanvas::TranslationRequestBus::BroadcastResult( + details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details); } - else + else if (slot.IsData()) { - - - if (slot.IsData()) + key.clear(); + key << context << className << "methods" << updatedMethodName; + if (slot.IsInput()) { - key.clear(); - key << context << className << "methods" << updatedMethodName; - if (slot.IsData() && slot.IsInput()) - { - key << "params"; - } - else - { - key << "results"; - } - key << index; - - GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details); + key << "params"; } - - if (slot.IsData()) - { - index++; + else + { + key << "results"; } + key << inputOutputIndex; + + GraphCanvas::TranslationRequestBus::BroadcastResult( + details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details); } - GraphCanvas::SlotRequestBus::Event(graphCanvasSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip); + GraphCanvas::SlotRequestBus::Event( + graphCanvasSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip); UpdateSlotDatumLabel(graphCanvasNodeId, slot.GetId(), details.m_name); - } - ++index; + ++slotIndex; + + if (!isBusIdSlot && slot.IsData()) + { + ++inputOutputIndex; + } } // Set the name @@ -485,9 +485,6 @@ namespace ScriptCanvasEditor::Nodes AZStd::vector< ScriptCanvas::SlotId > scriptCanvasSlots = busNode->GetNonEventSlotIds(); - int paramIndex = 0; - int outputIndex = 0; - for (const auto& slotId : scriptCanvasSlots) { ScriptCanvas::Slot* slot = busNode->GetSlot(slotId); @@ -501,8 +498,6 @@ namespace ScriptCanvasEditor::Nodes if (slot->IsVisible()) { - int& index = (slot->IsData() && slot->IsInput()) ? paramIndex : outputIndex; - AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, (*slot), group); if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn()) @@ -516,8 +511,6 @@ namespace ScriptCanvasEditor::Nodes GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip); } - - ++index; } } @@ -615,17 +608,12 @@ namespace ScriptCanvasEditor::Nodes *graphCanvasUserData = azEventNode->GetEntityId(); } - int paramIndex = 0; - int outputIndex = 0; - for (const ScriptCanvas::Slot& slot: azEventNode->GetSlots()) { GraphCanvas::SlotGroup group = GraphCanvas::SlotGroups::Invalid; if (slot.IsVisible()) { - int& index = (slot.IsData() && slot.IsInput()) ? paramIndex : outputIndex; - AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, group); GraphCanvas::TranslationKey key; @@ -636,8 +624,6 @@ namespace ScriptCanvasEditor::Nodes GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetName, details.m_name); GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetTooltip, details.m_tooltip);; - - ++index; } } @@ -703,9 +689,6 @@ namespace ScriptCanvasEditor::Nodes AZStd::vector< ScriptCanvas::SlotId > scriptCanvasSlots = busNode->GetNonEventSlotIds(); - int paramIndex = 0; - int outputIndex = 0; - for (const auto& slotId : scriptCanvasSlots) { ScriptCanvas::Slot* slot = busNode->GetSlot(slotId); @@ -719,8 +702,6 @@ namespace ScriptCanvasEditor::Nodes if (slot->IsVisible()) { - int& index = (slot->IsData() && slot->IsInput()) ? paramIndex : outputIndex; - AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, (*slot), group); if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn()) @@ -731,8 +712,6 @@ namespace ScriptCanvasEditor::Nodes GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details); GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip); } - - ++index; } } diff --git a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/TSGenerateAction.cpp b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/TSGenerateAction.cpp index 56168f6f56..75cf7e5392 100644 --- a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/TSGenerateAction.cpp +++ b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/TSGenerateAction.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #endif #include @@ -34,6 +37,26 @@ namespace ScriptCanvasDeveloperEditor qAction->setShortcut(QAction::tr("Ctrl+Alt+R", "Developer|Reload Text")); QObject::connect(qAction, &QAction::triggered, [mainWindow]() { ReloadText(mainWindow); }); + qAction = mainMenu->addAction(QAction::tr("Dump Translation Database")); + qAction->setAutoRepeat(false); + qAction->setShortcut(QAction::tr("Ctrl+Alt+L", "Developer|Dump Translation Database")); + QObject::connect( + qAction, &QAction::triggered, + [mainWindow]() + { + QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + QString directory = QFileDialog::getExistingDirectory(mainWindow, + QObject::tr("Select output folder for sc_translation.log file"), defaultPath); + if (!directory.isEmpty()) + { + const QString path = QDir::toNativeSeparators(directory + "/sc_translation.log"); + GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::DumpDatabase, path.toUtf8().constData()); + QMessageBox::information( + mainWindow, QObject::tr("Finished writing translation database"), + QObject::tr("Translation database written to:
%1").arg(path)); + } + }); + } return qAction; diff --git a/Gems/ScriptCanvasDeveloper/gem.json b/Gems/ScriptCanvasDeveloper/gem.json index 51aed9d9fa..fe1fdea0fc 100644 --- a/Gems/ScriptCanvasDeveloper/gem.json +++ b/Gems/ScriptCanvasDeveloper/gem.json @@ -1,5 +1,5 @@ { - "gem_name": "ScriptCanvasDeveloperGem", + "gem_name": "ScriptCanvasDeveloper", "display_name": "Script Canvas Developer", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", From 73419387c5235eba97ab11f194e6c1049c43f981 Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:49:59 -0800 Subject: [PATCH 150/272] Check engines_path in get_registered (#6828) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- scripts/o3de/o3de/manifest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/o3de/o3de/manifest.py b/scripts/o3de/o3de/manifest.py index 7392637c99..a334109e6a 100644 --- a/scripts/o3de/o3de/manifest.py +++ b/scripts/o3de/o3de/manifest.py @@ -624,6 +624,9 @@ def get_registered(engine_name: str = None, this_engines_name = engine_json_data['engine_name'] if this_engines_name == engine_name: return engine_path + engines_path = json_data.get('engines_path', {}) + if engine_name in engines_path: + return pathlib.Path(engines_path[engine_name]).resolve() elif isinstance(project_name, str): projects = get_all_projects() From 13bc91aa77880b46760e088e7ed3f0adfaad8b16 Mon Sep 17 00:00:00 2001 From: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:53:46 -0800 Subject: [PATCH 151/272] Split editor entity activation from PrefabSystemComponent (#6787) * Split editor entity activation from PrefabSystemComponent Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Fixed a small typo Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Pass entity activation callback during prefab instantiation for failing tests Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> --- .../PrefabEditorEntityOwnershipService.cpp | 8 ++- .../Prefab/PrefabSystemComponent.cpp | 12 +++-- .../Prefab/PrefabSystemComponent.h | 10 +++- .../Prefab/PrefabSystemComponentInterface.h | 11 ++++- .../Tests/Prefab/PrefabUndoLinkTests.cpp | 49 ++++++++++++++++--- .../Tests/Prefab/PrefabUndoTests.cpp | 9 +++- 6 files changed, 81 insertions(+), 18 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 418d176daa..4a1198fdfe 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -349,8 +349,12 @@ namespace AzToolsFramework instanceToParentUnder = *m_rootInstance; } - AZStd::unique_ptr instantiatedPrefabInstance = - m_prefabSystemComponent->InstantiatePrefab(filePath, instanceToParentUnder); + AZStd::unique_ptr instantiatedPrefabInstance = m_prefabSystemComponent->InstantiatePrefab( + filePath, instanceToParentUnder, + [this](const EntityList& entities) + { + HandleEntitiesAdded(entities); + }); if (instantiatedPrefabInstance) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 9936e466c3..98e0144f22 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -277,7 +277,7 @@ namespace AzToolsFramework } AZStd::unique_ptr PrefabSystemComponent::InstantiatePrefab( - AZ::IO::PathView filePath, InstanceOptionalReference parent) + AZ::IO::PathView filePath, InstanceOptionalReference parent, const InstantiatedEntitiesCallback& instantiatedEntitiesCallback) { // Retrieve the template id for the source prefab filepath Prefab::TemplateId templateId = GetTemplateIdFromFilePath(filePath); @@ -297,11 +297,11 @@ namespace AzToolsFramework return nullptr; } - return InstantiatePrefab(templateId, parent); + return InstantiatePrefab(templateId, parent, instantiatedEntitiesCallback); } AZStd::unique_ptr PrefabSystemComponent::InstantiatePrefab( - TemplateId templateId, InstanceOptionalReference parent) + TemplateId templateId, InstanceOptionalReference parent, const InstantiatedEntitiesCallback& instantiatedEntitiesCallback) { TemplateReference instantiatingTemplate = FindTemplate(templateId); @@ -324,8 +324,10 @@ namespace AzToolsFramework return nullptr; } - AzToolsFramework::EditorEntityContextRequestBus::Broadcast( - &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities); + if (instantiatedEntitiesCallback) + { + instantiatedEntitiesCallback(newEntities); + } return newInstance; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index d71065f8fc..b547e9bdd2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -124,19 +124,25 @@ namespace AzToolsFramework * Generates a new Prefab Instance based on the Template whose source is stored in filepath. * @param filePath The path to the prefab source file containing the template being instantiated. * @param parent Reference of the target instance the instantiated instance will be placed under. + * @param instantiatedEntitiesCallback An optional callback that can be used to modify the instantiated entities. * @return A unique_ptr to the newly instantiated instance. Null if operation failed. */ AZStd::unique_ptr InstantiatePrefab( - AZ::IO::PathView filePath, InstanceOptionalReference parent = AZStd::nullopt) override; + AZ::IO::PathView filePath, + InstanceOptionalReference parent = AZStd::nullopt, + const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) override; /** * Generates a new Prefab Instance based on the Template referenced by templateId. * @param templateId The id of the template being instantiated. * @param parent Reference of the target instance the instantiated instance will be placed under. + * @param instantiatedEntitiesCallback An optional callback that can be used to modify the instantiated entities. * @return A unique_ptr to the newly instantiated instance. Null if operation failed. */ AZStd::unique_ptr InstantiatePrefab( - TemplateId templateId, InstanceOptionalReference parent = AZStd::nullopt) override; + TemplateId templateId, + InstanceOptionalReference parent = AZStd::nullopt, + const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) override; /** * Add a new Link into Prefab System Component and create a unique id for it. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index ce75930cb6..d39e868ef4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -27,6 +27,9 @@ namespace AzToolsFramework class PrefabSystemComponentInterface { public: + + using InstantiatedEntitiesCallback = AZStd::function&)>; + AZ_RTTI(PrefabSystemComponentInterface, "{8E95A029-67F9-4F74-895F-DDBFE29516A0}"); virtual TemplateReference FindTemplate(TemplateId id) = 0; @@ -70,9 +73,13 @@ namespace AzToolsFramework virtual void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalConstReference instanceToExclude = AZStd::nullopt) = 0; virtual AZStd::unique_ptr InstantiatePrefab( - AZ::IO::PathView filePath, InstanceOptionalReference parent = AZStd::nullopt) = 0; + AZ::IO::PathView filePath, + InstanceOptionalReference parent = AZStd::nullopt, + const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) = 0; virtual AZStd::unique_ptr InstantiatePrefab( - TemplateId templateId, InstanceOptionalReference parent = AZStd::nullopt) = 0; + TemplateId templateId, + InstanceOptionalReference parent = AZStd::nullopt, + const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) = 0; virtual AZStd::unique_ptr CreatePrefab(const AZStd::vector& entities, AZStd::vector>&& instancesToConsume, AZ::IO::PathView filePath, AZStd::unique_ptr containerEntity = nullptr, InstanceOptionalReference parent = AZStd::nullopt, diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp index 8fafe1f177..442894c101 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp @@ -170,7 +170,14 @@ namespace UnitTest m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); //instantiate a new nested instance - nestedInstance = m_prefabSystemComponent->InstantiatePrefab(nestedTemplateId); + nestedInstance = m_prefabSystemComponent->InstantiatePrefab( + nestedTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); + nestedContainerEntityId = nestedInstance->GetContainerEntityId(); AZ::ComponentApplicationBus::BroadcastResult(nestedContainerEntity, &AZ::ComponentApplicationBus::Events::FindEntity, nestedContainerEntityId); ASSERT_TRUE(nestedContainerEntity); @@ -198,7 +205,13 @@ namespace UnitTest LinkId linkId = undoInstanceLinkNode.GetLinkId(); - rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId); + rootInstance = m_prefabSystemComponent->InstantiatePrefab( + rootTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId); //verify the link was created @@ -228,7 +241,13 @@ namespace UnitTest m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); //verify the update worked - rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId); + rootInstance = m_prefabSystemComponent->InstantiatePrefab( + rootTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId); nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]); nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId(); @@ -244,7 +263,13 @@ namespace UnitTest m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); //verify the undo update worked - rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId); + rootInstance = m_prefabSystemComponent->InstantiatePrefab( + rootTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId); nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]); nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId(); @@ -259,7 +284,13 @@ namespace UnitTest undoLinkUpdateNode.Redo(); m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); - rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId); + rootInstance = m_prefabSystemComponent->InstantiatePrefab( + rootTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId); nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]); nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId(); @@ -287,7 +318,13 @@ namespace UnitTest m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); //verify the update worked - rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId); + rootInstance = m_prefabSystemComponent->InstantiatePrefab( + rootTemplateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId); nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]); nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId(); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp index 5c68b30e8f..cfba41696c 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoTests.cpp @@ -79,7 +79,14 @@ namespace UnitTest // verify template updated correctly //instantiate second instance for checking if propogation works - AZStd::unique_ptr secondInstance = m_prefabSystemComponent->InstantiatePrefab(templateId); + AZStd::unique_ptr secondInstance = m_prefabSystemComponent->InstantiatePrefab( + templateId, AZStd::nullopt, + [](const AzToolsFramework::EntityList& entities) + { + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities); + }); + ASSERT_TRUE(secondInstance); ValidateInstanceEntitiesActive(*secondInstance); From b9787fb2b3141aced65e7d00676b35a6e7ea52de Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Tue, 11 Jan 2022 17:24:33 -0800 Subject: [PATCH 152/272] [Mac] Update to use AWSNativeSDK 1.9.50 (#6797) --- Gems/AWSCore/Code/Platform/Mac/AWSCore_Traits_Mac.h | 2 +- cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/AWSCore/Code/Platform/Mac/AWSCore_Traits_Mac.h b/Gems/AWSCore/Code/Platform/Mac/AWSCore_Traits_Mac.h index d7b1f32461..2cacfb0d34 100644 --- a/Gems/AWSCore/Code/Platform/Mac/AWSCore_Traits_Mac.h +++ b/Gems/AWSCore/Code/Platform/Mac/AWSCore_Traits_Mac.h @@ -7,4 +7,4 @@ */ #pragma once -#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 0 +#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 1 diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index 35a6b87c6c..ea324a5cb7 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -25,7 +25,7 @@ ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-ma ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-mac TARGETS SPIRVCross PACKAGE_HASH 78c6376ed2fd195b9b1f5fb2b56e5267a32c3aa21fb399e905308de470eb4515) ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-mac TARGETS TIFF PACKAGE_HASH c2615ccdadcc0e1d6c5ed61e5965c4d3a82193d206591b79b805c3b3ff35a4bf) ly_associate_package(PACKAGE_NAME freetype-2.10.4.16-mac TARGETS freetype PACKAGE_HASH f159b346ac3251fb29cb8dd5f805c99b0015ed7fdb3887f656945ca701a61d0d) -ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev6-mac TARGETS AWSNativeSDK PACKAGE_HASH 9b058376dec042ace98e198e902b399739adeb9e9398a6c210171fb530164577) +ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.9.50-rev1-mac TARGETS AWSNativeSDK PACKAGE_HASH 6c27a49376870c606144e4639e15867f9db7e4a1ee5f1a726f152d3bd8459966) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev6-mac TARGETS Lua PACKAGE_HASH b9079fd35634774c9269028447562c6b712dbc83b9c64975c095fd423ff04c08) ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev5-mac TARGETS PhysX PACKAGE_HASH 83940b3876115db82cd8ffcb9e902278e75846d6ad94a41e135b155cee1ee186) ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.2-rev1-mac TARGETS mcpp PACKAGE_HASH be9558905c9c49179ef3d7d84f0a5472415acdf7fe2d76eb060d9431723ddf2e) From acec79fe2e3404e31262aa13362eced3eb3ec9b5 Mon Sep 17 00:00:00 2001 From: tjmgd <92784061+tjmgd@users.noreply.github.com> Date: Wed, 12 Jan 2022 11:57:54 +0000 Subject: [PATCH 153/272] Node name change cursor missing (#6721) Signed-off-by: T.J. McGrath-Daly --- .../Editor/PropertyWidgets/AnimGraphNodeNameHandler.cpp | 6 ++++++ .../Editor/PropertyWidgets/AnimGraphNodeNameHandler.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.cpp b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.cpp index 754acdaf1c..854825b45c 100644 --- a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.cpp @@ -38,6 +38,12 @@ namespace EMotionFX m_node = node; } + void AnimGraphNodeNameLineEdit::focusInEvent([[maybe_unused]] QFocusEvent* event) + { + selectAll(); + QLineEdit::focusInEvent(event); + } + //--------------------------------------------------------------------------------------------------------------------------------------------------------- AnimGraphNodeNameHandler::AnimGraphNodeNameHandler() diff --git a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.h b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.h index ad6f0116ca..8da69f7437 100644 --- a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.h +++ b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/AnimGraphNodeNameHandler.h @@ -29,7 +29,8 @@ namespace EMotionFX ~AnimGraphNodeNameLineEdit() = default; void SetNode(AnimGraphNode* node); - + private: + void focusInEvent(QFocusEvent* event) override; private: AnimGraphNode* m_node; }; From f51c845cbb57c1d46c587ecbd318cd3bb9ee9aac Mon Sep 17 00:00:00 2001 From: tjmgd <92784061+tjmgd@users.noreply.github.com> Date: Wed, 12 Jan 2022 13:42:12 +0000 Subject: [PATCH 154/272] Fix: AnimAudioComponentRequestBus canvas script function failure (#6658) Signed-off-by: T.J. McGrath-Daly Co-authored-by: Tobias Alexander Franke --- .../Code/Source/Integration/Components/AnimAudioComponent.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp index eac3705300..7cfea90ae2 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp @@ -405,6 +405,7 @@ namespace EMotionFX ActorNotificationBus::Handler::BusConnect(GetEntityId()); AnimAudioComponentNotificationBus::Handler::BusConnect(GetEntityId()); + AnimAudioComponentRequestBus::Handler::BusConnect(GetEntityId()); } void AnimAudioComponent::Deactivate() @@ -421,6 +422,7 @@ namespace EMotionFX ActorNotificationBus::Handler::BusDisconnect(GetEntityId()); AnimAudioComponentNotificationBus::Handler::BusDisconnect(GetEntityId()); + AnimAudioComponentRequestBus::Handler::BusDisconnect(GetEntityId()); } void AnimAudioComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time) From ffa9cc3a66e7a6df95b18b19d3542370c6eed307 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Wed, 12 Jan 2022 08:46:10 -0600 Subject: [PATCH 155/272] Unit tests and benchmarks for GetValues() (#6823) * Benchmarks and tests for Image and Constant GetValues Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Verify GetValues for Perlin and Random Gradients Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Standardized the assert format for GetValues(). Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * More GetValues unit tests and test cleanup Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed typos Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * GetValues() unit tests for surface gradients. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Benchmarks for ShapeAreaFalloff Gradient Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for all remaining gradients and cleaned up the helper methods. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Renamed class for better report formatting. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added missing Mocks dependencies for the Editor tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- Gems/GradientSignal/Code/CMakeLists.txt | 3 + .../Ebuses/GradientRequestBus.h | 27 +- .../Include/GradientSignal/GradientSampler.h | 4 +- .../Code/Tests/GradientSignalBenchmarks.cpp | 401 +++++++++---- .../Tests/GradientSignalGetValuesTests.cpp | 182 ++++++ .../Code/Tests/GradientSignalImageTests.cpp | 1 - .../Tests/GradientSignalReferencesTests.cpp | 16 +- .../Tests/GradientSignalServicesTests.cpp | 9 +- .../Code/Tests/GradientSignalTestFixtures.cpp | 562 +++++++++++------- .../Code/Tests/GradientSignalTestFixtures.h | 59 +- .../Code/gradientsignal_tests_files.cmake | 1 + .../Source/Shape/ReferenceShapeComponent.cpp | 16 +- .../TerrainHeightGradientListComponent.cpp | 2 +- .../Components/AreaBlenderComponent.cpp | 10 +- 14 files changed, 907 insertions(+), 386 deletions(-) create mode 100644 Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp diff --git a/Gems/GradientSignal/Code/CMakeLists.txt b/Gems/GradientSignal/Code/CMakeLists.txt index 657a88db47..d4cf666630 100644 --- a/Gems/GradientSignal/Code/CMakeLists.txt +++ b/Gems/GradientSignal/Code/CMakeLists.txt @@ -141,6 +141,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTestShared Gem::GradientSignal.Static Gem::LmbrCentral + Gem::LmbrCentral.Mocks Gem::GradientSignal.Mocks ) @@ -160,6 +161,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Gem::GradientSignal.Tests.Static Gem::GradientSignal.Static Gem::LmbrCentral + Gem::LmbrCentral.Mocks Gem::GradientSignal.Mocks ) ly_add_googletest( @@ -190,6 +192,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Gem::GradientSignal.Static Gem::GradientSignal.Editor.Static Gem::LmbrCentral.Editor + Gem::LmbrCentral.Mocks ) ly_add_googletest( NAME Gem::GradientSignal.Editor.Tests diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h index d0fcabf746..3a215c5b5d 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h @@ -62,22 +62,21 @@ namespace GradientSignal // Reference implementation of GetValues for any gradients that don't have their own optimized implementations. // This is 10%-60% faster than calling GetValue via EBus many times due to the per-call EBus overhead. - AZ_Assert( - positions.size() == outValues.size(), "input and output lists are different sizes (%zu vs %zu).", - positions.size(), outValues.size()); - - if (positions.size() == outValues.size()) + if (positions.size() != outValues.size()) { - GradientSampleParams sampleParams; - for (size_t index = 0; index < positions.size(); index++) - { - sampleParams.m_position = positions[index]; + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - outValue = GetValue(sampleParams); - } + GradientSampleParams sampleParams; + for (size_t index = 0; index < positions.size(); index++) + { + sampleParams.m_position = positions[index]; + + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + outValue = GetValue(sampleParams); } } diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h index 454be938a5..a2e1849590 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h @@ -120,7 +120,7 @@ namespace GradientSignal if (m_isRequestInProgress) { - AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependences with gradient entity references"); + AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependencies with gradient entity references"); } else { @@ -197,7 +197,7 @@ namespace GradientSignal if (m_isRequestInProgress) { - AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependences with gradient entity references"); + AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependencies with gradient entity references"); ClearOutputValues(outValues); return; } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp index 6383b627c1..bd4ccf5205 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp @@ -16,162 +16,337 @@ #include #include -#include -#include -#include -#include - namespace UnitTest { - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue)(benchmark::State& state) + class GradientGetValues : public GradientSignalBenchmarkFixture { - CreateTestImageGradient(m_testEntity.get()); - RunEBusGetValueBenchmark(state); - } + public: + // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases + // to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark + // function for each test case for each gradient. + enum GetValuePermutation : int64_t + { + EBUS_GET_VALUE, + EBUS_GET_VALUES, + SAMPLER_GET_VALUE, + SAMPLER_GET_VALUES, + }; - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) + // Create an arbitrary size shape for creating our gradients for benchmark runs. + const float TestShapeHalfBounds = 128.0f; + + void FillQueryPositions(AZStd::vector& positions, float height, float width) + { + size_t index = 0; + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + } + + void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + GradientSignal::GradientSampleParams params; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + + // Call GetValue() on the EBus for every height and width in our ranges. + for (auto _ : state) + { + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + float value = 0.0f; + params.m_position = AZ::Vector3(x, y, 0.0f); + GradientSignal::GradientRequestBus::EventResult( + value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params); + benchmark::DoNotOptimize(value); + } + } + } + } + + void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Get the height and width ranges for querying from our benchmark parameters + float height = aznumeric_cast(queryRange); + float width = aznumeric_cast(queryRange); + int64_t totalQueryPoints = queryRange * queryRange; + + // Call GetValues() for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create + // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. + AZStd::vector positions(totalQueryPoints); + FillQueryPositions(positions, height, width); + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + GradientSignal::GradientRequestBus::Event( + gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); + } + } + + void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Create a gradient sampler to use for querying our gradient. + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientId; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + + // Call GetValue() through the GradientSampler for every height and width in our ranges. + for (auto _ : state) + { + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + GradientSignal::GradientSampleParams params; + params.m_position = AZ::Vector3(x, y, 0.0f); + float value = gradientSampler.GetValue(params); + benchmark::DoNotOptimize(value); + } + } + } + } + + void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Create a gradient sampler to use for querying our gradient. + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientId; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + const int64_t totalQueryPoints = queryRange * queryRange; + + // Call GetValues() through the GradientSampler for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create + // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. + AZStd::vector positions(totalQueryPoints); + FillQueryPositions(positions, height, width); + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + gradientSampler.GetValues(positions, results); + } + } + + void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId) + { + switch (state.range(0)) + { + case GetValuePermutation::EBUS_GET_VALUE: + RunEBusGetValueBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::EBUS_GET_VALUES: + RunEBusGetValuesBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::SAMPLER_GET_VALUE: + RunSamplerGetValueBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::SAMPLER_GET_VALUES: + RunSamplerGetValuesBenchmark(state, gradientId, state.range(1)); + break; + default: + AZ_Assert(false, "Benchmark permutation type not supported."); + } + } + }; + +// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by +// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results. +#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \ + ->ArgNames({ "EbusGetValue", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \ + ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \ + ->ArgNames({ "EbusGetValues", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \ + ->ArgNames({ "SamplerGetValue", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \ + ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \ + ->ArgNames({ "SamplerGetValues", "size" }) \ ->Unit(::benchmark::kMillisecond); - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues)(benchmark::State& state) + // -------------------------------------------------------------------------------------- + // Base Gradients + + BENCHMARK_DEFINE_F(GradientGetValues, BM_ConstantGradient)(benchmark::State& state) { - CreateTestImageGradient(m_testEntity.get()); - RunEBusGetValuesBenchmark(state); + auto entity = BuildTestConstantGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_ImageGradient)(benchmark::State& state) { - CreateTestImageGradient(m_testEntity.get()); - RunSamplerGetValueBenchmark(state); + auto entity = BuildTestImageGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_PerlinGradient)(benchmark::State& state) { - CreateTestImageGradient(m_testEntity.get()); - RunSamplerGetValuesBenchmark(state); + auto entity = BuildTestPerlinGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_RandomGradient)(benchmark::State& state) { - CreateTestPerlinGradient(m_testEntity.get()); - RunEBusGetValueBenchmark(state); + auto entity = BuildTestRandomGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_ShapeAreaFalloffGradient)(benchmark::State& state) { - CreateTestPerlinGradient(m_testEntity.get()); - RunEBusGetValuesBenchmark(state); + auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ConstantGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ImageGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_PerlinGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_RandomGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ShapeAreaFalloffGradient); - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue)(benchmark::State& state) + // -------------------------------------------------------------------------------------- + // Gradient Modifiers + + BENCHMARK_DEFINE_F(GradientGetValues, BM_DitherGradient)(benchmark::State& state) { - CreateTestPerlinGradient(m_testEntity.get()); - RunSamplerGetValueBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_InvertGradient)(benchmark::State& state) { - CreateTestPerlinGradient(m_testEntity.get()); - RunSamplerGetValuesBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_LevelsGradient)(benchmark::State& state) { - CreateTestRandomGradient(m_testEntity.get()); - RunEBusGetValueBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_MixedGradient)(benchmark::State& state) { - CreateTestRandomGradient(m_testEntity.get()); - RunEBusGetValuesBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds); + auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_PosterizeGradient)(benchmark::State& state) { - CreateTestRandomGradient(m_testEntity.get()); - RunSamplerGetValueBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); - - BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues)(benchmark::State& state) + BENCHMARK_DEFINE_F(GradientGetValues, BM_ReferenceGradient)(benchmark::State& state) { - CreateTestRandomGradient(m_testEntity.get()); - RunSamplerGetValuesBenchmark(state); + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } - BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues) - ->Args({ 1024, 1024 }) - ->Args({ 2048, 2048 }) - ->Args({ 4096, 4096 }) - ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(GradientGetValues, BM_SmoothStepGradient)(benchmark::State& state) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + } + + BENCHMARK_DEFINE_F(GradientGetValues, BM_ThresholdGradient)(benchmark::State& state) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId()); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + } + + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_DitherGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_InvertGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_LevelsGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_MixedGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_PosterizeGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ReferenceGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SmoothStepGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ThresholdGradient); + + // -------------------------------------------------------------------------------------- + // Surface Gradients + + BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceAltitudeGradient)(benchmark::State& state) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + } + + BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + } + + BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); + RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + } + + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceAltitudeGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceMaskGradient); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceSlopeGradient); #endif - - - - } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp new file mode 100644 index 0000000000..5504fa5b45 --- /dev/null +++ b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + + +#include +#include + +namespace UnitTest +{ + struct GradientSignalGetValuesTestsFixture + : public GradientSignalTest + { + // Create an arbitrary size shape for comparing values within. It should be large enough that we detect any value anomalies + // but small enough that the tests run quickly. + const float TestShapeHalfBounds = 128.0f; + + void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId) + { + // Create a gradient sampler and run through a series of points to see if they match expectations. + + const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)); + const AZ::Vector2 stepSize(1.0f, 1.0f); + + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientEntityId; + + const size_t numSamplesX = aznumeric_cast(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY())); + + // Build up the list of positions to query. + AZStd::vector positions(numSamplesX * numSamplesY); + size_t index = 0; + for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) + { + float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex); + for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) + { + float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex); + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + + // Get the results from GetValues + AZStd::vector results(numSamplesX * numSamplesY); + gradientSampler.GetValues(positions, results); + + // For each position, call GetValue and verify that the values match. + for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++) + { + GradientSignal::GradientSampleParams params; + params.m_position = positions[positionIndex]; + float value = gradientSampler.GetValue(params); + + // We use ASSERT_EQ instead of EXPECT_EQ because if one value doesn't match, they probably all won't, so there's no reason + // to keep running and printing failures for every value. + ASSERT_EQ(value, results[positionIndex]); + } + } + }; + + TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto entity = BuildTestImageGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto entity = BuildTestPerlinGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto entity = BuildTestRandomGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto entity = BuildTestConstantGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + + auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds); + auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); + auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId()); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } + + TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch) + { + auto mockSurfaceDataSystem = + CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); + + auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); + CompareGetValueAndGetValues(entity->GetId()); + } +} + + diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp index e99bf1de5b..5cd3c7edf6 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp @@ -417,7 +417,6 @@ namespace UnitTest TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); } } - } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp index 32cd483c81..cc91c58fce 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp @@ -371,12 +371,9 @@ namespace UnitTest const AZ::EntityId id = mockReference->GetId(); MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); - GradientSignal::ReferenceGradientConfig config; - config.m_gradientSampler.m_gradientId = mockReference->GetId(); - - auto entity = CreateEntity(); - CreateComponent(entity.get(), config); - ActivateEntity(entity.get()); + // Create a reference gradient with an arbitrary box shape on it. + const float HalfBounds = 64.0f; + auto entity = BuildTestReferenceGradient(HalfBounds, mockReference->GetId()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); } @@ -385,10 +382,9 @@ namespace UnitTest { // Verify that gradient references can validate and disconnect cyclic connections - auto constantGradientEntity = CreateEntity(); - GradientSignal::ConstantGradientConfig constantGradientConfig; - CreateComponent(constantGradientEntity.get(), constantGradientConfig); - ActivateEntity(constantGradientEntity.get()); + // Create a constant gradient with an arbitrary box shape on it. + const float HalfBounds = 64.0f; + auto constantGradientEntity = BuildTestConstantGradient(HalfBounds); // Verify cyclic reference test passes when pointing to gradient generator entity auto referenceGradientEntity1 = CreateEntity(); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp index dd81c14a09..ec770f038d 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp @@ -212,12 +212,9 @@ namespace UnitTest const AZ::EntityId id = entityMock->GetId(); UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); - GradientSignal::InvertGradientConfig config; - config.m_gradientSampler.m_gradientId = entityMock->GetId(); - - auto entity = CreateEntity(); - CreateComponent(entity.get(), config); - ActivateEntity(entity.get()); + // Create the entity with an arbitrarily-sized box. + const float HalfBounds = 64.0f; + auto entity = BuildTestInvertGradient(HalfBounds, entityMock->GetId()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp index 77568d3321..154e9032b2 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp @@ -9,10 +9,30 @@ #include +#include #include + +// Base gradient components +#include #include #include #include +#include + +// Gradient modifier components +#include +#include +#include +#include +#include +#include +#include +#include + +// Gradient surface data components +#include +#include +#include namespace UnitTest { @@ -32,12 +52,18 @@ namespace UnitTest AZ::Data::AssetManager::Create(desc); m_mockHandler = new ImageAssetMockAssetHandler(); AZ::Data::AssetManager::Instance().RegisterHandler(m_mockHandler, azrtti_typeid()); + + m_mockShapeHandlers = new AZStd::vector>>(); } void GradientSignalBaseFixture::TearDownCoreSystems() { + // Clear any mock shape handlers that we've created for our test entities. + delete m_mockShapeHandlers; + AZ::Data::AssetManager::Instance().UnregisterHandler(m_mockHandler); delete m_mockHandler; // delete after removing from the asset manager + AzFramework::LegacyAssetEventBus::ClearQueuedEvents(); AZ::Data::AssetManager::Destroy(); AZ::AllocatorInstance::Destroy(); @@ -47,6 +73,338 @@ namespace UnitTest m_systemEntity = nullptr; } + AZStd::unique_ptr> GradientSignalBaseFixture::CreateMockShape( + const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId) + { + AZStd::unique_ptr> mockShape = + AZStd::make_unique>(shapeEntityId); + + ON_CALL(*mockShape, GetEncompassingAabb).WillByDefault(testing::Return(spawnerBox)); + ON_CALL(*mockShape, GetTransformAndLocalBounds) + .WillByDefault( + [spawnerBox](AZ::Transform& transform, AZ::Aabb& bounds) + { + transform = AZ::Transform::CreateTranslation(spawnerBox.GetCenter()); + bounds = spawnerBox.GetTranslated(-spawnerBox.GetCenter()); + }); + ON_CALL(*mockShape, IsPointInside) + .WillByDefault( + [spawnerBox](const AZ::Vector3& point) -> bool + { + return spawnerBox.Contains(point); + }); + + return mockShape; + } + + AZStd::unique_ptr GradientSignalBaseFixture::CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox) + { + SurfaceData::SurfacePoint point; + AZStd::unique_ptr mockSurfaceDataSystem = AZStd::make_unique(); + + // Give the mock surface data a bunch of fake point values to return. + for (float y = spawnerBox.GetMin().GetY(); y < spawnerBox.GetMax().GetY(); y+= 1.0f) + { + for (float x = spawnerBox.GetMin().GetX(); x < spawnerBox.GetMax().GetX(); x += 1.0f) + { + // Use our x distance into the spawnerBox as an arbitrary percentage value that we'll use to calculate + // our other arbitrary values below. + float arbitraryPercentage = AZStd::abs(x / spawnerBox.GetExtents().GetX()); + + // Create a position that's between min and max Z of the box. + point.m_position = AZ::Vector3(x, y, AZ::Lerp(spawnerBox.GetMin().GetZ(), spawnerBox.GetMax().GetZ(), arbitraryPercentage)); + // Create an arbitrary normal value. + point.m_normal = point.m_position.GetNormalized(); + // Create an arbitrary surface value. + point.m_masks[AZ_CRC_CE("test_mask")] = arbitraryPercentage; + + mockSurfaceDataSystem->m_GetSurfacePoints[AZStd::make_pair(x, y)] = { { point } }; + } + } + + return mockSurfaceDataSystem; + } + + AZStd::unique_ptr GradientSignalBaseFixture::CreateTestEntity(float shapeHalfBounds) + { + // Create the base entity + AZStd::unique_ptr testEntity = CreateEntity(); + + // Create a mock Shape component that describes the bounds that we're using to map our gradient into world space. + CreateComponent(testEntity.get()); + + // Create and keep a reference to a mock shape handler that will respond to shape requests for the mock shape. + auto mockShapeHandler = + CreateMockShape(AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds), testEntity->GetId()); + m_mockShapeHandlers->push_back(AZStd::move(mockShapeHandler)); + + // Create a transform that locates our gradient in the center of our desired mock Shape. + auto transform = CreateComponent(testEntity.get()); + transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); + transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); + + return testEntity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestConstantGradient(float shapeHalfBounds) + { + // Create a Constant Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::ConstantGradientConfig config; + config.m_value = 0.75f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestImageGradient(float shapeHalfBounds) + { + // Create an Image Gradient Component with arbitrary sizes and parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::ImageGradientConfig config; + const uint32_t imageSize = 4096; + const int32_t imageSeed = 12345; + config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed); + config.m_tilingX = 1.0f; + config.m_tilingY = 1.0f; + CreateComponent(entity.get(), config); + + // Create a Gradient Transform Component with arbitrary parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity.get(), gradientTransformConfig); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestPerlinGradient(float shapeHalfBounds) + { + // Create a Perlin Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::PerlinGradientConfig config; + config.m_amplitude = 1.0f; + config.m_frequency = 1.1f; + config.m_octave = 4; + config.m_randomSeed = 12345; + CreateComponent(entity.get(), config); + + // Create a Gradient Transform Component with arbitrary parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity.get(), gradientTransformConfig); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestRandomGradient(float shapeHalfBounds) + { + // Create a Random Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::RandomGradientConfig config; + config.m_randomSeed = 12345; + CreateComponent(entity.get(), config); + + // Create a Gradient Transform Component with arbitrary parameters. + GradientSignal::GradientTransformConfig gradientTransformConfig; + gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; + CreateComponent(entity.get(), gradientTransformConfig); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestShapeAreaFalloffGradient(float shapeHalfBounds) + { + // Create a Shape Area Falloff Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::ShapeAreaFalloffGradientConfig config; + config.m_shapeEntityId = entity->GetId(); + config.m_falloffWidth = 16.0f; + config.m_falloffType = GradientSignal::FalloffType::InnerOuter; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestDitherGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Dither Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::DitherGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_useSystemPointsPerUnit = false; + config.m_pointsPerUnit = 1.0f; + config.m_patternOffset = AZ::Vector3::CreateZero(); + config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestInvertGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create an Invert Gradient Component. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::InvertGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestLevelsGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Levels Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::LevelsGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_inputMin = 0.1f; + config.m_inputMid = 0.3f; + config.m_inputMax = 0.9f; + config.m_outputMin = 0.0f; + config.m_outputMax = 1.0f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestMixedGradient( + float shapeHalfBounds, const AZ::EntityId& baseGradientId, const AZ::EntityId& mixedGradientId) + { + // Create a Mixed Gradient Component that mixes two input gradients together in arbitrary ways. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::MixedGradientConfig config; + + GradientSignal::MixedGradientLayer layer; + layer.m_enabled = true; + + layer.m_operation = GradientSignal::MixedGradientLayer::MixingOperation::Initialize; + layer.m_gradientSampler.m_gradientId = baseGradientId; + layer.m_gradientSampler.m_opacity = 1.0f; + config.m_layers.push_back(layer); + + layer.m_operation = GradientSignal::MixedGradientLayer::MixingOperation::Overlay; + layer.m_gradientSampler.m_gradientId = mixedGradientId; + layer.m_gradientSampler.m_opacity = 0.75f; + config.m_layers.push_back(layer); + + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestPosterizeGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Posterize Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::PosterizeGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_mode = GradientSignal::PosterizeGradientConfig::ModeType::Ps; + config.m_bands = 5; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestReferenceGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Reference Gradient Component. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::ReferenceGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_gradientSampler.m_ownerEntityId = entity->GetId(); + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSmoothStepGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Smooth Step Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::SmoothStepGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_smoothStep.m_falloffMidpoint = 0.75f; + config.m_smoothStep.m_falloffRange = 0.125f; + config.m_smoothStep.m_falloffStrength = 0.25f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestThresholdGradient( + float shapeHalfBounds, const AZ::EntityId& inputGradientId) + { + // Create a Threshold Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::ThresholdGradientConfig config; + config.m_gradientSampler.m_gradientId = inputGradientId; + config.m_threshold = 0.75f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceAltitudeGradient(float shapeHalfBounds) + { + // Create a Surface Altitude Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::SurfaceAltitudeGradientConfig config; + config.m_altitudeMin = -5.0f; + config.m_altitudeMax = 15.0f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceMaskGradient(float shapeHalfBounds) + { + // Create a Surface Mask Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::SurfaceMaskGradientConfig config; + config.m_surfaceTagList.push_back(AZ_CRC_CE("test_mask")); + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + + AZStd::unique_ptr GradientSignalBaseFixture::BuildTestSurfaceSlopeGradient(float shapeHalfBounds) + { + // Create a Surface Slope Gradient Component with arbitrary parameters. + auto entity = CreateTestEntity(shapeHalfBounds); + GradientSignal::SurfaceSlopeGradientConfig config; + config.m_slopeMin = 5.0f; + config.m_slopeMax = 50.0f; + config.m_rampType = GradientSignal::SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP; + config.m_smoothStep.m_falloffMidpoint = 0.75f; + config.m_smoothStep.m_falloffRange = 0.125f; + config.m_smoothStep.m_falloffStrength = 0.25f; + CreateComponent(entity.get(), config); + + ActivateEntity(entity.get()); + return entity; + } + void GradientSignalTest::TestFixedDataSampler(const AZStd::vector& expectedOutput, int size, AZ::EntityId gradientEntityId) { GradientSignal::GradientSampler gradientSampler; @@ -67,209 +425,5 @@ namespace UnitTest } } } - -#ifdef HAVE_BENCHMARK - void GradientSignalBenchmarkFixture::CreateTestEntity(float shapeHalfBounds) - { - // Create the base entity - m_testEntity = CreateEntity(); - - // Create a mock Shape component that describes the bounds that we're using to map our gradient into world space. - CreateComponent(m_testEntity.get()); - MockShapeComponentHandler mockShapeHandler(m_testEntity->GetId()); - mockShapeHandler.m_GetLocalBounds = AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds); - - // Create a mock Transform component that locates our gradient in the center of our desired mock Shape. - MockTransformHandler mockTransformHandler; - mockTransformHandler.m_GetLocalTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)); - mockTransformHandler.m_GetWorldTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)); - mockTransformHandler.BusConnect(m_testEntity->GetId()); - } - - void GradientSignalBenchmarkFixture::DestroyTestEntity() - { - m_testEntity.reset(); - } - - void GradientSignalBenchmarkFixture::CreateTestImageGradient(AZ::Entity* entity) - { - // Create the Image Gradient Component with some default sizes and parameters. - GradientSignal::ImageGradientConfig config; - const uint32_t imageSize = 4096; - const int32_t imageSeed = 12345; - config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed); - config.m_tilingX = 1.0f; - config.m_tilingY = 1.0f; - CreateComponent(entity, config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity, gradientTransformConfig); - } - - void GradientSignalBenchmarkFixture::CreateTestPerlinGradient(AZ::Entity* entity) - { - // Create the Perlin Gradient Component with some default sizes and parameters. - GradientSignal::PerlinGradientConfig config; - config.m_amplitude = 1.0f; - config.m_frequency = 1.1f; - config.m_octave = 4; - config.m_randomSeed = 12345; - CreateComponent(entity, config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity, gradientTransformConfig); - } - - void GradientSignalBenchmarkFixture::CreateTestRandomGradient(AZ::Entity* entity) - { - // Create the Random Gradient Component with some default parameters. - GradientSignal::RandomGradientConfig config; - config.m_randomSeed = 12345; - CreateComponent(entity, config); - - // Create the Gradient Transform Component with some default parameters. - GradientSignal::GradientTransformConfig gradientTransformConfig; - gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity, gradientTransformConfig); - } - - void GradientSignalBenchmarkFixture::RunSamplerGetValueBenchmark(benchmark::State& state) - { - AZ_PROFILE_FUNCTION(Entity); - - // All components are created, so activate the entity - ActivateEntity(m_testEntity.get()); - - // Create a gradient sampler and run through a series of points to see if they match expectations. - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = m_testEntity->GetId(); - - // Get the height and width ranges for querying from our benchmark parameters - float height = aznumeric_cast(state.range(0)); - float width = aznumeric_cast(state.range(1)); - - // Call GetValue() for every height and width in our ranges. - for (auto _ : state) - { - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - GradientSignal::GradientSampleParams params; - params.m_position = AZ::Vector3(x, y, 0.0f); - float value = gradientSampler.GetValue(params); - benchmark::DoNotOptimize(value); - } - } - } - } - - void GradientSignalBenchmarkFixture::RunSamplerGetValuesBenchmark(benchmark::State& state) - { - AZ_PROFILE_FUNCTION(Entity); - - // All components are created, so activate the entity - ActivateEntity(m_testEntity.get()); - - // Create a gradient sampler and run through a series of points to see if they match expectations. - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = m_testEntity->GetId(); - - // Get the height and width ranges for querying from our benchmark parameters - float height = aznumeric_cast(state.range(0)); - float width = aznumeric_cast(state.range(1)); - int64_t totalQueryPoints = state.range(0) * state.range(1); - - // Call GetValues() for every height and width in our ranges. - for (auto _ : state) - { - // Set up our vector of query positions. - AZStd::vector positions(totalQueryPoints); - size_t index = 0; - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - positions[index++] = AZ::Vector3(x, y, 0.0f); - } - } - - // Query and get the results. - AZStd::vector results(totalQueryPoints); - gradientSampler.GetValues(positions, results); - } - } - - void GradientSignalBenchmarkFixture::RunEBusGetValueBenchmark(benchmark::State& state) - { - AZ_PROFILE_FUNCTION(Entity); - - // All components are created, so activate the entity - ActivateEntity(m_testEntity.get()); - - GradientSignal::GradientSampleParams params; - - // Get the height and width ranges for querying from our benchmark parameters - float height = aznumeric_cast(state.range(0)); - float width = aznumeric_cast(state.range(1)); - - // Call GetValue() for every height and width in our ranges. - for (auto _ : state) - { - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - float value = 0.0f; - params.m_position = AZ::Vector3(x, y, 0.0f); - GradientSignal::GradientRequestBus::EventResult( - value, m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params); - benchmark::DoNotOptimize(value); - } - } - } - } - - void GradientSignalBenchmarkFixture::RunEBusGetValuesBenchmark(benchmark::State& state) - { - AZ_PROFILE_FUNCTION(Entity); - - // All components are created, so activate the entity - ActivateEntity(m_testEntity.get()); - - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = m_testEntity->GetId(); - - // Get the height and width ranges for querying from our benchmark parameters - float height = aznumeric_cast(state.range(0)); - float width = aznumeric_cast(state.range(1)); - int64_t totalQueryPoints = state.range(0) * state.range(1); - - // Call GetValues() for every height and width in our ranges. - for (auto _ : state) - { - // Set up our vector of query positions. - AZStd::vector positions(totalQueryPoints); - size_t index = 0; - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - positions[index++] = AZ::Vector3(x, y, 0.0f); - } - } - - // Query and get the results. - AZStd::vector results(totalQueryPoints); - GradientSignal::GradientRequestBus::Event( - m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); - } - } -#endif - } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h index 13ff69c82d..478f1c1d92 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h @@ -8,6 +8,7 @@ #pragma once #include +#include namespace UnitTest { @@ -30,22 +31,56 @@ namespace UnitTest } template - AZ::Component* CreateComponent(AZ::Entity* entity, const Configuration& config) + Component* CreateComponent(AZ::Entity* entity, const Configuration& config) { m_app->RegisterComponentDescriptor(Component::CreateDescriptor()); return entity->CreateComponent(config); } template - AZ::Component* CreateComponent(AZ::Entity* entity) + Component* CreateComponent(AZ::Entity* entity) { m_app->RegisterComponentDescriptor(Component::CreateDescriptor()); return entity->CreateComponent(); } + // Create a mock shape that will respond to the shape bus with proper responses for the given input box. + AZStd::unique_ptr> CreateMockShape( + const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId); + + // Create a mock SurfaceDataSystem that will respond to requests for surface points with mock responses for points inside + // the given input box. + AZStd::unique_ptr CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox); + + // Create an entity with a mock shape and a transform. It won't be activated yet though, because we expect a gradient component + // to also get added to it first before activation. + AZStd::unique_ptr CreateTestEntity(float shapeHalfBounds); + + // Create and activate an entity with a gradient component of the requested type, initialized with test data. + AZStd::unique_ptr BuildTestConstantGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestImageGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestPerlinGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestRandomGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestShapeAreaFalloffGradient(float shapeHalfBounds); + + AZStd::unique_ptr BuildTestDitherGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestInvertGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestLevelsGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestMixedGradient( + float shapeHalfBounds, const AZ::EntityId& baseGradientId, const AZ::EntityId& mixedGradientId); + AZStd::unique_ptr BuildTestPosterizeGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestReferenceGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestSmoothStepGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + AZStd::unique_ptr BuildTestThresholdGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId); + + AZStd::unique_ptr BuildTestSurfaceAltitudeGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestSurfaceMaskGradient(float shapeHalfBounds); + AZStd::unique_ptr BuildTestSurfaceSlopeGradient(float shapeHalfBounds); + AZStd::unique_ptr m_app; AZ::Entity* m_systemEntity = nullptr; ImageAssetMockAssetHandler* m_mockHandler = nullptr; + AZStd::vector>>* m_mockShapeHandlers = nullptr; }; struct GradientSignalTest @@ -80,33 +115,15 @@ namespace UnitTest AZ::Debug::TraceMessageBus::Handler::BusConnect(); UnitTest::AllocatorsBenchmarkFixture::SetUp(state); SetupCoreSystems(); - - // Create a default test entity with bounds of 256 m x 256 m x 256 m. - const float shapeHalfBounds = 128.0f; - CreateTestEntity(shapeHalfBounds); } void internalTearDown(const benchmark::State& state) { - DestroyTestEntity(); TearDownCoreSystems(); UnitTest::AllocatorsBenchmarkFixture::TearDown(state); AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); } - void CreateTestEntity(float shapeHalfBounds); - void DestroyTestEntity(); - - void CreateTestImageGradient(AZ::Entity* entity); - void CreateTestPerlinGradient(AZ::Entity* entity); - void CreateTestRandomGradient(AZ::Entity* entity); - - void RunSamplerGetValueBenchmark(benchmark::State& state); - void RunSamplerGetValuesBenchmark(benchmark::State& state); - - void RunEBusGetValueBenchmark(benchmark::State& state); - void RunEBusGetValuesBenchmark(benchmark::State& state); - protected: void SetUp(const benchmark::State& state) override { @@ -125,8 +142,6 @@ namespace UnitTest { internalTearDown(state); } - - AZStd::unique_ptr m_testEntity; }; #endif } diff --git a/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake index eb799811b7..814347c395 100644 --- a/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake +++ b/Gems/GradientSignal/Code/gradientsignal_tests_files.cmake @@ -8,6 +8,7 @@ set(FILES Tests/GradientSignalBenchmarks.cpp + Tests/GradientSignalGetValuesTests.cpp Tests/GradientSignalImageTests.cpp Tests/GradientSignalReferencesTests.cpp Tests/GradientSignalServicesTests.cpp diff --git a/Gems/LmbrCentral/Code/Source/Shape/ReferenceShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/ReferenceShapeComponent.cpp index 7ed79fe3a3..1fc4bb5107 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/ReferenceShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/ReferenceShapeComponent.cpp @@ -190,7 +190,7 @@ namespace LmbrCentral { AZ::Crc32 result = {}; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -205,7 +205,7 @@ namespace LmbrCentral { AZ::Aabb result = AZ::Aabb::CreateNull(); - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -221,7 +221,7 @@ namespace LmbrCentral transform = AZ::Transform::CreateIdentity(); bounds = AZ::Aabb::CreateNull(); - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -234,7 +234,7 @@ namespace LmbrCentral { bool result = false; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -249,7 +249,7 @@ namespace LmbrCentral { float result = FLT_MAX; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -264,7 +264,7 @@ namespace LmbrCentral { float result = FLT_MAX; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -279,7 +279,7 @@ namespace LmbrCentral { AZ::Vector3 result = AZ::Vector3::CreateZero(); - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; @@ -294,7 +294,7 @@ namespace LmbrCentral { bool result = false; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references"); if (AllowRequest()) { m_isRequestInProgress = true; diff --git a/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp index 108ae70632..b9055375d4 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp @@ -160,7 +160,7 @@ namespace Terrain { float maxSample = 0.0f; terrainExists = false; - AZ_WarningOnce("Terrain", !m_isRequestInProgress, "Detected cyclic dependences with terrain height entity references"); + AZ_WarningOnce("Terrain", !m_isRequestInProgress, "Detected cyclic dependencies with terrain height entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; diff --git a/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp b/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp index 8bf48de58e..2025ed059f 100644 --- a/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp @@ -224,7 +224,7 @@ namespace Vegetation bool result = true; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; @@ -264,7 +264,7 @@ namespace Vegetation return; } - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; @@ -295,7 +295,7 @@ namespace Vegetation { AZ_PROFILE_FUNCTION(Entity); - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; @@ -320,7 +320,7 @@ namespace Vegetation LmbrCentral::ShapeComponentRequestsBus::EventResult(bounds, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb); } - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; @@ -344,7 +344,7 @@ namespace Vegetation AZ::u32 count = 0; - AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references"); + AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references"); if (!m_isRequestInProgress) { m_isRequestInProgress = true; From a690c76ad4716233f726f60277f72636eebaf295 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Wed, 12 Jan 2022 08:54:22 -0800 Subject: [PATCH 156/272] Fixed depth clipping artifacts for parallax PDO. (#6837) The "precise" keyword was recently added to several shader inputs, but one was missed. This led to inconsistency between the depth and forward passes which resulted in artifacts when parallax pixel depth offset was in use. See https://github.com/o3de/o3de/pull/6536 Testing: I used AtomSampleViewer to make a local baseline of all screenshots in _fulltestsuite_.bv.lua. The only change was to the parallax test cases, which were a clear improvement. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl index 264542cd0a..04fd104407 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_DepthPass_WithPS.azsl @@ -63,7 +63,7 @@ VSDepthOutput MainVS(VSInput IN) struct PSDepthOutput { - float m_depth : SV_Depth; + precise float m_depth : SV_Depth; }; PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) From e31fa88c0093219fd3db6bda1918f88d572ebd46 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Wed, 12 Jan 2022 11:13:40 -0600 Subject: [PATCH 157/272] Removed unused legacy show icons option Signed-off-by: Chris Galvan --- .../EditorPreferencesPageViewportGeneral.cpp | 10 -- .../EditorPreferencesPageViewportGeneral.h | 2 - Code/Editor/EditorViewportWidget.cpp | 2 - Code/Editor/Objects/BaseObject.cpp | 151 ------------------ Code/Editor/Objects/BaseObject.h | 10 -- .../Objects/ComponentEntityObject.cpp | 91 ----------- .../Objects/ComponentEntityObject.h | 2 - Code/Editor/Settings.cpp | 7 - Code/Editor/Settings.h | 7 - 9 files changed, 282 deletions(-) diff --git a/Code/Editor/EditorPreferencesPageViewportGeneral.cpp b/Code/Editor/EditorPreferencesPageViewportGeneral.cpp index 77560e24f8..f33cc3f725 100644 --- a/Code/Editor/EditorPreferencesPageViewportGeneral.cpp +++ b/Code/Editor/EditorPreferencesPageViewportGeneral.cpp @@ -41,8 +41,6 @@ void CEditorPreferencesPage_ViewportGeneral::Reflect(AZ::SerializeContext& seria ->Field("ShowBBoxes", &Display::m_showBBoxes) ->Field("DrawEntityLabels", &Display::m_drawEntityLabels) ->Field("ShowTriggerBounds", &Display::m_showTriggerBounds) - ->Field("ShowIcons", &Display::m_showIcons) - ->Field("DistanceScaleIcons", &Display::m_distanceScaleIcons) ->Field("ShowFrozenHelpers", &Display::m_showFrozenHelpers) ->Field("FillSelectedShapes", &Display::m_fillSelectedShapes) ->Field("ShowGridGuide", &Display::m_showGridGuide) @@ -118,10 +116,6 @@ void CEditorPreferencesPage_ViewportGeneral::Reflect(AZ::SerializeContext& seria AZ::Edit::UIHandlers::CheckBox, &Display::m_drawEntityLabels, "Always Draw Entity Labels", "Always Draw Entity Labels") ->DataElement( AZ::Edit::UIHandlers::CheckBox, &Display::m_showTriggerBounds, "Always Show Trigger Bounds", "Always Show Trigger Bounds") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &Display::m_showIcons, "Show Object Icons", "Show Object Icons") - ->DataElement( - AZ::Edit::UIHandlers::CheckBox, &Display::m_distanceScaleIcons, "Scale Object Icons with Distance", - "Scale Object Icons with Distance") ->DataElement( AZ::Edit::UIHandlers::CheckBox, &Display::m_showFrozenHelpers, "Show Helpers of Frozen Objects", "Show Helpers of Frozen Objects") @@ -244,8 +238,6 @@ void CEditorPreferencesPage_ViewportGeneral::OnApply() } gSettings.viewports.bDrawEntityLabels = m_display.m_drawEntityLabels; gSettings.viewports.bShowTriggerBounds = m_display.m_showTriggerBounds; - gSettings.viewports.bShowIcons = m_display.m_showIcons; - gSettings.viewports.bDistanceScaleIcons = m_display.m_distanceScaleIcons; gSettings.viewports.nShowFrozenHelpers = m_display.m_showFrozenHelpers; gSettings.viewports.bFillSelectedShapes = m_display.m_fillSelectedShapes; gSettings.viewports.bShowGridGuide = m_display.m_showGridGuide; @@ -300,8 +292,6 @@ void CEditorPreferencesPage_ViewportGeneral::InitializeSettings() m_display.m_showBBoxes = (ds->GetRenderFlags() & RENDER_FLAG_BBOX) == RENDER_FLAG_BBOX; m_display.m_drawEntityLabels = gSettings.viewports.bDrawEntityLabels; m_display.m_showTriggerBounds = gSettings.viewports.bShowTriggerBounds; - m_display.m_showIcons = gSettings.viewports.bShowIcons; - m_display.m_distanceScaleIcons = gSettings.viewports.bDistanceScaleIcons; m_display.m_showFrozenHelpers = gSettings.viewports.nShowFrozenHelpers; m_display.m_fillSelectedShapes = gSettings.viewports.bFillSelectedShapes; m_display.m_showGridGuide = gSettings.viewports.bShowGridGuide; diff --git a/Code/Editor/EditorPreferencesPageViewportGeneral.h b/Code/Editor/EditorPreferencesPageViewportGeneral.h index be89cc6df4..2d2a207d6c 100644 --- a/Code/Editor/EditorPreferencesPageViewportGeneral.h +++ b/Code/Editor/EditorPreferencesPageViewportGeneral.h @@ -62,8 +62,6 @@ private: bool m_showBBoxes; bool m_drawEntityLabels; bool m_showTriggerBounds; - bool m_showIcons; - bool m_distanceScaleIcons; bool m_showFrozenHelpers; bool m_fillSelectedShapes; bool m_showGridGuide; diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 828812fb7e..e9a57dba4f 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -1027,8 +1027,6 @@ void EditorViewportWidget::OnTitleMenu(QMenu* menu) AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Safe Frame"), &gSettings.viewports.bShowSafeFrame); AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Construction Plane"), &gSettings.snap.constructPlaneDisplay); AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Trigger Bounds"), &gSettings.viewports.bShowTriggerBounds); - AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Icons"), &gSettings.viewports.bShowIcons, &gSettings.viewports.bShowSizeBasedIcons); - AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Size-based Icons"), &gSettings.viewports.bShowSizeBasedIcons, &gSettings.viewports.bShowIcons); AZ::ViewportHelpers::AddCheckbox(menu, tr("Show Helpers of Frozen Objects"), &gSettings.viewports.nShowFrozenHelpers); if (!m_predefinedAspectRatios.IsEmpty()) diff --git a/Code/Editor/Objects/BaseObject.cpp b/Code/Editor/Objects/BaseObject.cpp index 86840789dd..5ae68eaad7 100644 --- a/Code/Editor/Objects/BaseObject.cpp +++ b/Code/Editor/Objects/BaseObject.cpp @@ -761,72 +761,6 @@ void CBaseObject::SetModified(bool) { } -void CBaseObject::DrawDefault(DisplayContext& dc, const QColor& labelColor) -{ - Vec3 wp = GetWorldPos(); - - bool bDisplaySelectionHelper = false; - if (!CanBeDrawn(dc, bDisplaySelectionHelper)) - { - return; - } - - // Draw link between parent and child. - if (dc.flags & DISPLAY_LINKS) - { - if (GetParent()) - { - dc.DrawLine(GetParentAttachPointWorldTM().GetTranslation(), wp, IsFrozen() ? kLinkColorGray : kLinkColorParent, IsFrozen() ? kLinkColorGray : kLinkColorChild); - } - size_t nChildCount = GetChildCount(); - for (size_t i = 0; i < nChildCount; ++i) - { - const CBaseObject* pChild = GetChild(i); - dc.DrawLine(pChild->GetParentAttachPointWorldTM().GetTranslation(), pChild->GetWorldPos(), pChild->IsFrozen() ? kLinkColorGray : kLinkColorParent, pChild->IsFrozen() ? kLinkColorGray : kLinkColorChild); - } - } - - // Draw Bounding box - if (dc.flags & DISPLAY_BBOX) - { - AABB box; - GetBoundBox(box); - dc.SetColor(Vec3(1, 1, 1)); - dc.DrawWireBox(box.min, box.max); - } - - if (IsHighlighted()) - { - DrawHighlight(dc); - } - - if (IsSelected()) - { - DrawArea(dc); - - CSelectionGroup* pSelection = GetObjectManager()->GetSelection(); - - // If the number of selected object is over 2, the merged boundbox should be used to render the measurement axis. - if (!pSelection || (pSelection && pSelection->GetCount() == 1)) - { - DrawDimensions(dc); - } - } - - if (bDisplaySelectionHelper) - { - DrawSelectionHelper(dc, wp, labelColor, 1.0f); - } - else if (!(dc.flags & DISPLAY_HIDENAMES)) - { - DrawLabel(dc, wp, labelColor); - } - - SetDrawTextureIconProperties(dc, wp); - DrawTextureIcon(dc, wp); - DrawWarningIcons(dc, wp); -} - ////////////////////////////////////////////////////////////////////////// void CBaseObject::DrawDimensions(DisplayContext&, AABB*) { @@ -850,91 +784,6 @@ void CBaseObject::DrawSelectionHelper(DisplayContext& dc, const Vec3& pos, const dc.SetState(nPrevState); } -////////////////////////////////////////////////////////////////////////// -void CBaseObject::SetDrawTextureIconProperties(DisplayContext& dc, const Vec3& pos, float alpha, int texIconFlags) -{ - if (gSettings.viewports.bShowIcons || gSettings.viewports.bShowSizeBasedIcons) - { - if (IsHighlighted()) - { - dc.SetColor(QColor(255, 120, 0), 0.8f * alpha); - } - else if (IsSelected()) - { - dc.SetSelectedColor(alpha); - } - else if (IsFrozen()) - { - dc.SetFreezeColor(); - } - else - { - dc.SetColor(QColor(255, 255, 255), alpha); - } - - m_vDrawIconPos = pos; - - int nIconFlags = texIconFlags; - if (CheckFlags(OBJFLAG_SHOW_ICONONTOP)) - { - Vec3 objectPos = GetWorldPos(); - - AABB box; - GetBoundBox(box); - m_vDrawIconPos.z = (m_vDrawIconPos.z - objectPos.z) + box.max.z; - nIconFlags |= DisplayContext::TEXICON_ALIGN_BOTTOM; - } - m_nIconFlags = nIconFlags; - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseObject::DrawTextureIcon(DisplayContext& dc, [[maybe_unused]] const Vec3& pos, [[maybe_unused]] float alpha) -{ - if (m_nTextureIcon && (gSettings.viewports.bShowIcons || gSettings.viewports.bShowSizeBasedIcons)) - { - dc.DrawTextureLabel(GetTextureIconDrawPos(), OBJECT_TEXTURE_ICON_SIZEX, OBJECT_TEXTURE_ICON_SIZEY, GetTextureIcon(), GetTextureIconFlags()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CBaseObject::DrawWarningIcons(DisplayContext& dc, const Vec3&) -{ - if (gSettings.viewports.bShowIcons || gSettings.viewports.bShowSizeBasedIcons) - { - const int warningIconSizeX = OBJECT_TEXTURE_ICON_SIZEX / 2; - const int warningIconSizeY = OBJECT_TEXTURE_ICON_SIZEY / 2; - - const int iconOffsetX = m_nTextureIcon ? (-OBJECT_TEXTURE_ICON_SIZEX / 2) : 0; - const int iconOffsetY = m_nTextureIcon ? (-OBJECT_TEXTURE_ICON_SIZEY / 2) : 0; - - if (gSettings.viewports.bShowScaleWarnings) - { - const EScaleWarningLevel scaleWarningLevel = GetScaleWarningLevel(); - - if (scaleWarningLevel != eScaleWarningLevel_None) - { - dc.SetColor(QColor(255, scaleWarningLevel == eScaleWarningLevel_RescaledNonUniform ? 50 : 255, 50), 1.0f); - dc.DrawTextureLabel(GetTextureIconDrawPos(), warningIconSizeX, warningIconSizeY, - GetIEditor()->GetIconManager()->GetIconTexture(eIcon_ScaleWarning), GetTextureIconFlags(), - -warningIconSizeX / 2, iconOffsetX - (warningIconSizeY / 2)); - } - } - - if (gSettings.viewports.bShowRotationWarnings) - { - const ERotationWarningLevel rotationWarningLevel = GetRotationWarningLevel(); - if (rotationWarningLevel != eRotationWarningLevel_None) - { - dc.SetColor(QColor(255, rotationWarningLevel == eRotationWarningLevel_RotatedNonRectangular ? 50 : 255, 50), 1.0f); - dc.DrawTextureLabel(GetTextureIconDrawPos(), warningIconSizeX, warningIconSizeY, - GetIEditor()->GetIconManager()->GetIconTexture(eIcon_RotationWarning), GetTextureIconFlags(), - warningIconSizeX / 2, iconOffsetY - (warningIconSizeY / 2)); - } - } - } -} - ////////////////////////////////////////////////////////////////////////// void CBaseObject::DrawLabel(DisplayContext& dc, const Vec3& pos, const QColor& lC, float alpha, float size) { diff --git a/Code/Editor/Objects/BaseObject.h b/Code/Editor/Objects/BaseObject.h index f78755e81d..fea248c7f7 100644 --- a/Code/Editor/Objects/BaseObject.h +++ b/Code/Editor/Objects/BaseObject.h @@ -398,9 +398,6 @@ public: // Interface to be implemented in plugins. ////////////////////////////////////////////////////////////////////////// - //! Draw object to specified viewport. - virtual void Display([[maybe_unused]] DisplayContext& disp) {} - //! Perform intersection testing of this object. //! Return true if was hit. virtual bool HitTest([[maybe_unused]] HitContext& hc) { return false; }; @@ -529,8 +526,6 @@ protected: void ResolveParent(CBaseObject* object); void SetColor(const QColor& color); - //! Draw default object items. - virtual void DrawDefault(DisplayContext& dc, const QColor& labelColor = QColor(255, 255, 255)); //! Draw object label. void DrawLabel(DisplayContext& dc, const Vec3& pos, const QColor& labelColor = QColor(255, 255, 255), float alpha = 1.0f, float size = 1.f); //! Draw 3D Axis at object position. @@ -539,10 +534,6 @@ protected: void DrawArea(DisplayContext& dc); //! Draw selection helper. void DrawSelectionHelper(DisplayContext& dc, const Vec3& pos, const QColor& labelColor = QColor(255, 255, 255), float alpha = 1.0f); - //! Draw helper icon. - virtual void DrawTextureIcon(DisplayContext& dc, const Vec3& pos, float alpha = 1.0f); - //! Draw warning icons - virtual void DrawWarningIcons(DisplayContext& dc, const Vec3& pos); //! Check if dimension's figures can be displayed before draw them. virtual void DrawDimensions(DisplayContext& dc, AABB* pMergedBoundBox = nullptr); @@ -575,7 +566,6 @@ protected: //! Only used by ObjectManager. bool IsPotentiallyVisible() const; - void SetDrawTextureIconProperties(DisplayContext& dc, const Vec3& pos, float alpha = 1.0f, int texIconFlags = 0); const Vec3& GetTextureIconDrawPos(){ return m_vDrawIconPos; }; int GetTextureIconFlags(){ return m_nIconFlags; }; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp index fbb700723b..a70c200417 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp @@ -723,97 +723,6 @@ CComponentEntityObject* CComponentEntityObject::FindObjectForEntity(AZ::EntityId return nullptr; } -void CComponentEntityObject::Display(DisplayContext& dc) -{ - if (!(dc.flags & DISPLAY_2D)) - { - m_entityIconVisible = false; - } - - bool displaySelectionHelper = false; - if (!CanBeDrawn(dc, displaySelectionHelper)) - { - return; - } - - DrawDefault(dc); - - bool showIcons = m_hasIcon; - if (showIcons) - { - SEditorSettings* editorSettings = GetIEditor()->GetEditorSettings(); - if (!editorSettings->viewports.bShowIcons && !editorSettings->viewports.bShowSizeBasedIcons) - { - showIcons = false; - } - } - - if (m_entityId.IsValid()) - { - // Draw link to parent if this or the parent object are selected. - { - AZ::EntityId parentId; - EBUS_EVENT_ID_RESULT(parentId, m_entityId, AZ::TransformBus, GetParentId); - if (parentId.IsValid()) - { - bool isParentVisible = false; - AzToolsFramework::EditorEntityInfoRequestBus::EventResult(isParentVisible, parentId, &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible); - - CComponentEntityObject* parentObject = CComponentEntityObject::FindObjectForEntity(parentId); - if (isParentVisible && (IsSelected() || (parentObject && parentObject->IsSelected()))) - { - const QColor kLinkColorParent(0, 255, 255); - const QColor kLinkColorChild(0, 0, 255); - - AZ::Vector3 parentTranslation; - EBUS_EVENT_ID_RESULT(parentTranslation, parentId, AZ::TransformBus, GetWorldTranslation); - dc.DrawLine(AZVec3ToLYVec3(parentTranslation), GetWorldTM().GetTranslation(), kLinkColorParent, kLinkColorChild); - } - } - } - - // Don't draw icons if we have an ancestor in the same location that has an icon - makes sure - // ancestor icons draw on top and are able to be selected over children. Also check if a descendant - // is selected at the same location. In cases of entity hierarchies where numerous ancestors have - // no position offset, we need this so the ancestors don't draw over us when we're selected - if (showIcons) - { - if ((dc.flags & DISPLAY_2D) || - IsSelected() || - IsAncestorIconDrawingAtSameLocation() || - IsDescendantSelectedAtSameLocation()) - { - showIcons = false; - } - } - - // Allow components to override in-editor visualization. - { - const AzFramework::DisplayContextRequestGuard displayContextGuard(dc); - - AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus; - AzFramework::DebugDisplayRequestBus::Bind( - debugDisplayBus, AzFramework::g_defaultSceneEntityDebugDisplayId); - AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus."); - - AzFramework::DebugDisplayRequests* debugDisplay = - AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus); - - AzFramework::EntityDebugDisplayEventBus::Event( - m_entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport, - AzFramework::ViewportInfo{ dc.GetView()->asCViewport()->GetViewportId() }, - *debugDisplay); - } - } -} - -void CComponentEntityObject::DrawDefault(DisplayContext& dc, const QColor& labelColor) -{ - CEntityObject::DrawDefault(dc, labelColor); - - DrawAccent(dc); -} - bool CComponentEntityObject::IsIsolated() const { return m_isIsolated; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h index 7ccea8da84..62209965a5 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h @@ -55,7 +55,6 @@ public: bool SetRotation(const Quat& rotate, int flags) override; bool SetScale(const Vec3& scale, int flags) override; void InvalidateTM(int nWhyFlags) override; - void Display(DisplayContext& disp) override; bool HitTest(HitContext& hc) override; void GetLocalBounds(AABB& box) override; void GetBoundBox(AABB& box) override; @@ -69,7 +68,6 @@ public: void DetachThis(bool bKeepPos = true) override; XmlNodeRef Export(const QString& levelPath, XmlNodeRef& xmlNode) override; void DeleteEntity() override; - void DrawDefault(DisplayContext& dc, const QColor& labelColor = QColor(255, 255, 255)) override; bool IsIsolated() const override; bool IsSelected() const override; diff --git a/Code/Editor/Settings.cpp b/Code/Editor/Settings.cpp index acb48c3545..8561e6dba3 100644 --- a/Code/Editor/Settings.cpp +++ b/Code/Editor/Settings.cpp @@ -142,9 +142,6 @@ SEditorSettings::SEditorSettings() viewports.bShowMeshStatsOnMouseOver = false; viewports.bDrawEntityLabels = false; viewports.bShowTriggerBounds = false; - viewports.bShowIcons = true; - viewports.bDistanceScaleIcons = true; - viewports.bShowSizeBasedIcons = false; viewports.nShowFrozenHelpers = true; viewports.bFillSelectedShapes = false; viewports.nTopMapTextureResolution = 512; @@ -534,8 +531,6 @@ void SEditorSettings::Save(bool isEditorClosing) SaveValue("Settings", "ShowMeshStatsOnMouseOver", viewports.bShowMeshStatsOnMouseOver); SaveValue("Settings", "DrawEntityLabels", viewports.bDrawEntityLabels); SaveValue("Settings", "ShowTriggerBounds", viewports.bShowTriggerBounds); - SaveValue("Settings", "ShowIcons", viewports.bShowIcons); - SaveValue("Settings", "ShowSizeBasedIcons", viewports.bShowSizeBasedIcons); SaveValue("Settings", "ShowFrozenHelpers", viewports.nShowFrozenHelpers); SaveValue("Settings", "FillSelectedShapes", viewports.bFillSelectedShapes); SaveValue("Settings", "MapTextureResolution", viewports.nTopMapTextureResolution); @@ -736,8 +731,6 @@ void SEditorSettings::Load() LoadValue("Settings", "ShowMeshStatsOnMouseOver", viewports.bShowMeshStatsOnMouseOver); LoadValue("Settings", "DrawEntityLabels", viewports.bDrawEntityLabels); LoadValue("Settings", "ShowTriggerBounds", viewports.bShowTriggerBounds); - LoadValue("Settings", "ShowIcons", viewports.bShowIcons); - LoadValue("Settings", "ShowSizeBasedIcons", viewports.bShowSizeBasedIcons); LoadValue("Settings", "ShowFrozenHelpers", viewports.nShowFrozenHelpers); LoadValue("Settings", "FillSelectedShapes", viewports.bFillSelectedShapes); LoadValue("Settings", "MapTextureResolution", viewports.nTopMapTextureResolution); diff --git a/Code/Editor/Settings.h b/Code/Editor/Settings.h index 9276d9b715..0ebb70501d 100644 --- a/Code/Editor/Settings.h +++ b/Code/Editor/Settings.h @@ -136,13 +136,6 @@ struct SViewportsSettings bool bDrawEntityLabels; //! Show Trigger bounds. bool bShowTriggerBounds; - //! Show Icons in viewport. - bool bShowIcons; - //! Scale icons with distance, so they aren't a fixed size no matter how far away you are - bool bDistanceScaleIcons; - - //! Show Size-based Icons in viewport. - bool bShowSizeBasedIcons; //! Show Helpers in viewport for frozen objects. int nShowFrozenHelpers; From bd65da39d0033b504d7da196e86cd9e5a30ec337 Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Wed, 12 Jan 2022 10:20:04 -0800 Subject: [PATCH 158/272] Updated node subtitle Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../EBus/Senders/UiFlipbookAnimationBus.names | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/UiFlipbookAnimationBus.names b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/UiFlipbookAnimationBus.names index c0f62a816b..e869048b0c 100644 --- a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/UiFlipbookAnimationBus.names +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/UiFlipbookAnimationBus.names @@ -21,7 +21,8 @@ }, "details": { "name": "Get Loop Type", - "tooltip": "Gets the type of looping behavior for the animation" + "tooltip": "Gets the type of looping behavior for the animation", + "subtitle": "UI Flipbook" }, "results": [ { @@ -44,7 +45,8 @@ }, "details": { "name": "Get Reverse Delay", - "tooltip": "Gets the delay (in seconds) before playing the reverse loop sequence (PingPong loop types only)" + "tooltip": "Gets the delay (in seconds) before playing the reverse loop sequence (PingPong loop types only)", + "subtitle": "UI Flipbook" }, "results": [ { @@ -67,7 +69,8 @@ }, "details": { "name": "Set Is Auto Play Enabled", - "tooltip": "Sets whether the animation will begin playing as soon as the element is activated" + "tooltip": "Sets whether the animation will begin playing as soon as the element is activated", + "subtitle": "UI Flipbook" }, "params": [ { @@ -91,7 +94,8 @@ }, "details": { "name": "Set Current Frame", - "tooltip": "Sets the frame to immediately display for the animation" + "tooltip": "Sets the frame to immediately display for the animation", + "subtitle": "UI Flipbook" }, "params": [ { @@ -115,7 +119,8 @@ }, "details": { "name": "Get Loop Start Frame", - "tooltip": "Gets the first frame that is displayed within an animation loop. Applicable only when the \"Loop Type\" is set to anything other than \"None\"" + "tooltip": "Gets the first frame that is displayed within an animation loop. Applicable only when the \"Loop Type\" is set to anything other than \"None\"", + "subtitle": "UI Flipbook" }, "results": [ { @@ -138,7 +143,8 @@ }, "details": { "name": "Set Loop Type", - "tooltip": "Sets the type of looping behavior for this animation" + "tooltip": "Sets the type of looping behavior for this animation", + "subtitle": "UI Flipbook" }, "params": [ { @@ -162,7 +168,8 @@ }, "details": { "name": "Get Start Delay", - "tooltip": "Gets the delay (in seconds) before playing the flipbook (applied only once during playback)" + "tooltip": "Gets the delay (in seconds) before playing the flipbook (applied only once during playback)", + "subtitle": "UI Flipbook" }, "results": [ { @@ -185,7 +192,8 @@ }, "details": { "name": "Set Start Delay", - "tooltip": "Sets the delay (in seconds) before playing the flipbook (applied only once during playback)" + "tooltip": "Sets the delay (in seconds) before playing the flipbook (applied only once during playback)", + "subtitle": "UI Flipbook" }, "params": [ { @@ -209,7 +217,8 @@ }, "details": { "name": "Get Current Frame", - "tooltip": "Gets the frame of the animation currently displayed" + "tooltip": "Gets the frame of the animation currently displayed", + "subtitle": "UI Flipbook" }, "results": [ { @@ -232,7 +241,8 @@ }, "details": { "name": "Get Framerate", - "tooltip": "Gets the speed used to determine when to transition to the next frame. Framerate is defined relative to unit of time, specified by FramerateUnits" + "tooltip": "Gets the speed used to determine when to transition to the next frame. Framerate is defined relative to unit of time, specified by FramerateUnits", + "subtitle": "UI Flipbook" }, "results": [ { @@ -255,7 +265,8 @@ }, "details": { "name": "Set Loop Delay", - "tooltip": "Sets the delay (in seconds) before playing the loop sequence" + "tooltip": "Sets the delay (in seconds) before playing the loop sequence", + "subtitle": "UI Flipbook" }, "params": [ { @@ -279,7 +290,8 @@ }, "details": { "name": "Get Start Frame", - "tooltip": "Gets the first frame to display when starting the animation" + "tooltip": "Gets the first frame to display when starting the animation", + "subtitle": "UI Flipbook" }, "results": [ { @@ -302,7 +314,8 @@ }, "details": { "name": "Set Framerate Unit", - "tooltip": "Sets the framerate unit (0 = Frames per second, 1 = Seconds per frame)" + "tooltip": "Sets the framerate unit (0 = Frames per second, 1 = Seconds per frame)", + "subtitle": "UI Flipbook" }, "params": [ { @@ -326,7 +339,8 @@ }, "details": { "name": "Is Playing", - "tooltip": "Returns whether the animation is currently playing" + "tooltip": "Returns whether the animation is currently playing", + "subtitle": "UI Flipbook" }, "results": [ { @@ -349,7 +363,8 @@ }, "details": { "name": "Set End Frame", - "tooltip": "Sets the last frame to display for the animation" + "tooltip": "Sets the last frame to display for the animation", + "subtitle": "UI Flipbook" }, "params": [ { @@ -373,7 +388,8 @@ }, "details": { "name": "Set Loop Start Frame", - "tooltip": "Sets the first frame that is displayed within an animation loop. Applicable only when the \"Loop Type\" is set to anything other than \"None\"" + "tooltip": "Sets the first frame that is displayed within an animation loop. Applicable only when the \"Loop Type\" is set to anything other than \"None\"", + "subtitle": "UI Flipbook" }, "params": [ { @@ -397,7 +413,8 @@ }, "details": { "name": "Set Reverse Delay", - "tooltip": "Sets the delay (in seconds) before playing the reverse loop sequence (PingPong loop types only)" + "tooltip": "Sets the delay (in seconds) before playing the reverse loop sequence (PingPong loop types only)", + "subtitle": "UI Flipbook" }, "params": [ { @@ -421,7 +438,8 @@ }, "details": { "name": "Stop", - "tooltip": "Ends the animation" + "tooltip": "Ends the animation", + "subtitle": "UI Flipbook" } }, { @@ -436,7 +454,8 @@ }, "details": { "name": "Set Framerate", - "tooltip": "Sets the speed used to determine when to transition to the next frame. Framerate is defined relative to unit of time, specified by FramerateUnits" + "tooltip": "Sets the speed used to determine when to transition to the next frame. Framerate is defined relative to unit of time, specified by FramerateUnits", + "subtitle": "UI Flipbook" }, "params": [ { @@ -460,7 +479,8 @@ }, "details": { "name": "Is Auto Play Enabled", - "tooltip": "Returns whether the animation will begin playing as soon as the element is activated" + "tooltip": "Returns whether the animation will begin playing as soon as the element is activated", + "subtitle": "UI Flipbook" }, "results": [ { @@ -483,7 +503,8 @@ }, "details": { "name": "Start", - "tooltip": "Begins playing the flipbook animation" + "tooltip": "Begins playing the flipbook animation", + "subtitle": "UI Flipbook" } }, { @@ -498,7 +519,8 @@ }, "details": { "name": "Set Start Frame", - "tooltip": "Sets the first frame to display when starting the animation" + "tooltip": "Sets the first frame to display when starting the animation", + "subtitle": "UI Flipbook" }, "params": [ { @@ -522,7 +544,8 @@ }, "details": { "name": "Get End Frame", - "tooltip": "Gets the last frame to display for the animation" + "tooltip": "Gets the last frame to display for the animation", + "subtitle": "UI Flipbook" }, "results": [ { @@ -545,7 +568,8 @@ }, "details": { "name": "Get Framerate Unit", - "tooltip": "Gets the framerate unit (0 = Frames per second, 1 = Seconds per frame)" + "tooltip": "Gets the framerate unit (0 = Frames per second, 1 = Seconds per frame)", + "subtitle": "UI Flipbook" }, "results": [ { @@ -568,7 +592,8 @@ }, "details": { "name": "Get Loop Delay", - "tooltip": "Gets the delay (in seconds) before playing the loop sequence" + "tooltip": "Gets the delay (in seconds) before playing the loop sequence", + "subtitle": "UI Flipbook" }, "results": [ { From 5b195cb028781c8738da4d9e7ff587f0f940c0aa Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Wed, 12 Jan 2022 12:33:36 -0600 Subject: [PATCH 159/272] Removed some unused variables Signed-off-by: Chris Galvan --- Code/Editor/Objects/BaseObject.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Code/Editor/Objects/BaseObject.cpp b/Code/Editor/Objects/BaseObject.cpp index 5ae68eaad7..c14547407b 100644 --- a/Code/Editor/Objects/BaseObject.cpp +++ b/Code/Editor/Objects/BaseObject.cpp @@ -36,12 +36,6 @@ // To use the Andrew's algorithm in order to make convex hull from the points, this header is needed. #include "Util/GeometryUtil.h" -namespace { - QColor kLinkColorParent = QColor(0, 255, 255); - QColor kLinkColorChild = QColor(0, 0, 255); - QColor kLinkColorGray = QColor(128, 128, 128); -} - extern CObjectManager* g_pObjectManager; ////////////////////////////////////////////////////////////////////////// From 068244b1bb28191758637028864505c2b727b890 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 12 Jan 2022 12:00:33 -0800 Subject: [PATCH 160/272] Remove quotes around list of paths (#6857) Signed-off-by: amzn-sj --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 51e6e5830c..c27bf1fde4 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -187,7 +187,7 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") ) file(GLOB_RECURSE exe_file_list "${bundle_path}/Contents/Frameworks/Python.framework/**/*.exe") if(exe_file_list) - file(REMOVE_RECURSE "${exe_file_list}") + file(REMOVE_RECURSE ${exe_file_list}) endif() execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink include/python3.7m Headers WORKING_DIRECTORY "${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7" From 5dc442fcb0f2946cd104849b9bc814be134b9426 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 12 Jan 2022 12:07:57 -0800 Subject: [PATCH 161/272] [Terrain] First pass of the ProcessList and ProcessRegion APIs for retrieving surface data (#6729) * [Terrain] First pass of the ProcessList and ProcessRegion APIs for retrieving surface data Signed-off-by: amzn-sj * Add a couple of more tests. The expected values were plugged in based on the values generated by the brute force approach. Signed-off-by: amzn-sj * Move some declarations out of loops since they can be reused. Signed-off-by: amzn-sj * Update all the per position callbacks to pass SurfacePoint refs. Construct only one SurfacePoint object outside the loop which can be reused. Signed-off-by: amzn-sj * Update tests to use the new per position callbacks Signed-off-by: amzn-sj * Add ProcessRegion functions to the terrain benchmark. Signed-off-by: amzn-sj * Change C style static casts to aznumeric_cast. Add maybe_unused to unused params in benchmarks. Signed-off-by: amzn-sj * Update the ProcessList API functions to use array_view instead of a vector. This includes some additional changes to satisfy build dependencies. Signed-off-by: amzn-sj * Add ProcessList API functions to benchmarks Signed-off-by: amzn-sj * Update the ProcessList API functions to take Vector2 as input positions Signed-off-by: amzn-sj * Revert changes to AtomCore library split. Add partial implementation of span(mostly just copied over from array_view) to AzCore std containers. Signed-off-by: amzn-sj * Adding some const/non-const overloads that were missing in span Signed-off-by: amzn-sj * Move input position list generation to a function Signed-off-by: amzn-sj * Bring back Vector3 version of ProcessList functions. Rename Vector2 version to follow similar pattern as the Get functions. Signed-off-by: amzn-sj * Split span.h into .h/.inl files Signed-off-by: amzn-sj * Add [mayby_unused] for unused parameters to fix build errors Signed-off-by: amzn-sj --- .../AzCore/AzCore/std/azstd_files.cmake | 2 + .../AzCore/AzCore/std/containers/span.h | 137 ++++++++ .../AzCore/AzCore/std/containers/span.inl | 150 ++++++++ .../Terrain/TerrainDataRequestBus.h | 50 +++ .../Mocks/Terrain/MockTerrainDataRequestBus.h | 24 ++ .../Source/TerrainSystem/TerrainSystem.cpp | 282 +++++++++++++-- .../Code/Source/TerrainSystem/TerrainSystem.h | 47 +++ .../Code/Tests/TerrainSystemBenchmarks.cpp | 262 ++++++++++++++ Gems/Terrain/Code/Tests/TerrainSystemTest.cpp | 330 ++++++++++++++++++ 9 files changed, 1251 insertions(+), 33 deletions(-) create mode 100644 Code/Framework/AzCore/AzCore/std/containers/span.h create mode 100644 Code/Framework/AzCore/AzCore/std/containers/span.inl diff --git a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake index 2746489f8c..d516a56295 100644 --- a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake +++ b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake @@ -64,6 +64,8 @@ set(FILES containers/rbtree.h containers/ring_buffer.h containers/set.h + containers/span.h + containers/span.inl containers/stack.h containers/unordered_map.h containers/unordered_set.h diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.h b/Code/Framework/AzCore/AzCore/std/containers/span.h new file mode 100644 index 0000000000..8f68e921d8 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/std/containers/span.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include + +namespace AZStd +{ + /** + * First pass partial implementation of span copied over from array_view. It + * returns non-const iterator/pointers. first(), last(), and subspan() + * are yet to be implemented. It does not maintain storage for the data, + * but just holds pointers to mark the beginning and end of the array. + * It can be conveniently constructed from a variety of other container + * types like array, vector, and fixed_vector. + * + * Example: + * Given "void Func(AZStd::span a) {...}" you can call... + * - Func({1,2,3}); + * - AZStd::array a = {1,2,3}; + * Func(a); + * - AZStd::vector v = {1,2,3}; + * Func(v); + * - AZStd::fixed_vector fv = {1,2,3}; + * Func(fv); + * + * Since the span does not copy and store any data, it is only valid as long as the data used to create it is valid. + */ + template + class span final + { + public: + using value_type = Element; + + using pointer = value_type*; + using const_pointer = const value_type*; + + using reference = value_type&; + using const_reference = const value_type&; + + using size_type = AZStd::size_t; + using difference_type = AZStd::ptrdiff_t; + + using iterator = value_type*; + using const_iterator = const value_type*; + using reverse_iterator = AZStd::reverse_iterator; + using const_reverse_iterator = AZStd::reverse_iterator; + + constexpr span(); + + ~span() = default; + + constexpr span(pointer s, size_type length); + + constexpr span(pointer first, const_pointer last); + + // We explicitly delete this constructor because it's too easy to accidentally + // create a span to just the first element instead of an entire array. + constexpr span(const_pointer s) = delete; + + template + constexpr span(AZStd::array& data); + + constexpr span(AZStd::vector& data); + + template + constexpr span(AZStd::fixed_vector& data); + + template + constexpr span(const AZStd::array& data); + + constexpr span(const AZStd::vector& data); + + template + constexpr span(const AZStd::fixed_vector& data); + + constexpr span(const span&) = default; + + constexpr span(span&& other); + + constexpr span& operator=(const span& other) = default; + + constexpr span& operator=(span&& other); + + constexpr size_type size() const; + + constexpr bool empty() const; + + constexpr pointer data(); + constexpr const_pointer data() const; + + constexpr const_reference operator[](size_type index) const; + constexpr reference operator[](size_type index); + + constexpr void erase(); + + constexpr iterator begin(); + constexpr iterator end(); + constexpr const_iterator begin() const; + constexpr const_iterator end() const; + + constexpr const_iterator cbegin() const; + constexpr const_iterator cend() const; + + constexpr reverse_iterator rbegin(); + constexpr reverse_iterator rend(); + constexpr const_reverse_iterator rbegin() const; + constexpr const_reverse_iterator rend() const; + + constexpr const_reverse_iterator crbegin() const; + constexpr const_reverse_iterator crend() const; + + friend bool operator==(span lhs, span rhs) + { + return lhs.m_begin == rhs.m_begin && lhs.m_end == rhs.m_end; + } + + friend bool operator!=(span lhs, span rhs) { return !(lhs == rhs); } + friend bool operator< (span lhs, span rhs) { return lhs.m_begin < rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end < rhs.m_end; } + friend bool operator> (span lhs, span rhs) { return lhs.m_begin > rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end > rhs.m_end; } + friend bool operator<=(span lhs, span rhs) { return lhs == rhs || lhs < rhs; } + friend bool operator>=(span lhs, span rhs) { return lhs == rhs || lhs > rhs; } + + private: + pointer m_begin; + pointer m_end; + }; +} // namespace AZStd + +#include diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.inl b/Code/Framework/AzCore/AzCore/std/containers/span.inl new file mode 100644 index 0000000000..c33e4a7227 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/std/containers/span.inl @@ -0,0 +1,150 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +namespace AZStd +{ + template + inline constexpr span::span() + : m_begin(nullptr) + , m_end(nullptr) + { } + + template + inline constexpr span::span(pointer s, size_type length) + : m_begin(s) + , m_end(m_begin + length) + { + if (length == 0) erase(); + } + + template + inline constexpr span::span(pointer first, const_pointer last) + : m_begin(first) + , m_end(last) + { } + + template + template + inline constexpr span::span(AZStd::array& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + inline constexpr span::span(AZStd::vector& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + template + inline constexpr span::span(AZStd::fixed_vector& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + template + inline constexpr span::span(const AZStd::array& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + inline constexpr span::span(const AZStd::vector& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + template + inline constexpr span::span(const AZStd::fixed_vector& data) + : m_begin(data.data()) + , m_end(m_begin + data.size()) + { } + + template + inline constexpr span::span(span&& other) + : span(other.m_begin, other.m_end) + { +#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging + other.m_begin = nullptr; + other.m_end = nullptr; +#endif + } + + template + inline constexpr AZStd::size_t span::size() const { return m_end - m_begin; } + + template + inline constexpr bool span::empty() const { return m_end == m_begin; } + + template + inline constexpr Element* span::data() { return m_begin; } + + template + inline constexpr const Element* span::data() const { return m_begin; } + + template + inline constexpr span& span::operator=(span&& other) + { + m_begin = other.m_begin; + m_end = other.m_end; +#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging + other.m_begin = nullptr; + other.m_end = nullptr; +#endif + return *this; + } + + template + inline constexpr const Element& span::operator[](AZStd::size_t index) const + { + AZ_Assert(index < size(), "index value is out of range"); + return m_begin[index]; + } + + template + inline constexpr Element& span::operator[](AZStd::size_t index) + { + AZ_Assert(index < size(), "index value is out of range"); + return m_begin[index]; + } + + template + inline constexpr void span::erase() { m_begin = m_end = nullptr; } + + template + inline constexpr Element* span::begin() { return m_begin; } + template + inline constexpr Element* span::end() { return m_end; } + template + inline constexpr const Element* span::begin() const { return m_begin; } + template + inline constexpr const Element* span::end() const { return m_end; } + + template + inline constexpr const Element* span::cbegin() const { return m_begin; } + template + inline constexpr const Element* span::cend() const { return m_end; } + + template + inline constexpr AZStd::reverse_iterator span::rbegin() { return AZStd::reverse_iterator(m_end); } + template + inline constexpr AZStd::reverse_iterator span::rend() { return AZStd::reverse_iterator(m_begin); } + template + inline constexpr AZStd::reverse_iterator span::rbegin() const { return AZStd::reverse_iterator(m_end); } + template + inline constexpr AZStd::reverse_iterator span::rend() const { return AZStd::reverse_iterator(m_begin); } + + template + inline constexpr AZStd::reverse_iterator span::crbegin() const { return AZStd::reverse_iterator(cend()); } + template + inline constexpr AZStd::reverse_iterator span::crend() const { return AZStd::reverse_iterator(cbegin()); } +} // namespace AZStd diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 2572a07494..0d16bf3460 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -11,12 +11,15 @@ #include #include #include +#include #include namespace AzFramework { namespace Terrain { + typedef AZStd::function SurfacePointRegionFillCallback; + typedef AZStd::function SurfacePointListFillCallback; //! Shared interface for terrain system implementations class TerrainDataRequests @@ -131,6 +134,53 @@ namespace AzFramework Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0; + //! Given a list of XY coordinates, call the provided callback function with surface data corresponding to each + //! XY coordinate in the list. + virtual void ProcessHeightsFromList(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessNormalsFromList(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfaceWeightsFromList(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfacePointsFromList(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessHeightsFromListOfVector2(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessNormalsFromListOfVector2(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span& inPositions, + SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the + //! coordinates in the region. + virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessNormalsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfaceWeightsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + virtual void ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const = 0; + + private: // Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of // using an "out" parameter. The "out" parameter is useful for reusing memory allocated in SurfacePoint when diff --git a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h index dbce11d639..f3a6cc07b3 100644 --- a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h @@ -76,5 +76,29 @@ namespace UnitTest GetSurfacePointFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*)); MOCK_CONST_METHOD5( GetSurfacePointFromFloats, void(float, float, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*)); + MOCK_CONST_METHOD3( + ProcessHeightsFromList, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessNormalsFromList, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessSurfaceWeightsFromList, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessSurfacePointsFromList, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessHeightsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessNormalsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD3( + ProcessSurfacePointsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD4( + ProcessHeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); + MOCK_CONST_METHOD4( + ProcessNormalsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); + MOCK_CONST_METHOD4( + ProcessSurfaceWeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); + MOCK_CONST_METHOD4( + ProcessSurfacePointsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); }; } // namespace UnitTest diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp index 7c8b6021af..2ecd13b5ad 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp @@ -530,9 +530,171 @@ const char* TerrainSystem::GetMaxSurfaceName( return ""; } -/* +void TerrainSystem::ProcessHeightsFromList( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } -void TerrainSystem::ProcessHeightsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, Sampler sampleFilter, SurfacePointRegionFillCallback perPositionCallback, TerrainDataReadyCallback onComplete) + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position = position; + surfacePoint.m_position.SetZ(GetHeight(position, sampleFilter, &terrainExists)); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessNormalsFromList( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position = position; + surfacePoint.m_normal = GetNormal(position, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessSurfaceWeightsFromList( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position = position; + GetSurfaceWeights(position, surfacePoint.m_surfaceTags, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessSurfacePointsFromList( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position = position; + GetSurfacePoint(position, surfacePoint, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessHeightsFromListOfVector2( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position.Set(position.GetX(), position.GetY(), 0.0f); + surfacePoint.m_position.SetZ(GetHeightFromVector2(position, sampleFilter, &terrainExists)); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessNormalsFromListOfVector2( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position.Set(position.GetX(), position.GetY(), 0.0f); + surfacePoint.m_normal = GetNormalFromVector2(position, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessSurfaceWeightsFromListOfVector2( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position.Set(position.GetX(), position.GetY(), 0.0f); + GetSurfaceWeightsFromVector2(position, surfacePoint.m_surfaceTags, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessSurfacePointsFromListOfVector2( + const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + if (!perPositionCallback) + { + return; + } + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (const auto& position : inPositions) + { + bool terrainExists = false; + surfacePoint.m_position.Set(position.GetX(), position.GetY(), 0.0f); + GetSurfacePointFromVector2(position, surfacePoint, sampleFilter, &terrainExists); + perPositionCallback(surfacePoint, terrainExists); + } +} + +void TerrainSystem::ProcessHeightsFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter) const { // Don't bother processing if we don't have a callback if (!perPositionCallback) @@ -540,30 +702,29 @@ void TerrainSystem::ProcessHeightsFromRegion(const AZ::Aabb& inRegion, const AZ: return; } - uint32_t numSamplesX = static_cast((inRegion.GetMax().GetX() - inRegion.GetMin().GetX()) / stepSize.GetX()); - uint32_t numSamplesY = static_cast((inRegion.GetMax().GetY() - inRegion.GetMin().GetY()) / stepSize.GetY()); - - for (uint32_t y = 0; y < numSamplesY; y++) + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) { - for (uint32_t x = 0; x < numSamplesX; x++) + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) { - float fx = (float)(inRegion.GetMin().GetX() + (x * stepSize.GetX())); - float fy = (float)(inRegion.GetMin().GetY() + (y * stepSize.GetY())); - - SurfaceData::SurfacePoint surfacePoint; - GetHeight(AZ::Vector3(fx, fy, 0.0f), sampleFilter, surfacePoint.m_position); - perPositionCallback(surfacePoint, x, y); + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, 0.0f); + surfacePoint.m_position.SetZ(GetHeight(surfacePoint.m_position, sampleFilter, &terrainExists)); + perPositionCallback(x, y, surfacePoint, terrainExists); } } - - if (onComplete) - { - onComplete(); - } } - -void TerrainSystem::ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, Sampler sampleFilter, SurfacePointRegionFillCallback perPositionCallback, TerrainDataReadyCallback onComplete) +void TerrainSystem::ProcessNormalsFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter) const { // Don't bother processing if we don't have a callback if (!perPositionCallback) @@ -571,28 +732,83 @@ void TerrainSystem::ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion, con return; } - uint32_t numSamplesX = static_cast((inRegion.GetMax().GetX() - inRegion.GetMin().GetX()) / stepSize.GetX()); - uint32_t numSamplesY = static_cast((inRegion.GetMax().GetY() - inRegion.GetMin().GetY()) / stepSize.GetY()); + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); - for (uint32_t y = 0; y < numSamplesY; y++) + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) { - for (uint32_t x = 0; x < numSamplesX; x++) + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) { - float fx = (float)(inRegion.GetMin().GetX() + (x * stepSize.GetX())); - float fy = (float)(inRegion.GetMin().GetY() + (y * stepSize.GetY())); - - SurfaceData::SurfacePoint surfacePoint; - GetSurfacePoint(AZ::Vector3(fx, fy, inRegion.GetMin().GetZ()), sampleFilter, surfacePoint); - perPositionCallback(surfacePoint, x, y); + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, 0.0f); + surfacePoint.m_normal = GetNormal(surfacePoint.m_position, sampleFilter, &terrainExists); + perPositionCallback(x, y, surfacePoint, terrainExists); } } +} - if (onComplete) +void TerrainSystem::ProcessSurfaceWeightsFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + // Don't bother processing if we don't have a callback + if (!perPositionCallback) { - onComplete(); + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, 0.0f); + GetSurfaceWeights(surfacePoint.m_position, surfacePoint.m_surfaceTags, sampleFilter, &terrainExists); + perPositionCallback(x, y, surfacePoint, terrainExists); + } + } +} + +void TerrainSystem::ProcessSurfacePointsFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter) const +{ + // Don't bother processing if we don't have a callback + if (!perPositionCallback) + { + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, 0.0f); + GetSurfacePoint(surfacePoint.m_position, surfacePoint, sampleFilter, &terrainExists); + perPositionCallback(x, y, surfacePoint, terrainExists); + } } } -*/ void TerrainSystem::RegisterArea(AZ::EntityId areaId) { diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h index d7267476ed..7c6e0cd91e 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -135,6 +136,52 @@ namespace Terrain Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const override; + //! Given a list of XY coordinates, call the provided callback function with surface data corresponding to each + //! XY coordinate in the list. + virtual void ProcessHeightsFromList(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessNormalsFromList(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfaceWeightsFromList(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfacePointsFromList(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessHeightsFromListOfVector2(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessNormalsFromListOfVector2(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span& inPositions, + AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the + //! coordinates in the region. + virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessNormalsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfaceWeightsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + virtual void ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + Sampler sampleFilter = Sampler::DEFAULT) const override; + private: void ClampPosition(float x, float y, AZ::Vector2& outPosition, AZ::Vector2& normalizedDelta) const; diff --git a/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp b/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp index 3d0cb5222e..85dd5dc0c4 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp @@ -281,6 +281,22 @@ namespace UnitTest surfaceGradientShapeRequests.clear(); } + void GenerateInputPositionsList(const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, AZStd::vector& positions) + { + const size_t numSamplesX = aznumeric_cast(ceil(worldBounds.GetExtents().GetX() / queryResolution.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(worldBounds.GetExtents().GetY() / queryResolution.GetY())); + + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(worldBounds.GetMin().GetY() + (y * queryResolution.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + float fx = aznumeric_cast(worldBounds.GetMin().GetX() + (x * queryResolution.GetX())); + positions.emplace_back(fx, fy, 0.0f); + } + } + } + protected: AZStd::unique_ptr m_app; }; @@ -322,6 +338,72 @@ namespace UnitTest ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegion)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + []([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_position.GetZ()); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, worldBounds, queryResolution, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegion) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsList)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + [this]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + AZStd::vector inPositions; + GenerateInputPositionsList(queryResolution, worldBounds, inPositions); + + auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_position.GetZ()); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromList, inPositions, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsList) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 4096, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetNormal)(benchmark::State& state) { // Run the benchmark @@ -353,6 +435,66 @@ namespace UnitTest ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegion)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + []([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_normal); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromRegion, worldBounds, queryResolution, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegion) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsList)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + [this]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + AZStd::vector inPositions; + GenerateInputPositionsList(queryResolution, worldBounds, inPositions); + + auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_normal); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromList, inPositions, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsList) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfaceWeights)(benchmark::State& state) { // Run the benchmark @@ -385,6 +527,66 @@ namespace UnitTest ->Args({ 2048, 4, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegion)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + []([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_surfaceTags); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromRegion, worldBounds, queryResolution, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegion) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 1024, 2, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 2, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 1024, 4, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 4, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsList)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + [this]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + AZStd::vector inPositions; + GenerateInputPositionsList(queryResolution, worldBounds, inPositions); + + auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint.m_surfaceTags); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromList, inPositions, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsList) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 1024, 2, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 2, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 1024, 4, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 4, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfacePoints)(benchmark::State& state) { // Run the benchmark @@ -416,6 +618,66 @@ namespace UnitTest ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegion)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + []([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromRegion, worldBounds, queryResolution, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegion) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); + + BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsList)(benchmark::State& state) + { + // Run the benchmark + RunTerrainApiBenchmark( + state, + [this]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds, + AzFramework::Terrain::TerrainDataRequests::Sampler sampler) + { + AZStd::vector inPositions; + GenerateInputPositionsList(queryResolution, worldBounds, inPositions); + + auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + benchmark::DoNotOptimize(surfacePoint); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromList, inPositions, perPositionCallback, sampler); + } + ); + } + + BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsList) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) }) + ->Args({ 1024, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Args({ 2048, 1, static_cast(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) }) + ->Unit(::benchmark::kMillisecond); #endif } diff --git a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp index e5434c0a1d..a5798a3dad 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp @@ -41,6 +41,28 @@ namespace UnitTest float m_expectedHeight = 0.0f; }; + struct NormalTestPoint + { + AZ::Vector2 m_testLocation = AZ::Vector2::CreateZero(); + AZ::Vector3 m_expectedNormal = AZ::Vector3::CreateZero(); + }; + + struct HeightTestRegionPoints + { + size_t m_xIndex; + size_t m_yIndex; + float m_expectedHeight; + AZ::Vector2 m_testLocation = AZ::Vector2::CreateZero(); + }; + + struct NormalTestRegionPoints + { + size_t m_xIndex; + size_t m_yIndex; + AZ::Vector3 m_expectedNormal = AZ::Vector3::CreateZero(); + AZ::Vector2 m_testLocation = AZ::Vector2::CreateZero(); + }; + AZ::ComponentApplication m_app; AZStd::unique_ptr> m_boxShapeRequests; @@ -572,4 +594,312 @@ namespace UnitTest EXPECT_EQ(tagWeight.m_surfaceType, tagWeight1.m_surfaceType); EXPECT_NEAR(tagWeight.m_weight, tagWeight1.m_weight, 0.01f); } + + TEST_F(TerrainSystemTest, TerrainProcessHeightsFromListWithBilinearSamplers) + { + // This repeats the same test as TerrainHeightQueriesWithBilinearSamplersUseQueryGridToInterpolate + // The difference is that it tests the ProcessHeightsFromList variation. + + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + const float amplitudeMeters = 10.0f; + const float frequencyMeters = 1.0f; + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [amplitudeMeters, frequencyMeters](AZ::Vector3& position, bool& terrainExists) + { + // Our generated height will be X + Y. + float expectedHeight = position.GetX() + position.GetY(); + + // If either X or Y aren't evenly divisible by the query frequency, add a scaled value to our generated height. + // This will show up as an unexpected height "spike" if it gets used in any bilinear filter queries. + float unexpectedVariance = + amplitudeMeters * (fmodf(position.GetX(), frequencyMeters) + fmodf(position.GetY(), frequencyMeters)); + position.SetZ(expectedHeight + unexpectedVariance); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(frequencyMeters); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + // Test some points and verify that the results are the expected bilinear filtered result, + // whether they're in positive or negative space. + // (Z contains the the expected result for convenience). + const HeightTestPoint testPoints[] = { + + // Queries directly on grid points. These should return values of X + Y. + { AZ::Vector2(0.0f, 0.0f), 0.0f }, // Should return a height of 0 + 0 + { AZ::Vector2(1.0f, 0.0f), 1.0f }, // Should return a height of 1 + 0 + { AZ::Vector2(0.0f, 1.0f), 1.0f }, // Should return a height of 0 + 1 + { AZ::Vector2(1.0f, 1.0f), 2.0f }, // Should return a height of 1 + 1 + { AZ::Vector2(3.0f, 5.0f), 8.0f }, // Should return a height of 3 + 5 + + { AZ::Vector2(-1.0f, 0.0f), -1.0f }, // Should return a height of -1 + 0 + { AZ::Vector2(0.0f, -1.0f), -1.0f }, // Should return a height of 0 + -1 + { AZ::Vector2(-1.0f, -1.0f), -2.0f }, // Should return a height of -1 + -1 + { AZ::Vector2(-3.0f, -5.0f), -8.0f }, // Should return a height of -3 + -5 + + // Queries that are on a grid edge (one axis on the grid, the other somewhere in-between). + // These should just be a linear interpolation of the points, so it should still be X + Y. + + { AZ::Vector2(0.25f, 0.0f), 0.25f }, // Should return a height of -0.25 + 0 + { AZ::Vector2(3.75f, 0.0f), 3.75f }, // Should return a height of -3.75 + 0 + { AZ::Vector2(0.0f, 0.25f), 0.25f }, // Should return a height of 0 + -0.25 + { AZ::Vector2(0.0f, 3.75f), 3.75f }, // Should return a height of 0 + -3.75 + + { AZ::Vector2(2.0f, 3.75f), 5.75f }, // Should return a height of -2 + -3.75 + { AZ::Vector2(2.25f, 4.0f), 6.25f }, // Should return a height of -2.25 + -4 + + { AZ::Vector2(-0.25f, 0.0f), -0.25f }, // Should return a height of -0.25 + 0 + { AZ::Vector2(-3.75f, 0.0f), -3.75f }, // Should return a height of -3.75 + 0 + { AZ::Vector2(0.0f, -0.25f), -0.25f }, // Should return a height of 0 + -0.25 + { AZ::Vector2(0.0f, -3.75f), -3.75f }, // Should return a height of 0 + -3.75 + + { AZ::Vector2(-2.0f, -3.75f), -5.75f }, // Should return a height of -2 + -3.75 + { AZ::Vector2(-2.25f, -4.0f), -6.25f }, // Should return a height of -2.25 + -4 + + // Queries inside a grid square (both axes are in-between grid points) + // This is a full bilinear interpolation, but because we're using X + Y for our heights, the interpolated values + // should *still* be X + Y assuming the points were sampled correctly from the grid points. + + { AZ::Vector2(3.25f, 5.25f), 8.5f }, // Should return a height of 3.25 + 5.25 + { AZ::Vector2(7.71f, 9.74f), 17.45f }, // Should return a height of 7.71 + 9.74 + + { AZ::Vector2(-3.25f, -5.25f), -8.5f }, // Should return a height of -3.25 + -5.25 + { AZ::Vector2(-7.71f, -9.74f), -17.45f }, // Should return a height of -7.71 + -9.74 + }; + + auto perPositionCallback = [&testPoints](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists){ + bool found = false; + for (auto& testPoint : testPoints) + { + if (testPoint.m_testLocation.GetX() == surfacePoint.m_position.GetX() && testPoint.m_testLocation.GetY() == surfacePoint.m_position.GetY()) + { + constexpr float epsilon = 0.0001f; + EXPECT_NEAR(surfacePoint.m_position.GetZ(), testPoint.m_expectedHeight, epsilon); + found = true; + break; + } + } + EXPECT_EQ(found, true); + }; + + AZStd::vector inPositions; + for (auto& testPoint : testPoints) + { + AZ::Vector3 position(testPoint.m_testLocation.GetX(), testPoint.m_testLocation.GetY(), 0.0f); + inPositions.push_back(position); + } + + terrainSystem->ProcessHeightsFromList(inPositions, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); + } + + TEST_F(TerrainSystemTest, TerrainProcessNormalsFromListWithBilinearSamplers) + { + // Similar to TerrainProcessHeightsFromListWithBilinearSamplers but for normals + + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + const float amplitudeMeters = 10.0f; + const float frequencyMeters = 1.0f; + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [amplitudeMeters, frequencyMeters](AZ::Vector3& position, bool& terrainExists) + { + // Our generated height will be X + Y. + float expectedHeight = position.GetX() + position.GetY(); + + // If either X or Y aren't evenly divisible by the query frequency, add a scaled value to our generated height. + // This will show up as an unexpected height "spike" if it gets used in any bilinear filter queries. + float unexpectedVariance = + amplitudeMeters * (fmodf(position.GetX(), frequencyMeters) + fmodf(position.GetY(), frequencyMeters)); + position.SetZ(expectedHeight + unexpectedVariance); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(frequencyMeters); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + const NormalTestPoint testPoints[] = { + + { AZ::Vector2(0.0f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(1.0f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, 1.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(1.0f, 1.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(3.0f, 5.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(-1.0f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, -1.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(-1.0f, -1.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(-3.0f, -5.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(0.25f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(3.75f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, 0.25f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, 3.75f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(2.0f, 3.75f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(2.25f, 4.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(-0.25f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(-3.75f, 0.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, -0.25f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(0.0f, -3.75f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(-2.0f, -3.75f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(-2.25f, -4.0f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + + { AZ::Vector2(3.25f, 5.25f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(7.71f, 9.74f), AZ::Vector3(-0.0292f, 0.9991f, 0.0292f) }, + + { AZ::Vector2(-3.25f, -5.25f), AZ::Vector3(-0.5773f, -0.5773f, 0.5773f) }, + { AZ::Vector2(-7.71f, -9.74f), AZ::Vector3(-0.0366f, -0.9986f, 0.0366f) }, + }; + + auto perPositionCallback = [&testPoints](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists){ + bool found = false; + for (auto& testPoint : testPoints) + { + if (testPoint.m_testLocation.GetX() == surfacePoint.m_position.GetX() && testPoint.m_testLocation.GetY() == surfacePoint.m_position.GetY()) + { + constexpr float epsilon = 0.0001f; + EXPECT_NEAR(surfacePoint.m_normal.GetX(), testPoint.m_expectedNormal.GetX(), epsilon); + EXPECT_NEAR(surfacePoint.m_normal.GetY(), testPoint.m_expectedNormal.GetY(), epsilon); + EXPECT_NEAR(surfacePoint.m_normal.GetZ(), testPoint.m_expectedNormal.GetZ(), epsilon); + found = true; + break; + } + } + EXPECT_EQ(found, true); + }; + + AZStd::vector inPositions; + for (auto& testPoint : testPoints) + { + AZ::Vector3 position(testPoint.m_testLocation.GetX(), testPoint.m_testLocation.GetY(), 0.0f); + inPositions.push_back(position); + } + + terrainSystem->ProcessNormalsFromList(inPositions, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); + } + + TEST_F(TerrainSystemTest, TerrainProcessHeightsFromRegionWithBilinearSamplers) + { + // This repeats the same test as TerrainHeightQueriesWithBilinearSamplersUseQueryGridToInterpolate + // The difference is that it tests the ProcessHeightsFromList variation. + + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + const float amplitudeMeters = 10.0f; + const float frequencyMeters = 1.0f; + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [amplitudeMeters, frequencyMeters](AZ::Vector3& position, bool& terrainExists) + { + // Our generated height will be X + Y. + float expectedHeight = position.GetX() + position.GetY(); + + // If either X or Y aren't evenly divisible by the query frequency, add a scaled value to our generated height. + // This will show up as an unexpected height "spike" if it gets used in any bilinear filter queries. + float unexpectedVariance = + amplitudeMeters * (fmodf(position.GetX(), frequencyMeters) + fmodf(position.GetY(), frequencyMeters)); + position.SetZ(expectedHeight + unexpectedVariance); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(frequencyMeters); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f); + const AZ::Vector2 stepSize(1.0f); + + const HeightTestRegionPoints testPoints[] = { + { 0, 0, -2.0f, AZ::Vector2(-1.0f, -1.0f) }, + { 1, 0, -1.0f, AZ::Vector2(0.0f, -1.0f) }, + { 0, 1, -1.0f, AZ::Vector2(-1.0f, 0.0f) }, + { 1, 1, 0.0f, AZ::Vector2(0.0f, 0.0f) }, + }; + + auto perPositionCallback = [&testPoints](size_t xIndex, size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + bool found = false; + for (auto& testPoint : testPoints) + { + if (testPoint.m_xIndex == xIndex && testPoint.m_yIndex == yIndex + && testPoint.m_testLocation.GetX() == surfacePoint.m_position.GetX() + && testPoint.m_testLocation.GetY() == surfacePoint.m_position.GetY()) + { + constexpr float epsilon = 0.0001f; + EXPECT_NEAR(surfacePoint.m_position.GetZ(), testPoint.m_expectedHeight, epsilon); + found = true; + break; + } + } + EXPECT_EQ(found, true); + }; + + terrainSystem->ProcessHeightsFromRegion(testRegionBox, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); + } + + TEST_F(TerrainSystemTest, TerrainProcessNormalsFromRegionWithBilinearSamplers) + { + // This repeats the same test as TerrainHeightQueriesWithBilinearSamplersUseQueryGridToInterpolate + // The difference is that it tests the ProcessHeightsFromList variation. + + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + const float amplitudeMeters = 10.0f; + const float frequencyMeters = 1.0f; + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [amplitudeMeters, frequencyMeters](AZ::Vector3& position, bool& terrainExists) + { + // Our generated height will be X + Y. + float expectedHeight = position.GetX() + position.GetY(); + + // If either X or Y aren't evenly divisible by the query frequency, add a scaled value to our generated height. + // This will show up as an unexpected height "spike" if it gets used in any bilinear filter queries. + float unexpectedVariance = + amplitudeMeters * (fmodf(position.GetX(), frequencyMeters) + fmodf(position.GetY(), frequencyMeters)); + position.SetZ(expectedHeight + unexpectedVariance); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(frequencyMeters); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f); + const AZ::Vector2 stepSize(1.0f); + + const NormalTestRegionPoints testPoints[] = { + { 0, 0, AZ::Vector3(-0.5773f, -0.5773f, 0.5773f), AZ::Vector2(-1.0f, -1.0f) }, + { 1, 0, AZ::Vector3(-0.5773f, -0.5773f, 0.5773f), AZ::Vector2(0.0f, -1.0f) }, + { 0, 1, AZ::Vector3(-0.5773f, -0.5773f, 0.5773f), AZ::Vector2(-1.0f, 0.0f) }, + { 1, 1, AZ::Vector3(-0.5773f, -0.5773f, 0.5773f), AZ::Vector2(0.0f, 0.0f) }, + }; + + auto perPositionCallback = [&testPoints](size_t xIndex, size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + bool found = false; + for (auto& testPoint : testPoints) + { + if (testPoint.m_xIndex == xIndex && testPoint.m_yIndex == yIndex + && testPoint.m_testLocation.GetX() == surfacePoint.m_position.GetX() + && testPoint.m_testLocation.GetY() == surfacePoint.m_position.GetY()) + { + constexpr float epsilon = 0.0001f; + EXPECT_NEAR(surfacePoint.m_normal.GetX(), testPoint.m_expectedNormal.GetX(), epsilon); + EXPECT_NEAR(surfacePoint.m_normal.GetY(), testPoint.m_expectedNormal.GetY(), epsilon); + EXPECT_NEAR(surfacePoint.m_normal.GetZ(), testPoint.m_expectedNormal.GetZ(), epsilon); + found = true; + break; + } + } + EXPECT_EQ(found, true); + }; + + terrainSystem->ProcessNormalsFromRegion(testRegionBox, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); + } } // namespace UnitTest From aebf93d8824a8b1d8b8e31d7a808161b21357dd8 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 12 Jan 2022 13:13:52 -0800 Subject: [PATCH 162/272] fixing a typo in docstring Signed-off-by: Scott Murray --- .../editor_python_test_tools/editor_entity_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index bf27ec06e0..c3398406ab 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -264,7 +264,7 @@ class EditorComponent: def disable_component(self): """ Used to disable the component using its id value. - Deprecation warning! Use set_enable(False) instead as this method is in deprecation + Deprecation warning! Use set_enabled(False) instead as this method is in deprecation :return: None """ warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning) From 74e40551957548935201d5a935c5a66c9d520310 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 12 Jan 2022 15:23:06 -0800 Subject: [PATCH 163/272] Fix Prefab instance assets not preloading (#6834) PrefabCatchmentProcessor::ProcessPrefab was no longer updating the ProcessedObjectStore's referenced object list, this change exposes the referenced asset list in the new PrefabDocument API and uses them to update the referenced asset list. Signed-off-by: Nicholas Van Sickle --- .../Prefab/Spawnable/PrefabCatchmentProcessor.cpp | 1 + .../Prefab/Spawnable/PrefabDocument.cpp | 12 +++++++++++- .../Prefab/Spawnable/PrefabDocument.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 40cd52cac8..a5ca034c36 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -64,6 +64,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer)); AZ_Assert(spawnable, "Failed to create a new spawnable."); + object.GetReferencedAssets() = prefab.GetReferencedAssets(); Instance& instance = prefab.GetInstance(); // Resolve entity aliases that store PrefabDOM information to use the spawnable instead. This is done before the entities are // moved from the instance as they'd otherwise can't be found. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp index 04fdea30d2..230c2226cd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.cpp @@ -124,12 +124,22 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return *m_instance; } + AZStd::vector>& PrefabDocument::GetReferencedAssets() + { + return m_referencedAssets; + } + + const AZStd::vector>& PrefabDocument::GetReferencedAssets() const + { + return m_referencedAssets; + } + bool PrefabDocument::ConstructInstanceFromPrefabDom(const PrefabDom& prefab) { using namespace AzToolsFramework::Prefab; m_instance->Reset(); - if (PrefabDomUtils::LoadInstanceFromPrefabDom(*m_instance, prefab, PrefabDomUtils::LoadFlags::AssignRandomEntityId)) + if (PrefabDomUtils::LoadInstanceFromPrefabDom(*m_instance, prefab, m_referencedAssets, PrefabDomUtils::LoadFlags::AssignRandomEntityId)) { return true; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h index 215daf7f71..661dba5edf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabDocument.h @@ -53,12 +53,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AzToolsFramework::Prefab::Instance& GetInstance(); const AzToolsFramework::Prefab::Instance& GetInstance() const; + AZStd::vector>& GetReferencedAssets(); + const AZStd::vector>& GetReferencedAssets() const; + private: bool ConstructInstanceFromPrefabDom(const PrefabDom& prefab); mutable PrefabDom m_dom; AZStd::unique_ptr m_instance; AZStd::string m_name; + AZStd::vector> m_referencedAssets; mutable bool m_isDirty{ false }; }; } // namespace AzToolsFramework::Prefab::PrefabConversionUtils From 4e755cc258645d29cc286e5ec52b623486e1ca0e Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Wed, 12 Jan 2022 16:21:40 -0800 Subject: [PATCH 164/272] Add variable, datum sanity for user added slots Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../ConnectionFilters/DataConnectionFilters.h | 4 ++-- .../DataConnectionComponent.cpp | 4 ++-- .../Slots/Data/DataSlotComponent.cpp | 11 +++++---- .../Components/Slots/Data/DataSlotComponent.h | 4 ++-- .../Components/Slots/Data/DataSlotBus.h | 4 ++-- .../GraphCanvas/Editor/GraphModelBus.h | 9 +++---- .../SlotContextMenuActions.cpp | 10 ++++---- .../GraphModel/Code/Tests/MockGraphCanvas.cpp | 4 ++-- Gems/GraphModel/Code/Tests/MockGraphCanvas.h | 4 ++-- .../Code/Editor/Components/EditorGraph.cpp | 24 ++++++++++--------- .../ScriptCanvas/Components/EditorGraph.h | 8 +++---- .../View/Windows/ScriptCanvasContextMenus.cpp | 2 +- .../Asset/RuntimeAssetHandler.cpp | 8 ++++++- .../Code/Include/ScriptCanvas/Core/Node.cpp | 4 ++-- .../Code/Include/ScriptCanvas/Core/Node.h | 2 +- .../Code/Include/ScriptCanvas/Core/Slot.cpp | 11 +++++---- .../Code/Include/ScriptCanvas/Core/Slot.h | 4 ++-- .../Grammar/AbstractCodeModel.cpp | 10 ++++---- .../GraphVariableManagerComponent.cpp | 2 +- 19 files changed, 70 insertions(+), 59 deletions(-) diff --git a/Gems/GraphCanvas/Code/Include/GraphCanvas/Components/Connections/ConnectionFilters/DataConnectionFilters.h b/Gems/GraphCanvas/Code/Include/GraphCanvas/Components/Connections/ConnectionFilters/DataConnectionFilters.h index c7721e284d..452b6e744a 100644 --- a/Gems/GraphCanvas/Code/Include/GraphCanvas/Components/Connections/ConnectionFilters/DataConnectionFilters.h +++ b/Gems/GraphCanvas/Code/Include/GraphCanvas/Components/Connections/ConnectionFilters/DataConnectionFilters.h @@ -97,7 +97,7 @@ namespace GraphCanvas // Only want to try to convert to references when we have no connections if (!hasConnections) { - DataSlotRequestBus::EventResult(acceptConnection, sourceEndpoint.GetSlotId(), &DataSlotRequests::CanConvertToReference); + DataSlotRequestBus::EventResult(acceptConnection, sourceEndpoint.GetSlotId(), &DataSlotRequests::CanConvertToReference, false); } } else if (targetType == DataSlotType::Value) @@ -115,7 +115,7 @@ namespace GraphCanvas // Only want to try to convert to references when we have no connections if (!hasConnections) { - DataSlotRequestBus::EventResult(acceptConnection, targetEndpoint.GetSlotId(), &DataSlotRequests::CanConvertToReference); + DataSlotRequestBus::EventResult(acceptConnection, targetEndpoint.GetSlotId(), &DataSlotRequests::CanConvertToReference, false); } } else if (sourceType == DataSlotType::Value) diff --git a/Gems/GraphCanvas/Code/Source/Components/Connections/DataConnections/DataConnectionComponent.cpp b/Gems/GraphCanvas/Code/Source/Components/Connections/DataConnections/DataConnectionComponent.cpp index f4ec0bfa1d..46e6f25978 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Connections/DataConnections/DataConnectionComponent.cpp +++ b/Gems/GraphCanvas/Code/Source/Components/Connections/DataConnections/DataConnectionComponent.cpp @@ -92,7 +92,7 @@ namespace GraphCanvas } else if (sourceSlotType == DataSlotType::Reference) { - DataSlotRequestBus::EventResult(converted, GetTargetSlotId(), &DataSlotRequests::ConvertToReference); + DataSlotRequestBus::EventResult(converted, GetTargetSlotId(), &DataSlotRequests::ConvertToReference, false); } } else if (m_dragContext == DragContext::MoveSource) @@ -103,7 +103,7 @@ namespace GraphCanvas } else if (targetSlotType == DataSlotType::Reference) { - DataSlotRequestBus::EventResult(converted, GetSourceSlotId(), &DataSlotRequests::ConvertToReference); + DataSlotRequestBus::EventResult(converted, GetSourceSlotId(), &DataSlotRequests::ConvertToReference, false); } } else if (m_dragContext == DragContext::TryConnection) diff --git a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp index db62b29de5..7eb9187123 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp +++ b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp @@ -294,9 +294,9 @@ namespace GraphCanvas } } - bool DataSlotComponent::ConvertToReference() + bool DataSlotComponent::ConvertToReference(bool isNewSlot) { - if (CanConvertToReference()) + if (CanConvertToReference(isNewSlot)) { AZ::EntityId nodeId = GetNode(); GraphId graphId; @@ -307,7 +307,7 @@ namespace GraphCanvas ScopedGraphUndoBlocker undoBlocker(graphId); bool convertedToReference = false; - GraphModelRequestBus::EventResult(convertedToReference, graphId, &GraphModelRequests::ConvertSlotToReference, Endpoint(nodeId, GetEntityId())); + GraphModelRequestBus::EventResult(convertedToReference, graphId, &GraphModelRequests::ConvertSlotToReference, Endpoint(nodeId, GetEntityId()), isNewSlot); if (convertedToReference) { @@ -326,8 +326,9 @@ namespace GraphCanvas return m_dataSlotType == DataSlotType::Reference; } - bool DataSlotComponent::CanConvertToReference() const + bool DataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot) const { + // #sc_user_slot_variable_ux make sure this can be converted to reference, or created as one bool canToggleReference = false; if (m_canConvertSlotTypes && DataSlotUtils::IsValueDataSlotType(m_dataSlotType) && !HasConnections()) @@ -336,7 +337,7 @@ namespace GraphCanvas GraphId graphId; SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene); - GraphModelRequestBus::EventResult(canToggleReference, graphId, &GraphModelRequests::CanConvertSlotToReference, Endpoint(nodeId, GetEntityId())); + GraphModelRequestBus::EventResult(canToggleReference, graphId, &GraphModelRequests::CanConvertSlotToReference, Endpoint(nodeId, GetEntityId()), isNewSlot); } return canToggleReference; diff --git a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.h b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.h index fb76c2c80e..5bd35d9f34 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.h +++ b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.h @@ -47,8 +47,8 @@ namespace GraphCanvas //// // DataSlotRequestBus - bool ConvertToReference() override; - bool CanConvertToReference() const override; + bool ConvertToReference(bool isNewSlot = false) override; + bool CanConvertToReference(bool isNewSlot = false) const override; bool ConvertToValue() override; bool CanConvertToValue() const override; diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/Slots/Data/DataSlotBus.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/Slots/Data/DataSlotBus.h index 3d007dda91..fbdae8a971 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/Slots/Data/DataSlotBus.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/Slots/Data/DataSlotBus.h @@ -70,8 +70,8 @@ namespace GraphCanvas static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; using BusIdType = AZ::EntityId; - virtual bool ConvertToReference() = 0; - virtual bool CanConvertToReference() const = 0; + virtual bool ConvertToReference(bool isNewSlot = false) = 0; + virtual bool CanConvertToReference(bool isNewSlot = false) const = 0; virtual bool ConvertToValue() = 0; virtual bool CanConvertToValue() const = 0; diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/GraphModelBus.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/GraphModelBus.h index 769cdb2a10..23aa612dd5 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/GraphModelBus.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/GraphModelBus.h @@ -125,12 +125,12 @@ namespace GraphCanvas return false; } - virtual bool ConvertSlotToReference([[maybe_unused]] const Endpoint& endpoint) + virtual bool ConvertSlotToReference([[maybe_unused]] const Endpoint& endpoint, [[maybe_unused]] bool isNewSlot) { return false; } - virtual bool CanConvertSlotToReference([[maybe_unused]] const Endpoint& endpoint) + virtual bool CanConvertSlotToReference([[maybe_unused]] const Endpoint& endpoint, [[maybe_unused]] bool isNewSlot) { return false; } @@ -145,12 +145,13 @@ namespace GraphCanvas return false; } - virtual bool CanPromoteToVariable([[maybe_unused]] const Endpoint& endpoint) const + virtual bool CanPromoteToVariable([[maybe_unused]] const Endpoint& endpoint, [[maybe_unused]] bool isNewSlot = false) const { return false; } - virtual bool PromoteToVariableAction([[maybe_unused]] const Endpoint& endpoint) + virtual bool PromoteToVariableAction([[maybe_unused]] const Endpoint& endpoint + , [[maybe_unused]] bool isNewSlot) { return false; } diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SlotMenuActions/SlotContextMenuActions.cpp b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SlotMenuActions/SlotContextMenuActions.cpp index a255c97120..38e97f90cc 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SlotMenuActions/SlotContextMenuActions.cpp +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/EditorContextMenu/ContextMenuActions/SlotMenuActions/SlotContextMenuActions.cpp @@ -258,7 +258,7 @@ namespace GraphCanvas if (DataSlotUtils::IsValueDataSlotType(dataSlotType)) { setText("Convert to Reference"); - DataSlotRequestBus::EventResult(canToggleState, targetId, &DataSlotRequests::CanConvertToReference); + DataSlotRequestBus::EventResult(canToggleState, targetId, &DataSlotRequests::CanConvertToReference, false); } else { @@ -291,7 +291,7 @@ namespace GraphCanvas if (DataSlotUtils::IsValueDataSlotType(dataSlotType)) { - DataSlotRequestBus::EventResult(toggledState, targetId, &DataSlotRequests::ConvertToReference); + DataSlotRequestBus::EventResult(toggledState, targetId, &DataSlotRequests::ConvertToReference, false); } else { @@ -345,14 +345,14 @@ namespace GraphCanvas if (DataSlotUtils::IsValueDataSlotType(dataSlotType)) { - DataSlotRequestBus::EventResult(enableAction, targetId, &DataSlotRequests::CanConvertToReference); + DataSlotRequestBus::EventResult(enableAction, targetId, &DataSlotRequests::CanConvertToReference, false); if (enableAction) { Endpoint endpoint; SlotRequestBus::EventResult(endpoint, targetId, &SlotRequests::GetEndpoint); - GraphModelRequestBus::EventResult(enableAction, graphId, &GraphModelRequests::CanPromoteToVariable, endpoint); + GraphModelRequestBus::EventResult(enableAction, graphId, &GraphModelRequests::CanPromoteToVariable, endpoint, false); } } } @@ -371,7 +371,7 @@ namespace GraphCanvas SlotRequestBus::EventResult(endpoint, targetId, &SlotRequests::GetEndpoint); bool promotedElement = false; - GraphModelRequestBus::EventResult(promotedElement, graphId, &GraphModelRequests::PromoteToVariableAction, endpoint); + GraphModelRequestBus::EventResult(promotedElement, graphId, &GraphModelRequests::PromoteToVariableAction, endpoint, false); if (promotedElement) { diff --git a/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp b/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp index 91a25d6a30..525386a1a3 100644 --- a/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp +++ b/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp @@ -94,12 +94,12 @@ namespace MockGraphCanvasServices GraphCanvas::DataSlotRequestBus::Handler::BusDisconnect(); } - bool MockDataSlotComponent::ConvertToReference() + bool MockDataSlotComponent::ConvertToReference([[maybe_unused]] bool isNewSlot = false) { return false; } - bool MockDataSlotComponent::CanConvertToReference() const + bool MockDataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot = false) const { return false; } diff --git a/Gems/GraphModel/Code/Tests/MockGraphCanvas.h b/Gems/GraphModel/Code/Tests/MockGraphCanvas.h index c7865e769e..00bd80aa02 100644 --- a/Gems/GraphModel/Code/Tests/MockGraphCanvas.h +++ b/Gems/GraphModel/Code/Tests/MockGraphCanvas.h @@ -72,8 +72,8 @@ namespace MockGraphCanvasServices void Deactivate() override; // GraphCanvas::DataSlotRequestBus overrides ... - bool ConvertToReference() override; - bool CanConvertToReference() const override; + bool ConvertToReference(bool isNewSlot = false) override; + bool CanConvertToReference(bool isNewSlot = false) const override; bool ConvertToValue() override; bool CanConvertToValue() const override; bool IsUserSlot() const override; diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index d713bc09a6..342273cb2e 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -667,7 +667,8 @@ namespace ScriptCanvasEditor } // Now that the slot has a valid type/name, we can actually promote it to a variable - if (PromoteToVariableAction(endpoint) /*&& slot->IsVariableReference()*/) + // #sc_user_slot_variable_ux add a value indicating that the slot is new + if (PromoteToVariableAction(endpoint, true)) { ScriptCanvas::GraphVariable* variable = slot->GetVariable(); @@ -2081,20 +2082,20 @@ namespace ScriptCanvasEditor return false; } - bool Graph::ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) + bool Graph::ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint, bool isNewSlot) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); if (canvasNode) { - return canvasNode->ConvertSlotToReference(scEndpoint.GetSlotId()); + return canvasNode->ConvertSlotToReference(scEndpoint.GetSlotId(), isNewSlot); } return false; } - bool Graph::CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) + bool Graph::CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint, bool isNewSlot) { ScriptCanvas::Endpoint scEndpoint = ConvertToScriptCanvasEndpoint(endpoint); ScriptCanvas::Node* canvasNode = FindNode(scEndpoint.GetNodeId()); @@ -2104,7 +2105,7 @@ namespace ScriptCanvasEditor ScriptCanvas::Slot* slot = canvasNode->GetSlot(scEndpoint.GetSlotId()); if (slot) { - return slot->CanConvertToReference(); + return slot->CanConvertToReference(isNewSlot); } } @@ -2170,7 +2171,7 @@ namespace ScriptCanvasEditor return handledEvent; } - bool Graph::CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint) const + bool Graph::CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint, [[maybe_unused]] bool isNewSlot) const { ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(endpoint); auto activeSlot = FindSlot(scriptCanvasEndpoint); @@ -2189,8 +2190,9 @@ namespace ScriptCanvasEditor return false; } - bool Graph::PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint) + bool Graph::PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint, bool isNewSlot) { + // #sc_user_slot_variable_ux make the fix here...rework is user added or something ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(endpoint); auto activeNode = FindNode(scriptCanvasEndpoint.GetNodeId()); @@ -2282,12 +2284,12 @@ namespace ScriptCanvasEditor AZ::Outcome addOutcome; - // #functions2 slot<->variable re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion) + // #sc_user_slot_variable_ux re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion) ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum, true); if (addOutcome.IsSuccess()) { - GraphCanvas::DataSlotRequestBus::Event(endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference); + GraphCanvas::DataSlotRequestBus::Event(endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference, isNewSlot); activeSlot->SetVariableReference(addOutcome.GetValue()); @@ -2319,7 +2321,7 @@ namespace ScriptCanvasEditor { if (!targetSlot->IsVariableReference()) { - GraphCanvas::DataSlotRequestBus::Event(referenceTarget.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference); + GraphCanvas::DataSlotRequestBus::Event(referenceTarget.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference, false); } if (targetSlot->IsVariableReference()) @@ -2884,7 +2886,7 @@ namespace ScriptCanvasEditor for (auto graphCanvasEndpoint : referencableEndpoints) { - GraphCanvas::DataSlotRequestBus::Event(graphCanvasEndpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference); + GraphCanvas::DataSlotRequestBus::Event(graphCanvasEndpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference, false); ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(graphCanvasEndpoint); diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h index 9157aaeac9..ba7ff6abaf 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h @@ -175,12 +175,12 @@ namespace ScriptCanvasEditor void RemoveSlot(const GraphCanvas::Endpoint& endpoint) override; bool IsSlotRemovable(const GraphCanvas::Endpoint& endpoint) const override; - bool ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) override; - bool CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint) override; + bool ConvertSlotToReference(const GraphCanvas::Endpoint& endpoint, bool isNewSlot = false) override; + bool CanConvertSlotToReference(const GraphCanvas::Endpoint& endpoint, bool isNewSlot = false) override; GraphCanvas::CanHandleMimeEventOutcome CanHandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) override; bool HandleReferenceMimeEvent(const GraphCanvas::Endpoint& endpoint, const QMimeData* mimeData) override; - bool CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint) const override; - bool PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint) override; + bool CanPromoteToVariable(const GraphCanvas::Endpoint& endpoint, bool isNewSlot = false) const override; + bool PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint, bool isNewSlot = false) override; bool SynchronizeReferences(const GraphCanvas::Endpoint& sourceEndpoint, const GraphCanvas::Endpoint& targetEndpoint) override; bool ConvertSlotToValue(const GraphCanvas::Endpoint& endpoint) override; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasContextMenus.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasContextMenus.cpp index 6402a24b3a..662cec7195 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasContextMenus.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasContextMenus.cpp @@ -516,7 +516,7 @@ namespace ScriptCanvasEditor GraphCanvas::SlotRequestBus::EventResult(endpoint, slotId2, &GraphCanvas::SlotRequests::GetEndpoint); bool promotedElement = false; - GraphCanvas::GraphModelRequestBus::EventResult(promotedElement, graphId2, &GraphCanvas::GraphModelRequests::PromoteToVariableAction, endpoint); + GraphCanvas::GraphModelRequestBus::EventResult(promotedElement, graphId2, &GraphCanvas::GraphModelRequests::PromoteToVariableAction, endpoint, false); if (promotedElement) { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp index 0b94fb370a..a18caf4b87 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp @@ -100,12 +100,18 @@ namespace ScriptCanvas { RuntimeAsset* runtimeAsset = asset.GetAs(); AZ_Assert(runtimeAsset, "This should be a Script Canvas runtime asset, as this is the only type we process!"); + if (runtimeAsset && m_serializeContext) { stream->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*stream, runtimeAsset->m_runtimeData, m_serializeContext, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB)); + const bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*stream, runtimeAsset->m_runtimeData + , m_serializeContext, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB)); + AZ_Error("ScriptCanvas", loadSuccess, "ScriptCanvas failed to load runtime asset: %s - %s" + , asset.GetHint().c_str(), asset.GetId().ToString().c_str()); + return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error; } + return AZ::Data::AssetHandler::LoadResult::Error; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index c4143e7295..6cf9da1510 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -2577,11 +2577,11 @@ namespace ScriptCanvas } } - bool Node::ConvertSlotToReference(const SlotId& slotId) + bool Node::ConvertSlotToReference(const SlotId& slotId, bool isNewSlot) { Slot* slot = GetSlot(slotId); - if (slot && slot->ConvertToReference()) + if (slot && slot->ConvertToReference(isNewSlot)) { InitializeVariableReference((*slot), {}); return true; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index 97916c8af6..f8b4ca7264 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -498,7 +498,7 @@ namespace ScriptCanvas void SanityCheckDynamicDisplay(); void SanityCheckDynamicDisplay(ExploredDynamicGroupCache& exploredGroupCache); - bool ConvertSlotToReference(const SlotId& slotId); + bool ConvertSlotToReference(const SlotId& slotId, bool isNewSlot = false); bool ConvertSlotToValue(const SlotId& slotId); NamedEndpoint CreateNamedEndpoint(SlotId slotId) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp index 44d2367156..6aef61b12f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp @@ -460,14 +460,15 @@ namespace ScriptCanvas && GetDataType() != Data::Type::BehaviorContextObject(GraphScopedVariableId::TYPEINFO_Uuid()); } - bool Slot::CanConvertToReference() const - { - return !m_isUserAdded && CanConvertTypes() && !m_isVariableReference && !m_node->HasConnectedNodes((*this)); + bool Slot::CanConvertToReference(bool isNewSlot) const + { + // #sc_user_slot_variable_ux make sure this can be converted to reference, or created as one + return (!m_isUserAdded || isNewSlot) && CanConvertTypes() && !m_isVariableReference && !m_node->HasConnectedNodes((*this)); } - bool Slot::ConvertToReference() + bool Slot::ConvertToReference(bool isNewSlot) { - if (CanConvertToReference()) + if (CanConvertToReference(isNewSlot)) { m_isVariableReference = true; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h index b182af7c67..5649c3e34c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h @@ -147,8 +147,8 @@ namespace ScriptCanvas bool CanConvertToValue() const; bool ConvertToValue(); - bool CanConvertToReference() const; - bool ConvertToReference(); + bool CanConvertToReference(bool isNewSlot = false) const; + bool ConvertToReference(bool isNewSlot = false); void SetVariableReference(const VariableId& variableId); const VariableId& GetVariableReference() const; GraphVariable* GetVariable() const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 829a1098dc..299718fd0f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -237,7 +237,7 @@ namespace ScriptCanvas if (auto datum = variablePair.second.GetDatum()) { - // #functions2 slot<->variable consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering + // #sc_user_slot_variable_ux consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering m_sourceVariableByDatum.insert(AZStd::make_pair(datum, &variablePair.second)); } @@ -248,7 +248,7 @@ namespace ScriptCanvas auto datum = sourceVariable->GetDatum(); AZ_Assert(datum != nullptr, "the datum must be valid"); - // #functions2 slot<->variable check to verify if it is a member variable + // #sc_user_slot_variable_ux check to verify if it is a member variable auto variable = sourceVariable->GetScope() == VariableFlags::Scope::Graph ? AddMemberVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId()) : AddVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId()); @@ -1671,7 +1671,7 @@ namespace ScriptCanvas if (returnValue.second->m_source->m_sourceSlotId == slot->GetId()) { - // #functions2 slot<->variable determine if the root or the function call should be passed in here...the slot/node lead to the user call on the thread, but it may not even be created yet + // #sc_user_slot_variable_ux determine if the root or the function call should be passed in here...the slot/node lead to the user call on the thread, but it may not even be created yet return AZStd::make_pair(root, returnValue.second->m_source); } } @@ -4644,7 +4644,7 @@ namespace ScriptCanvas void AbstractCodeModel::ParseNodelingVariables(const Node& node, NodelingType nodelingType) { - // #functions2 slot<->variable adjust once datums are more coordinated + // #sc_user_slot_variable_ux adjust once datums are more coordinated auto createVariablesSlots = [&](AZStd::unordered_map& variablesBySlots, const AZStd::vector& slots, bool slotHasDatum) { for (const auto& slot : slots) @@ -4660,7 +4660,7 @@ namespace ScriptCanvas return; } - // #functions2 slot<->variable consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering + // #sc_user_slot_variable_ux consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering // auto iter = m_sourceVariableByDatum.find(variableDatum); // if (iter == m_sourceVariableByDatum.end()) // { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp index 58e8be0c37..81383bf747 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp @@ -220,7 +220,7 @@ namespace ScriptCanvas return AZ::Success(newId); } - // #functions2 slot<->variable add this to the graph, using the old datum + // #sc_user_slot_variable_ux add this to the graph, using the old datum AZ::Outcome GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value, bool functionScope) { if (FindVariable(name)) From 073994e8e75d1ec3ffafe84a16d1613962b42b34 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 12 Jan 2022 17:34:34 -0800 Subject: [PATCH 165/272] Remove quotes around list (#6864) Signed-off-by: amzn-sj --- cmake/Platform/Mac/InstallUtils_mac.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Mac/InstallUtils_mac.cmake.in b/cmake/Platform/Mac/InstallUtils_mac.cmake.in index 3db9903e48..9be6338752 100644 --- a/cmake/Platform/Mac/InstallUtils_mac.cmake.in +++ b/cmake/Platform/Mac/InstallUtils_mac.cmake.in @@ -43,7 +43,7 @@ function(fixup_python_framework framework_path) file(GLOB_RECURSE exe_file_list "${framework_path}/**/*.exe") if(exe_file_list) - file(REMOVE_RECURSE "${exe_file_list}") + file(REMOVE_RECURSE ${exe_file_list}) endif() execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink include/python@LY_PYTHON_VERSION_MAJOR_MINOR@m Headers WORKING_DIRECTORY "${framework_path}/Versions/@LY_PYTHON_VERSION_MAJOR_MINOR@" From e224fc2ee5ec2a12e75a10acae268b7b38ae3a32 Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Wed, 12 Jan 2022 22:39:56 -0800 Subject: [PATCH 166/272] Bugfix - ViewportInteractionImp connected to the wrong id in RenderViewportWidget (#6867) Signed-off-by: rhhong --- .../Code/Source/Viewport/RenderViewportWidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 505ff70122..b15cf53427 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -68,6 +68,7 @@ namespace AtomToolsFramework { return false; } + const AzFramework::ViewportId newId = m_viewportContext->GetId(); SetControllerList(AZStd::make_shared()); @@ -78,14 +79,14 @@ namespace AtomToolsFramework m_viewportInteractionImpl = AZStd::make_unique(m_defaultCamera); m_viewportInteractionImpl->m_deviceScalingFactorFn = [this] { return aznumeric_cast(devicePixelRatioF()); }; m_viewportInteractionImpl->m_screenSizeFn = [this] { return AzFramework::ScreenSize(width(), height()); }; - m_viewportInteractionImpl->Connect(id); + m_viewportInteractionImpl->Connect(newId); AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Handler::BusConnect(GetId()); AzFramework::InputChannelEventListener::Connect(); AZ::TickBus::Handler::BusConnect(); AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle); - m_inputChannelMapper = new AzToolsFramework::QtEventToAzInputMapper(this, id); + m_inputChannelMapper = new AzToolsFramework::QtEventToAzInputMapper(this, newId); // Forward input events to our controller list. QObject::connect(m_inputChannelMapper, &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, this, From ff0df4b8b6e66286c12391522c4814cc7f8864f7 Mon Sep 17 00:00:00 2001 From: Andre Mitchell <47983418+BytesOfPiDev@users.noreply.github.com> Date: Thu, 13 Jan 2022 03:36:19 -0500 Subject: [PATCH 167/272] Update behavior reflection of EMotionFX's MotionEvent to use nullptr instead of empty lambdas. (#6617) Signed-off-by: Andre Mitchell --- .../Integration/System/SystemComponent.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp index 15037793f1..08607c330d 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp @@ -400,17 +400,16 @@ namespace EMotionFX behaviorContext->EBus("SystemNotificationBus") ; - // In order for a property to be displayed in ScriptCanvas. Both a setter and a getter are necessary(both must be non-null). - // This is being worked on in dragon branch, once this is complete the dummy lambda functions can be removed. + // In order for a property to be displayed in ScriptCanvas. behaviorContext->Class("MotionEvent") - ->Property("entityId", BehaviorValueGetter(&MotionEvent::m_entityId), [](MotionEvent*, const AZ::EntityId&) {}) - ->Property("parameter", BehaviorValueGetter(&MotionEvent::m_parameter), [](MotionEvent*, const char*) {}) - ->Property("eventType", BehaviorValueGetter(&MotionEvent::m_eventType), [](MotionEvent*, const AZ::u32&) {}) - ->Property("eventTypeName", BehaviorValueGetter(&MotionEvent::m_eventTypeName), [](MotionEvent*, const char*) {}) - ->Property("time", BehaviorValueGetter(&MotionEvent::m_time), [](MotionEvent*, const float&) {}) - ->Property("globalWeight", BehaviorValueGetter(&MotionEvent::m_globalWeight), [](MotionEvent*, const float&) {}) - ->Property("localWeight", BehaviorValueGetter(&MotionEvent::m_localWeight), [](MotionEvent*, const float&) {}) - ->Property("isEventStart", BehaviorValueGetter(&MotionEvent::m_isEventStart), [](MotionEvent*, const bool&) {}) + ->Property("entityId", BehaviorValueGetter(&MotionEvent::m_entityId), nullptr) + ->Property("parameter", BehaviorValueGetter(&MotionEvent::m_parameter), nullptr) + ->Property("eventType", BehaviorValueGetter(&MotionEvent::m_eventType), nullptr) + ->Property("eventTypeName", BehaviorValueGetter(&MotionEvent::m_eventTypeName), nullptr) + ->Property("time", BehaviorValueGetter(&MotionEvent::m_time), nullptr) + ->Property("globalWeight", BehaviorValueGetter(&MotionEvent::m_globalWeight), nullptr) + ->Property("localWeight", BehaviorValueGetter(&MotionEvent::m_localWeight), nullptr) + ->Property("isEventStart", BehaviorValueGetter(&MotionEvent::m_isEventStart), nullptr) ; behaviorContext->EBus("ActorNotificationBus") From 6d1a2382e872c74cf51e34127ab4e9573305b1dd Mon Sep 17 00:00:00 2001 From: tjmgd <92784061+tjmgd@users.noreply.github.com> Date: Thu, 13 Jan 2022 13:56:38 +0000 Subject: [PATCH 168/272] Bug hide window (#5939) * [lyn3736] adding init files to module paths (#5111) * fixing class names in PYI files Signed-off-by: jackalbe <23512001+jackalbe@users.noreply.github.com> Signed-off-by: T.J. McGrath-Daly * Fixed crash when typing asset name and clicking browse (#5495) Signed-off-by: T.J. McGrath-Daly * Fixed bug involving inappropriate window Signed-off-by: T.J. McGrath-Daly Co-authored-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com> Co-authored-by: AMZN-AlexOteiza <82234181+AMZN-AlexOteiza@users.noreply.github.com> --- Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp b/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp index d827f657b8..f8414e25e4 100644 --- a/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp +++ b/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp @@ -33,6 +33,7 @@ namespace AudioControls { setupUi(this); + m_connectionPropertiesFrame->setHidden(true); m_connectionList->viewport()->installEventFilter(this); m_connectionList->installEventFilter(this); From fed1278fe64e8a435b1c19ba8092b18a98fa9eb1 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Thu, 13 Jan 2022 08:56:24 -0600 Subject: [PATCH 169/272] AP: product dependency optimization (#6619) * Initial pass at optimizing product path dependency resolution Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add version of StripAssetPlatform that doesn't allocate or copy strings. Re-add missing test and fix up compile errors. Add benchmark test Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Change UpdateProductDependencies to directly call s_InsertProductDependencyQuery.BindAndStep Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add test for same filename on multiple platforms Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Rework search logic to keep track of the source of a search path (source vs product) and keep track of which search matches which dependency to avoid doing another search through every product later on Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Clean up code, expand test Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix paths not being lowercased by SanitizeForDatabase. Fix UpdateProductDependencies not updating existing dependencies Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add test for duplicate dependency matches. Fix saving duplicates Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Clean up code Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Separate test into test and benchmark versions Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Cleanup include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix includes, switch hardcoded job manager setup to use JobManagerComponent instead Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Replaced wildcard_match with PathView::Match. Changed StripAssetPlatformNoCopy to use TokenizeNext. Removed Environment Create/Destroy calls. Made ScopedAllocatorFixture a base class of ScopedAllocatorSetupFixture Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add AZ Environment create/destroy on AP test environment Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add missing asserts on database functions Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix incorrect usage of StripAssetPlatformNoCopy Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix source/product dependency type being ignored. Removed need for unordered_set for list of resolved dependencies. Updated unit tests Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Better variable names Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Remove testing code Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix missing includes and namespaces Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../AzCore/AzCore/UnitTest/TestTypes.h | 40 +- .../assetprocessor_test_files.cmake | 1 + .../native/AssetDatabase/AssetDatabase.cpp | 84 ++-- .../native/AssetManager/AssetCatalog.cpp | 4 +- .../AssetManager/PathDependencyManager.cpp | 187 +++++---- .../AssetManager/PathDependencyManager.h | 23 +- .../AssetManager/assetProcessorManager.cpp | 138 ++++--- .../native/tests/BaseAssetProcessorTest.h | 2 + .../tests/PathDependencyManagerTests.cpp | 362 ++++++++++++++++-- .../AssetProcessorManagerTest.cpp | 79 +++- .../assetmanager/AssetProcessorManagerTest.h | 11 +- .../utilities/PlatformConfiguration.cpp | 14 +- .../native/utilities/assetUtils.cpp | 28 +- .../native/utilities/assetUtils.h | 6 +- 14 files changed, 742 insertions(+), 237 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h index afa6898944..0b1d7caefe 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h @@ -71,18 +71,35 @@ namespace UnitTest }; /** - * RAII wrapper of AllocatorBase. - * The benefit of using this wrapper instead of AllocatorsTestFixture is that SetUp/TearDown of the allocator is managed - * on construction/destruction, allowing member variables of derived classes to exist as value (and do heap allocation). - */ - class ScopedAllocatorSetupFixture - : public ::testing::Test - , AllocatorsBase + * RAII wrapper of AllocatorBase. + * The benefit of using this wrapper instead of AllocatorsTestFixture is that SetUp/TearDown of the allocator is managed + * on construction/destruction, allowing member variables of derived classes to exist as value (and do heap allocation). + */ + class ScopedAllocatorFixture : AllocatorsBase { public: - ScopedAllocatorSetupFixture() { SetupAllocator(); } - explicit ScopedAllocatorSetupFixture(const AZ::SystemAllocator::Descriptor& allocatorDesc) { SetupAllocator(allocatorDesc); } - ~ScopedAllocatorSetupFixture() { TeardownAllocator(); } + ScopedAllocatorFixture() + { + SetupAllocator(); + } + explicit ScopedAllocatorFixture(const AZ::SystemAllocator::Descriptor& allocatorDesc) + { + SetupAllocator(allocatorDesc); + } + ~ScopedAllocatorFixture() override + { + TeardownAllocator(); + } + }; + + // Like ScopedAllocatorFixture, but includes the Test base class + class ScopedAllocatorSetupFixture + : public ::testing::Test + , public ScopedAllocatorFixture + { + public: + ScopedAllocatorSetupFixture() = default; + explicit ScopedAllocatorSetupFixture(const AZ::SystemAllocator::Descriptor& allocatorDesc) : ScopedAllocatorFixture(allocatorDesc){} }; /** @@ -114,6 +131,7 @@ namespace UnitTest using AllocatorsFixture = AllocatorsTestFixture; #if defined(HAVE_BENCHMARK) + /** * Helper class to handle the boiler plate of setting up a benchmark fixture that uses the system allocators * If you wish to do additional setup and tear down be sure to call the base class SetUp first and TearDown @@ -218,7 +236,7 @@ namespace UnitTest static constexpr bool sHasPadding = size < alignment; AZStd::enable_if mPadding; }; - + template int CreationCounter::s_count = 0; template diff --git a/Code/Tools/AssetProcessor/assetprocessor_test_files.cmake b/Code/Tools/AssetProcessor/assetprocessor_test_files.cmake index 2c4c53642c..a7a46ad62c 100644 --- a/Code/Tools/AssetProcessor/assetprocessor_test_files.cmake +++ b/Code/Tools/AssetProcessor/assetprocessor_test_files.cmake @@ -48,6 +48,7 @@ set(FILES native/tests/InternalBuilders/SettingsRegistryBuilderTests.cpp native/tests/MissingDependencyScannerTests.cpp native/tests/SourceFileRelocatorTests.cpp + native/tests/PathDependencyManagerTests.cpp native/tests/AssetProcessorMessagesTests.cpp native/unittests/AssetProcessingStateDataUnitTests.cpp native/unittests/AssetProcessingStateDataUnitTests.h diff --git a/Code/Tools/AssetProcessor/native/AssetDatabase/AssetDatabase.cpp b/Code/Tools/AssetProcessor/native/AssetDatabase/AssetDatabase.cpp index cf33e559ac..5edf4e1d53 100644 --- a/Code/Tools/AssetProcessor/native/AssetDatabase/AssetDatabase.cpp +++ b/Code/Tools/AssetProcessor/native/AssetDatabase/AssetDatabase.cpp @@ -172,7 +172,7 @@ namespace AssetProcessor static const char* CREATEINDEX_BUILDERGUID_SOURCE_SOURCEDEPENDENCY_STATEMENT = "CREATE INDEX IF NOT EXISTS BuilderGuid_Source_SourceDependency ON SourceDependency (BuilderGuid, Source);"; static const char* CREATEINDEX_TYPEOFDEPENDENCY_SOURCEDEPENDENCY = "AssetProcessor::CreateIndexTypeOfDependency_SourceDependency"; - static const char* CREATEINDEX_TYPEOFDEPENDENCY_SOURCEDEPENDENCY_STATEMENT = + static const char* CREATEINDEX_TYPEOFDEPENDENCY_SOURCEDEPENDENCY_STATEMENT = "CREATE INDEX IF NOT EXISTS TypeOfDependency_SourceDependency ON SourceDependency (TypeOfDependency);"; static const char* CREATEINDEX_SCANFOLDERS_SOURCES_SCANFOLDER = "AssetProcesser::CreateIndexScanFoldersSourcesScanFolder"; @@ -611,7 +611,7 @@ namespace AssetProcessor SqlParam(":missingDependencyString"), SqlParam(":lastScanTime"), SqlParam(":scanTimeSecondsSinceEpoch")); - + static const auto s_DeleteMissingProductDependencyByProductIdQuery = MakeSqlQuery( DELETE_MISSING_PRODUCT_DEPENDENCY_BY_PRODUCTID, @@ -643,7 +643,7 @@ namespace AssetProcessor SqlParam(":analysisFingerprint")); static const char* INSERT_COLUMN_ANALYSISFINGERPRINT = "AssetProcessor::AddColumnAnalysisFingerprint"; - static const char* INSERT_COLUMN_ANALYSISFINGERPRINT_STATEMENT = + static const char* INSERT_COLUMN_ANALYSISFINGERPRINT_STATEMENT = "ALTER TABLE Sources " "ADD AnalysisFingerprint TEXT NOT NULL collate nocase default('');"; @@ -653,7 +653,7 @@ namespace AssetProcessor "ADD TypeOfDependency INTEGER NOT NULL DEFAULT 0;"; static const char* INSERT_COLUMN_FILE_MODTIME = "AssetProcessor::AddFiles_ModTime"; - static const char* INSERT_COLUMN_FILE_MODTIME_STATEMENT = + static const char* INSERT_COLUMN_FILE_MODTIME_STATEMENT = "ALTER TABLE Files " "ADD ModTime INTEGER NOT NULL DEFAULT 0;"; @@ -673,7 +673,7 @@ namespace AssetProcessor "ADD UnresolvedDependencyType INTEGER NOT NULL DEFAULT 0;"; static const char* INSERT_COLUMN_PRODUCTDEPENDENCY_PLATFORM = "AssetProcessor::AddProductDependency_Platform"; - static const char* INSERT_COLUMN_PRODUCTDEPENDENCY_PLATFORM_STATEMENT = + static const char* INSERT_COLUMN_PRODUCTDEPENDENCY_PLATFORM_STATEMENT = "ALTER TABLE ProductDependencies " "ADD Platform TEXT NOT NULL collate nocase default('');"; @@ -721,7 +721,7 @@ namespace AssetProcessor SqlParam(":isfolder"), SqlParam(":modtime"), SqlParam(":hash")); - + static const char* UPDATE_FILE = "AssetProcessor::UpdateFile"; static const char* UPDATE_FILE_STATEMENT = "UPDATE Files SET " @@ -961,7 +961,7 @@ namespace AssetProcessor AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Upgraded Asset Database to version %i (AddedTypeOfDependencyIndex)\n", foundVersion) } } - + if (foundVersion == AssetDatabase::DatabaseVersion::AddedTypeOfDependencyIndex) { if (m_databaseConnection->ExecuteOneOffStatement(INSERT_COLUMN_PRODUCTDEPENDENCY_PLATFORM)) @@ -1178,7 +1178,7 @@ namespace AssetProcessor AddStatement(m_databaseConnection, s_InsertJobQuery); AddStatement(m_databaseConnection, s_UpdateJobQuery); AddStatement(m_databaseConnection, s_DeleteJobQuery); - + // --------------------------------------------------------------------------------------------- // Builder Info Table // --------------------------------------------------------------------------------------------- @@ -1207,7 +1207,7 @@ namespace AssetProcessor m_databaseConnection->AddStatement(CREATE_SOURCE_DEPENDENCY_TABLE, CREATE_SOURCE_DEPENDENCY_TABLE_STATEMENT); m_databaseConnection->AddStatement(INSERT_COLUMN_SOURCEDEPENDENCY_TYPEOFDEPENDENCY, INSERT_COLUMN_SOURCEDEPENDENCY_TYPEOFDEPENDENCY_STATEMENT); m_databaseConnection->AddStatement(INSERT_COLUMNS_SOURCEDEPENDENCY_FROM_ASSETID, INSERT_COLUMNS_SOURCEDEPENDENCY_FROM_ASSETID_STATEMENT); - + m_createStatements.push_back(CREATE_SOURCE_DEPENDENCY_TABLE); AddStatement(m_databaseConnection, s_InsertSourceDependencyQuery); @@ -1242,7 +1242,7 @@ namespace AssetProcessor AddStatement(m_databaseConnection, s_InsertProductDependencyQuery); AddStatement(m_databaseConnection, s_UpdateProductDependencyQuery); AddStatement(m_databaseConnection, s_DeleteProductDependencyByProductIdQuery); - + // --------------------------------------------------------------------------------------------- // Missing Product Dependency table // --------------------------------------------------------------------------------------------- @@ -1253,7 +1253,7 @@ namespace AssetProcessor AddStatement(m_databaseConnection, s_InsertMissingProductDependencyQuery); AddStatement(m_databaseConnection, s_UpdateMissingProductDependencyQuery); AddStatement(m_databaseConnection, s_DeleteMissingProductDependencyByProductIdQuery); - + // --------------------------------------------------------------------------------------------- // Files table // --------------------------------------------------------------------------------------------- @@ -1344,7 +1344,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetScanFolderByScanFolderID(AZ::s64 scanfolderID, ScanFolderDatabaseEntry& entry) { bool found = false; - QueryScanFolderByScanFolderID( scanfolderID, + QueryScanFolderByScanFolderID( scanfolderID, [&](ScanFolderDatabaseEntry& scanFolderEntry) { entry = scanFolderEntry; @@ -1357,7 +1357,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetScanFolderBySourceID(AZ::s64 sourceID, ScanFolderDatabaseEntry& entry) { bool found = false; - QueryScanFolderBySourceID( sourceID, + QueryScanFolderBySourceID( sourceID, [&](ScanFolderDatabaseEntry& scanFolderEntry) { entry = scanFolderEntry; @@ -1370,7 +1370,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetScanFolderByJobID(AZ::s64 jobID, ScanFolderDatabaseEntry& entry) { bool found = false; - QueryScanFolderByJobID( jobID, + QueryScanFolderByJobID( jobID, [&](ScanFolderDatabaseEntry& scanFolderEntry) { entry = scanFolderEntry; @@ -1383,7 +1383,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetScanFolderByProductID(AZ::s64 productID, ScanFolderDatabaseEntry& entry) { bool found = false; - QueryScanFolderByProductID( productID, + QueryScanFolderByProductID( productID, [&](ScanFolderDatabaseEntry& scanFolderEntry) { entry = scanFolderEntry; @@ -2105,7 +2105,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetProductsLikeProductName(QString likeProductName, LikeType likeType, ProductDatabaseEntryContainer& container, AZ::Uuid builderGuid, QString jobKey, QString platform, JobStatus status) { bool found = false; - + if (likeProductName.isEmpty()) { return false; @@ -2198,7 +2198,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetProductByJobIDSubId(AZ::s64 jobID, AZ::u32 subID, AzToolsFramework::AssetDatabase::ProductDatabaseEntry& result) { bool found = false; - QueryProductByJobIDSubID(jobID, subID, + QueryProductByJobIDSubID(jobID, subID, [&](ProductDatabaseEntry& resultFromDB) { found = true; @@ -2312,13 +2312,19 @@ namespace AssetProcessor { return false; } - - bool succeeded = true; + + ScopedTransaction transaction(m_databaseConnection); + for (auto& entry : container) { - succeeded &= SetProduct(entry); + if(!SetProduct(entry)) + { + return false; + } } - return succeeded; + + transaction.Commit(); + return true; } //! Clear the products for a given source. This removes the entry entirely, not just sets it to empty. @@ -2407,7 +2413,7 @@ namespace AssetProcessor if(!platform.isEmpty()) { AZStd::string platformStr = platform.toUtf8().constData(); - + if (!s_DeleteProductsBySourceidPlatformQuery.BindAndStep(*m_databaseConnection, sourceID, platformStr.c_str())) { return false; @@ -2521,7 +2527,7 @@ namespace AssetProcessor { succeeded = succeeded && RemoveSourceFileDependency(entry); } - + if (succeeded) { transaction.Commit(); @@ -2577,7 +2583,7 @@ namespace AssetProcessor } bool AssetDatabaseConnection::GetDependsOnSourceBySource( - const char* source, + const char* source, AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::TypeOfDependency typeOfDependency, AzToolsFramework::AssetDatabase::SourceFileDependencyEntryContainer& container) { @@ -2596,7 +2602,7 @@ namespace AssetProcessor bool AssetDatabaseConnection::GetSourceFileDependencyBySourceDependencyId(AZ::s64 sourceDependencyId, SourceFileDependencyEntry& sourceDependencyEntry) { bool found = false; - QuerySourceDependencyBySourceDependencyId(sourceDependencyId, + QuerySourceDependencyBySourceDependencyId(sourceDependencyId, [&](SourceFileDependencyEntry& entry) { found = true; @@ -2624,7 +2630,7 @@ namespace AssetProcessor return false; } - + if (creatingNew) { AZ::s64 rowID = m_databaseConnection->GetLastRowID(); @@ -2958,9 +2964,25 @@ namespace AssetProcessor for(auto& entry : container) { - if(!SetProductDependency(entry)) + if(entry.m_productDependencyID == InvalidEntryId) { - return false; + if (!s_InsertProductDependencyQuery.BindAndStep( + *m_databaseConnection, entry.m_productPK, entry.m_dependencySourceGuid, entry.m_dependencySubID, + entry.m_dependencyFlags.to_ullong(), entry.m_platform.c_str(), entry.m_unresolvedPath.c_str(), + entry.m_dependencyType, entry.m_fromAssetId)) + { + return false; + } + } + else + { + if(!s_UpdateProductDependencyQuery.BindAndStep( + *m_databaseConnection, entry.m_productPK, entry.m_dependencySourceGuid, entry.m_dependencySubID, + entry.m_dependencyFlags.to_ullong(), entry.m_platform.c_str(), entry.m_unresolvedPath.c_str(), + entry.m_productDependencyID, entry.m_dependencyType, entry.m_fromAssetId)) + { + return false; + } } } @@ -2989,7 +3011,7 @@ namespace AssetProcessor } // now insert the new ones since we know there's no collisions: - + for (auto& entry : container) { @@ -3109,7 +3131,7 @@ namespace AssetProcessor } Statement* statement = autoFinal.Get(); - + if (statement->Step() == Statement::SqlError) { AZ_Warning(LOG_NAME, false, "Failed to write the new source into the database. %s", entry.m_fileName.c_str()); @@ -3126,7 +3148,7 @@ namespace AssetProcessor return UpdateFile(entry, entryAlreadyExists); } - bool AssetDatabaseConnection::UpdateFile(FileDatabaseEntry& entry, bool& entryAlreadyExists) + bool AssetDatabaseConnection::UpdateFile(FileDatabaseEntry& entry, bool& entryAlreadyExists) { entryAlreadyExists = false; diff --git a/Code/Tools/AssetProcessor/native/AssetManager/AssetCatalog.cpp b/Code/Tools/AssetProcessor/native/AssetManager/AssetCatalog.cpp index d7cdd30be8..bda5eb7842 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/AssetCatalog.cpp +++ b/Code/Tools/AssetProcessor/native/AssetManager/AssetCatalog.cpp @@ -480,12 +480,12 @@ namespace AssetProcessor AZ::Data::AssetId assetId(combined.m_sourceGuid, combined.m_subID); // relative file path is gotten by removing the platform and game from the product name - QString relativeProductPath = AssetUtilities::StripAssetPlatform(combined.m_productName); + AZStd::string_view relativeProductPath = AssetUtilities::StripAssetPlatformNoCopy(combined.m_productName); QString fullProductPath = m_cacheRoot.absoluteFilePath(combined.m_productName.c_str()); AZ::Data::AssetInfo info; info.m_assetType = combined.m_assetType; - info.m_relativePath = relativeProductPath.toUtf8().data(); + info.m_relativePath = relativeProductPath; info.m_assetId = assetId; info.m_sizeBytes = AZ::IO::SystemFile::Length(fullProductPath.toUtf8().constData()); diff --git a/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.cpp b/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.cpp index dc10dc2237..6dddfd62d3 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.cpp +++ b/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.cpp @@ -9,18 +9,24 @@ #include "PathDependencyManager.h" #include #include +#include #include #include #include +#include namespace AssetProcessor { void SanitizeForDatabase(AZStd::string& str) { - // Not calling normalize because wildcards should be preserved. AZStd::to_lower(str.begin(), str.end()); - AZStd::replace(str.begin(), str.end(), AZ_WRONG_DATABASE_SEPARATOR, AZ_CORRECT_DATABASE_SEPARATOR); - AzFramework::StringFunc::Replace(str, AZ_DOUBLE_CORRECT_DATABASE_SEPARATOR, AZ_CORRECT_DATABASE_SEPARATOR_STRING); + + // Not calling normalize because wildcards should be preserved. + if (AZ::StringFunc::Contains(str, AZ_WRONG_DATABASE_SEPARATOR, true)) + { + AZStd::replace(str.begin(), str.end(), AZ_WRONG_DATABASE_SEPARATOR, AZ_CORRECT_DATABASE_SEPARATOR); + AzFramework::StringFunc::Replace(str, AZ_DOUBLE_CORRECT_DATABASE_SEPARATOR, AZ_CORRECT_DATABASE_SEPARATOR_STRING); + } } PathDependencyManager::PathDependencyManager(AZStd::shared_ptr stateData, PlatformConfiguration* platformConfig) @@ -29,7 +35,97 @@ namespace AssetProcessor } - void PathDependencyManager::SaveUnresolvedDependenciesToDatabase(AssetBuilderSDK::ProductPathDependencySet& unresolvedDependencies, const AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry, const AZStd::string& platform) + void PathDependencyManager::QueueSourceForDependencyResolution(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry) + { + m_queuedForResolve.push_back(sourceEntry); + } + + void PathDependencyManager::ProcessQueuedDependencyResolves() + { + if (m_queuedForResolve.empty()) + { + return; + } + + auto queuedForResolve = m_queuedForResolve; + m_queuedForResolve.clear(); + + // Grab every product from the database and map to Source PK -> [products] + AZStd::unordered_map> productMap; + m_stateData->QueryCombined([&productMap](const AzToolsFramework::AssetDatabase::CombinedDatabaseEntry& entry) + { + productMap[entry.m_sourcePK].push_back(entry); + return true; + }); + + // Build up a list of all the paths we need to search for: products + 2 variations of the source path + AZStd::vector searches; + + for (const auto& entry : queuedForResolve) + { + // Search for each product + for (const auto& productEntry : productMap[entry.m_sourceID]) + { + const AZStd::string& productName = productEntry.m_productName; + + // strip path of the / + AZStd::string_view result = AssetUtilities::StripAssetPlatformNoCopy(productName); + searches.emplace_back(result, false, &entry, &productEntry); + } + + // Search for the source path + AZStd::string sourceNameWithScanFolder = + ToScanFolderPrefixedPath(aznumeric_cast(entry.m_scanFolderPK), entry.m_sourceName.c_str()); + AZStd::string sanitizedSourceName = entry.m_sourceName; + + SanitizeForDatabase(sourceNameWithScanFolder); + SanitizeForDatabase(sanitizedSourceName); + + searches.emplace_back(sourceNameWithScanFolder, true, &entry, nullptr); + searches.emplace_back(sanitizedSourceName, true, &entry, nullptr); + } + + AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer unresolvedDependencies; + m_stateData->GetUnresolvedProductDependencies(unresolvedDependencies); + + AZStd::recursive_mutex mapMutex; + // Map of Map of Product Dependency>> + AZStd::unordered_map>> sourceIdToMatchedSearchDependencies; + + // For every search path we created, we're going to see if it matches up against any of the unresolved dependencies + AZ::parallel_for_each( + searches.begin(), searches.end(), + [&sourceIdToMatchedSearchDependencies, &mapMutex, &unresolvedDependencies](const SearchEntry& search) + { + AZStd::unordered_set matches; + for (const auto& entry: unresolvedDependencies) + { + AZ::IO::PathView searchPath(search.m_path); + + if(((entry.m_dependencyType == AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry::ProductDep_SourceFile && search.m_isSourcePath) + || (entry.m_dependencyType == AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry::ProductDep_ProductFile && !search.m_isSourcePath)) + && searchPath.Match(entry.m_unresolvedPath)) + { + matches.insert(entry); + } + } + + if (!matches.empty()) + { + AZStd::scoped_lock lock(mapMutex); + auto& productDependencyDatabaseEntries = sourceIdToMatchedSearchDependencies[search.m_sourceEntry->m_sourceID][&search]; + productDependencyDatabaseEntries.insert(matches.begin(), matches.end()); + } + }); + + for (const auto& entry : queuedForResolve) + { + RetryDeferredDependencies(entry, sourceIdToMatchedSearchDependencies[entry.m_sourceID], productMap[entry.m_sourceID]); + } + } + + void PathDependencyManager::SaveUnresolvedDependenciesToDatabase(AssetBuilderSDK::ProductPathDependencySet& unresolvedDependencies, + const AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry, const AZStd::string& platform) { using namespace AzToolsFramework::AssetDatabase; @@ -206,9 +302,9 @@ namespace AssetProcessor } void PathDependencyManager::SaveResolvedDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const MapSet& exclusionMaps, const AZStd::string& sourceNameWithScanFolder, - const AZStd::vector& dependencyEntries, + const AZStd::unordered_set& dependencyEntries, AZStd::string_view matchedPath, bool isSourceDependency, const AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer& matchedProducts, - AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencyContainer) const + AZStd::vector& dependencyContainer) const { for (const auto& productDependencyDatabaseEntry : dependencyEntries) { @@ -267,8 +363,7 @@ namespace AssetProcessor } // All checks passed, this is a valid dependency we need to save to the db - dependencyContainer.push_back(); - auto& entry = dependencyContainer.back(); + AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry entry; entry.m_productDependencyID = dependencyId; entry.m_productPK = productDependencyDatabaseEntry.m_productPK; @@ -276,62 +371,30 @@ namespace AssetProcessor entry.m_dependencySubID = matchedProduct.m_subID; entry.m_platform = productDependencyDatabaseEntry.m_platform; + dependencyContainer.push_back(AZStd::move(entry)); + // If there's more than 1 product, reset the ID so further products create new db entries dependencyId = AzToolsFramework::AssetDatabase::InvalidEntryId; } } } - void PathDependencyManager::RetryDeferredDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry) + void PathDependencyManager::RetryDeferredDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, + const AZStd::unordered_map>& matches, + const AZStd::vector& products) { MapSet exclusionMaps = PopulateExclusionMaps(); - // Gather a list of all the products this source file produced - AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer products; - if (!m_stateData->GetProductsBySourceName(sourceEntry.m_sourceName.c_str(), products)) - { - AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Source %s did not have any products. Skipping dependency processing.\n", sourceEntry.m_sourceName.c_str()); - return; - } - - AZStd::unordered_map> map; - - // Build up a list of all the paths we need to search for: products + 2 variations of the source path - AZStd::vector searchPaths; - - for (const auto& productEntry : products) - { - const AZStd::string& productName = productEntry.m_productName; - - // strip path of the / - AZStd::string strippedPath = AssetUtilities::StripAssetPlatform(productName).toUtf8().constData(); - SanitizeForDatabase(strippedPath); - - searchPaths.push_back(strippedPath); - } - AZStd::string sourceNameWithScanFolder = ToScanFolderPrefixedPath(aznumeric_cast(sourceEntry.m_scanFolderPK), sourceEntry.m_sourceName.c_str()); - AZStd::string sanitizedSourceName = sourceEntry.m_sourceName; - SanitizeForDatabase(sourceNameWithScanFolder); - SanitizeForDatabase(sanitizedSourceName); - searchPaths.push_back(sourceNameWithScanFolder); - searchPaths.push_back(sanitizedSourceName); - - m_stateData->QueryProductDependenciesUnresolvedAdvanced(searchPaths, [&map](AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry& entry, const AZStd::string& matchedPath) - { - map[matchedPath].push_back(AZStd::move(entry)); - return true; - }); - - AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer dependencyContainer; + AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer dependencyVector; // Go through all the matched dependencies - for (const auto& pair : map) + for (const auto& pair : matches) { - AZStd::string_view matchedPath = pair.first; - const bool isSourceDependency = matchedPath == sanitizedSourceName || matchedPath == sourceNameWithScanFolder; + const SearchEntry* searchEntry = pair.first; + const bool isSourceDependency = searchEntry->m_isSourcePath; AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer matchedProducts; @@ -342,34 +405,24 @@ namespace AssetProcessor } else { - for (const auto& productEntry : products) - { - const AZStd::string& productName = productEntry.m_productName; - - // strip path of the leading asset platform / - AZStd::string strippedPath = AssetUtilities::StripAssetPlatform(productName).toUtf8().constData(); - SanitizeForDatabase(strippedPath); - - if (strippedPath == matchedPath) - { - matchedProducts.push_back(productEntry); - } - } + matchedProducts.push_back(*searchEntry->m_productEntry); } // Go through each dependency we're resolving and create a db entry for each product that resolved it (wildcard/source dependencies will generally create more than 1) - SaveResolvedDependencies(sourceEntry, exclusionMaps, sourceNameWithScanFolder, pair.second, matchedPath, isSourceDependency, matchedProducts, dependencyContainer); + SaveResolvedDependencies( + sourceEntry, exclusionMaps, sourceNameWithScanFolder, pair.second, searchEntry->m_path, isSourceDependency, matchedProducts, + dependencyVector); } - // Save everything to the db - if (!m_stateData->UpdateProductDependencies(dependencyContainer)) + // Save everything to the db, this will update matched non-wildcard dependencies and add new records for wildcard matches + if (!m_stateData->UpdateProductDependencies(dependencyVector)) { AZ_Error("PathDependencyManager", false, "Failed to update product dependencies"); } else { // Send a notification for each dependency that has been resolved - NotifyResolvedDependencies(dependencyContainer); + NotifyResolvedDependencies(dependencyVector); } } @@ -460,7 +513,7 @@ namespace AssetProcessor if (isExactDependency) { // Search for products in the cache platform folder - // Example: If a path dependency is "test1.asset" in AutomatedTesting on PC, this would search + // Example: If a path dependency is "test1.asset" in AutomatedTesting on PC, this would search // "AutomatedTesting/Cache/pc/test1.asset" m_stateData->GetProductsByProductName(productNameWithPlatform, productInfoContainer); diff --git a/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.h b/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.h index 3a207ec6a9..763ee2cd74 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.h +++ b/Code/Tools/AssetProcessor/native/AssetManager/PathDependencyManager.h @@ -39,9 +39,27 @@ namespace AssetProcessor PathDependencyManager(AZStd::shared_ptr stateData, PlatformConfiguration* platformConfig); + void QueueSourceForDependencyResolution(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry); + + void ProcessQueuedDependencyResolves(); + + struct SearchEntry + { + SearchEntry(AZStd::string path, bool isSourcePath, const AzToolsFramework::AssetDatabase::SourceDatabaseEntry* sourceEntry, const AzToolsFramework::AssetDatabase::ProductDatabaseEntry* productEntry) + : m_path(std::move(path)), + m_isSourcePath(isSourcePath), + m_sourceEntry(sourceEntry), + m_productEntry(productEntry) {} + + AZStd::string m_path; + bool m_isSourcePath; + const AzToolsFramework::AssetDatabase::SourceDatabaseEntry* m_sourceEntry = nullptr; + const AzToolsFramework::AssetDatabase::ProductDatabaseEntry* m_productEntry = nullptr; + }; + /// This function is responsible for looking up existing, unresolved dependencies that the current asset satisfies. /// These can be dependencies on either the source asset or one of the product assets - void RetryDeferredDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry); + void RetryDeferredDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const AZStd::unordered_map>& matches, const AZStd::vector& products); /// This function is responsible for taking the path dependencies output by the current asset and trying to resolve them to AssetIds /// This does not look for dependencies that the current asset satisfies. @@ -66,7 +84,7 @@ namespace AssetProcessor MapSet PopulateExclusionMaps() const; void NotifyResolvedDependencies(const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencyContainer) const; - void SaveResolvedDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const MapSet& exclusionMaps, const AZStd::string& sourceNameWithScanFolder, const AZStd::vector& dependencyEntries, AZStd::string_view matchedPath, bool isSourceDependency, const AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer& matchedProducts, AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencyContainer) const; + void SaveResolvedDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const MapSet& exclusionMaps, const AZStd::string& sourceNameWithScanFolder, const AZStd::unordered_set& dependencyEntries, AZStd::string_view matchedPath, bool isSourceDependency, const AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer& matchedProducts, AZStd::vector& dependencyContainer) const; static DependencyProductMap& SelectMap(MapSet& mapSet, bool wildcard, AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry::DependencyType type); /// Returns false if a path contains wildcards, true otherwise @@ -93,5 +111,6 @@ namespace AssetProcessor AZStd::shared_ptr m_stateData; PlatformConfiguration* m_platformConfig{}; DependencyResolvedCallback m_dependencyResolvedCallback{}; + AZStd::vector m_queuedForResolve; }; } // namespace AssetProcessor diff --git a/Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp b/Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp index 8867f2379f..beb82dfcab 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp +++ b/Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp @@ -48,7 +48,7 @@ namespace AssetProcessor // note that this is not the first time we're opening the database - the main thread also opens it before this happens, // which allows it to upgrade it and check it for errors. If we get here, it means the database is already good to go. - m_stateData->OpenDatabase(); + m_stateData->OpenDatabase(); MigrateScanFolders(); @@ -70,7 +70,7 @@ namespace AssetProcessor m_excludedFolderCache = AZStd::make_unique(m_platformConfig); PopulateJobStateCache(); - + AssetProcessor::ProcessingJobInfoBus::Handler::BusConnect(); } @@ -126,7 +126,7 @@ namespace AssetProcessor { // capture scanning stats: AssetProcessor::StatsCapture::BeginCaptureStat("AssetScanning"); - + // Ensure that the source file list is populated before a scan begins m_sourceFilesInDatabase.clear(); m_fileModTimes.clear(); @@ -155,11 +155,11 @@ namespace AssetProcessor QString scanFolderPath; QString relativeToScanFolderPath = QString::fromUtf8(entry.m_fileName.c_str()); - + for (int i = 0; i < m_platformConfig->GetScanFolderCount(); ++i) { const auto& scanFolderInfo = m_platformConfig->GetScanFolderAt(i); - + if (scanFolderInfo.ScanFolderID() == entry.m_scanFolderPK) { scanFolderPath = scanFolderInfo.ScanPath(); @@ -181,7 +181,7 @@ namespace AssetProcessor { m_isCurrentlyScanning = false; AssetProcessor::StatsCapture::EndCaptureStat("AssetScanning"); - + // we cannot invoke this immediately - the scanner might be done, but we aren't actually ready until we've processed all remaining messages: QMetaObject::invokeMethod(this, "CheckMissingFiles", Qt::QueuedConnection); } @@ -216,7 +216,7 @@ namespace AssetProcessor else { QString statKey = QString("ProcessJob,%1,%2,%3").arg(jobEntry.m_databaseSourceName).arg(jobEntry.m_jobKey).arg(jobEntry.m_platformInfo.m_identifier.c_str()); - + if (status == JobStatus::InProgress) { //update to in progress status @@ -232,7 +232,7 @@ namespace AssetProcessor // without going thru the RC. // as such, all the code in this block should be crafted to work regardless of whether its double called. AssetProcessor::StatsCapture::EndCaptureStat(statKey.toUtf8().constData()); - + m_jobRunKeyToJobInfoMap.erase(jobEntry.m_jobRunKey); Q_EMIT SourceFinished(sourceUUID, legacySourceUUID); Q_EMIT JobComplete(jobEntry, status); @@ -308,7 +308,7 @@ namespace AssetProcessor //! A network request came in, Given a Job Run Key (from the above Job Request), asking for the actual log for that job. GetAbsoluteAssetDatabaseLocationResponse AssetProcessorManager::ProcessGetAbsoluteAssetDatabaseLocationRequest(MessageData messageData) - { + { GetAbsoluteAssetDatabaseLocationResponse response; AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Broadcast(&AzToolsFramework::AssetDatabase::AssetDatabaseRequests::GetAssetDatabaseLocation, response.m_absoluteAssetDatabaseLocation); @@ -525,7 +525,7 @@ namespace AssetProcessor { foundOne = true; return true; - }, + }, AZ::Uuid::CreateNull(), nullptr, platform.toUtf8().constData(), @@ -750,7 +750,7 @@ namespace AssetProcessor } OnJobStatusChanged(jobEntry, JobStatus::Failed); - + // note that we always print out the failed job status here in both batch and GUI mode. AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Failed %s, (%s)... \n", jobEntry.m_pathRelativeToWatchFolder.toUtf8().constData(), @@ -868,7 +868,7 @@ namespace AssetProcessor && AzFramework::StringFunc::Equal(job.m_platform.c_str(), itProcessedAsset->m_entry.m_platformInfo.m_identifier.c_str())) { // If we are here it implies that for the same source file we have another job that outputs the same product. - // This is usually the case when two builders process the same source file and outputs the same product file. + // This is usually the case when two builders process the same source file and outputs the same product file. remove = true; AZStd::string consoleMsg = AZStd::string::format("Failing Job (source : %s , jobkey %s) because another job (source : %s , jobkey : %s ) outputted the same product %s.\n", itProcessedAsset->m_entry.m_pathRelativeToWatchFolder.toUtf8().constData(), itProcessedAsset->m_entry.m_jobKey.toUtf8().data(), source.m_sourceName.c_str(), job.m_jobKey.c_str(), newProductName.toUtf8().constData()); @@ -1128,7 +1128,7 @@ namespace AssetProcessor QString fullProductPath = m_cacheRootDir.absoluteFilePath(productName); // Strip the from the front of a relative product path - QString relativeProductPath = AssetUtilities::StripAssetPlatform(priorProduct.m_productName); + AZStd::string_view relativeProductPath = AssetUtilities::StripAssetPlatformNoCopy(priorProduct.m_productName); AZ::Data::AssetId assetId(source.m_sourceGuid, priorProduct.m_subID); @@ -1137,7 +1137,7 @@ namespace AssetProcessor AZ::Data::AssetId legacyAssetId(priorProduct.m_legacyGuid, 0); AZ::Data::AssetId legacySourceAssetId(AssetUtilities::CreateSafeSourceUUIDFromName(source.m_sourceName.c_str(), false), priorProduct.m_subID); - AssetNotificationMessage message(relativeProductPath.toUtf8().constData(), AssetNotificationMessage::AssetRemoved, priorProduct.m_assetType, processedAsset.m_entry.m_platformInfo.m_identifier.c_str()); + AssetNotificationMessage message(relativeProductPath, AssetNotificationMessage::AssetRemoved, priorProduct.m_assetType, processedAsset.m_entry.m_platformInfo.m_identifier.c_str()); message.m_assetId = assetId; if (legacyAssetId != assetId) @@ -1271,7 +1271,7 @@ namespace AssetProcessor [&](AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry& dependencyEntry) { return dependencyEntry.m_dependencySubID == pair.first.m_subID - && dependencyEntry.m_dependencySourceGuid == source.m_sourceGuid; + && dependencyEntry.m_dependencySourceGuid == source.m_sourceGuid; }); if (conflictItr != dependencySet.end()) @@ -1312,14 +1312,14 @@ namespace AssetProcessor // relative file path is gotten by removing the platform and game from the product name // Strip the from the front of a relative product path - QString relativeProductPath = AssetUtilities::StripAssetPlatform(productName.toUtf8().constData()); + AZStd::string relativeProductPath = AssetUtilities::StripAssetPlatform(productName.toUtf8().constData()).toUtf8().constData(); - AssetNotificationMessage message(relativeProductPath.toUtf8().constData(), AssetNotificationMessage::AssetChanged, newProduct.m_assetType, processedAsset.m_entry.m_platformInfo.m_identifier.c_str()); + AssetNotificationMessage message(relativeProductPath, AssetNotificationMessage::AssetChanged, newProduct.m_assetType, processedAsset.m_entry.m_platformInfo.m_identifier.c_str()); AZ::Data::AssetId assetId(source.m_sourceGuid, newProduct.m_subID); AZ::Data::AssetId legacyAssetId(newProduct.m_legacyGuid, 0); AZ::Data::AssetId legacySourceAssetId(AssetUtilities::CreateSafeSourceUUIDFromName(source.m_sourceName.c_str(), false), newProduct.m_subID); - message.m_data = relativeProductPath.toUtf8().data(); + message.m_data = relativeProductPath; message.m_sizeBytes = QFileInfo(fullProductPath).size(); message.m_assetId = assetId; @@ -1350,7 +1350,7 @@ namespace AssetProcessor } Q_EMIT AssetMessage( message); - + AddKnownFoldersRecursivelyForFile(fullProductPath, m_cacheRootDir.absolutePath()); } @@ -1497,7 +1497,7 @@ namespace AssetProcessor // Record the modtime for the metadata file so we don't re-analyze this change again next time AP starts up QFileInfo metadataFileInfo(originalName); auto* scanFolder = m_platformConfig->GetScanFolderForFile(originalName); - + if (scanFolder) { QString databaseName; @@ -1534,7 +1534,7 @@ namespace AssetProcessor for (const QString& absolutePath : absoluteSourcePathList) { // we need to check if its already in the "active files" (things that we are looking over) - // or if its in the "currently being examined" list. The latter is likely to be the smaller list, + // or if its in the "currently being examined" list. The latter is likely to be the smaller list, // so we check it first. Both of those are absolute paths, so we convert to absolute path before // searching those lists: if (m_filesToExamine.find(absolutePath) != m_filesToExamine.end()) @@ -1633,9 +1633,6 @@ namespace AssetProcessor } } - // Strip the from the front of a relative product path - QString relativePath = AssetUtilities::StripAssetPlatform(relativeProductFile.toUtf8().constData()); - //set the fingerprint on the job that made this product for (auto& job : jobs) { @@ -1678,7 +1675,7 @@ namespace AssetProcessor } QString fullProductPath = m_cacheRootDir.absoluteFilePath(product.m_productName.c_str()); - QString relativeProductPath(AssetUtilities::StripAssetPlatform(product.m_productName)); + AZStd::string_view relativeProductPath = AssetUtilities::StripAssetPlatformNoCopy(product.m_productName); QFileInfo productFileInfo(fullProductPath); if (productFileInfo.exists()) { @@ -1725,7 +1722,7 @@ namespace AssetProcessor AZ::Data::AssetId legacyAssetId(product.m_legacyGuid, 0); AZ::Data::AssetId legacySourceAssetId(AssetUtilities::CreateSafeSourceUUIDFromName(source.m_sourceName.c_str(), false), product.m_subID); - AssetNotificationMessage message(relativeProductPath.toUtf8().constData(), AssetNotificationMessage::AssetRemoved, product.m_assetType, job.m_platform.c_str()); + AssetNotificationMessage message(relativeProductPath, AssetNotificationMessage::AssetRemoved, product.m_assetType, job.m_platform.c_str()); message.m_assetId = assetId; if (legacyAssetId != assetId) @@ -1759,7 +1756,7 @@ namespace AssetProcessor // and no overrides exist for it. // we must delete its products. using namespace AzToolsFramework::AssetDatabase; - + // If we fail to delete a product, the deletion event gets requeued // To avoid retrying forever, we keep track of the time of the first deletion failure and only retry // if less than this amount of time has passed. @@ -1832,7 +1829,7 @@ namespace AssetProcessor { return; } - + // Check if this file causes any file types to be re-evaluated CheckMetaDataRealFiles(normalizedPath); @@ -2046,7 +2043,7 @@ namespace AssetProcessor AZ_TracePrintf(AssetProcessor::DebugChannel, "Non-processed file: %s\n", databaseSourceFile.toUtf8().constData()); ++m_numSourcesNotHandledByAnyBuilder; - + // Record the modtime for the file so we know we've already processed it QString absolutePath = QDir(scanFolder->ScanPath()).absoluteFilePath(normalizedPath); @@ -2114,7 +2111,7 @@ namespace AssetProcessor // Check whether another job emitted this job as a job dependency and if true, queue the dependent job source file also JobDesc jobDesc(jobDetails.m_jobEntry.m_databaseSourceName.toUtf8().data(), jobDetails.m_jobEntry.m_jobKey.toUtf8().data(), jobDetails.m_jobEntry.m_platformInfo.m_identifier); - + shouldProcessAsset = true; QFileInfo file(jobDetails.m_jobEntry.GetAbsoluteSourcePath()); QDateTime dateTime(file.lastModified()); @@ -2347,7 +2344,7 @@ namespace AssetProcessor } QString canonicalRootDir = AssetUtilities::NormalizeFilePath(m_cacheRootDir.canonicalPath()); - + FileExamineContainer swapped; m_filesToExamine.swap(swapped); // makes it okay to call CheckSource(...) @@ -2470,7 +2467,7 @@ namespace AssetProcessor AZ_TracePrintf(AssetProcessor::DebugChannel, "ProcessFilesToExamineQueue: Unable to find the relative path.\n"); continue; } - + const ScanFolderInfo* scanFolderInfo = m_platformConfig->GetScanFolderForFile(normalizedPath); relativePathToFile = databasePathToFile; @@ -2494,9 +2491,9 @@ namespace AssetProcessor QString::fromUtf8(jobInfo.m_watchFolder.c_str()), relativePathToFile, databasePathToFile, - jobInfo.m_builderGuid, - *platformFromInfo, - jobInfo.m_jobKey.c_str(), 0, GenerateNewJobRunKey(), + jobInfo.m_builderGuid, + *platformFromInfo, + jobInfo.m_jobKey.c_str(), 0, GenerateNewJobRunKey(), AZ::Uuid::CreateNull()); job.m_autoFail = true; @@ -2597,7 +2594,7 @@ namespace AssetProcessor { // on the other hand, if we found a file it means that a deleted file revealed a file that // was previously overridden by it. - // Because the deleted file may have "revealed" a file with different case, + // Because the deleted file may have "revealed" a file with different case, // we have to actually correct its case here. This is rare, so it should be reasonable // to call the expensive function to discover correct case. QString pathRelativeToScanFolder; @@ -2674,6 +2671,7 @@ namespace AssetProcessor AZ_TracePrintf(ConsoleChannel, "Builder optimization: %i / %i files required full analysis, %i sources found but not processed by anyone\n", m_numSourcesNeedingFullAnalysis, m_numTotalSourcesFound, m_numSourcesNotHandledByAnyBuilder); } + m_pathDependencyManager->ProcessQueuedDependencyResolves(); QTimer::singleShot(20, this, SLOT(RemoveEmptyFolders())); } else @@ -2739,7 +2737,7 @@ namespace AssetProcessor } // over here we also want to invalidate the metafiles on disk map if it COULD Be a metafile - // note that there is no reason to do an expensive exacting computation here, it will be + // note that there is no reason to do an expensive exacting computation here, it will be // done later and cached when m_cachedMetaFilesExistMap is set to false, we just need to // know if its POSSIBLE that its a metafile, cheaply. // if its a metafile match, then invalidate the metafile table. @@ -2752,7 +2750,7 @@ namespace AssetProcessor m_metaFilesWhichActuallyExistOnDisk.clear(); // invalidate the map, force a recompuation later. } } - + } m_AssetProcessorIsBusy = true; @@ -2927,7 +2925,7 @@ namespace AssetProcessor } AZ::u64 fileHash = AssetUtilities::GetFileHash(fileInfo.m_filePath.toUtf8().constData()); - + if(fileHash != databaseHashValue) { // File contents have changed @@ -3149,7 +3147,7 @@ namespace AssetProcessor { AddMetadataFilesForFingerprinting(kvp.first.c_str(), job.m_fingerprintFiles); } - + // Check the current builder jobs with the previous ones in the database: job.m_jobEntry.m_computedFingerprint = AssetUtilities::GenerateFingerprint(job); JobIndentifier jobIndentifier(JobDesc(job.m_jobEntry.m_databaseSourceName.toUtf8().data(), job.m_jobEntry.m_jobKey.toUtf8().data(), job.m_jobEntry.m_platformInfo.m_identifier), job.m_jobEntry.m_builderGuid); @@ -3208,7 +3206,7 @@ namespace AssetProcessor { // If the database knows about the job than it implies that AP has processed it sucessfully at least once // and therefore the dependent job should not cause the job which depends on it to be processed again. - // If however we find a dependent job which is not known to AP then we know this job needs to be processed + // If however we find a dependent job which is not known to AP then we know this job needs to be processed // after all the dependent jobs have completed at least once. AzToolsFramework::AssetDatabase::JobDatabaseEntryContainer jobs; @@ -3238,7 +3236,7 @@ namespace AssetProcessor } else if(sourceFileDependency.m_sourceDependencyType != AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Wildcards) { - AZ_TracePrintf(AssetProcessor::ConsoleChannel, "UpdateJobDependency: Failed to find builder dependency for %s job (%s, %s, %s)\n", + AZ_TracePrintf(AssetProcessor::ConsoleChannel, "UpdateJobDependency: Failed to find builder dependency for %s job (%s, %s, %s)\n", job.m_jobEntry.GetAbsoluteSourcePath().toUtf8().constData(), jobDependencyInternal->m_jobDependency.m_sourceFile.m_sourceFileDependencyPath.c_str(), jobDependencyInternal->m_jobDependency.m_jobKey.c_str(), @@ -3262,7 +3260,7 @@ namespace AssetProcessor ++jobDependencySlot; } - // sorting job dependencies as they can effect the fingerprint of the job + // sorting job dependencies as they can effect the fingerprint of the job AZStd::sort(job.m_jobDependencyList.begin(), job.m_jobDependencyList.end(), [](const AssetProcessor::JobDependencyInternal& lhs, const AssetProcessor::JobDependencyInternal& rhs) { @@ -3289,7 +3287,7 @@ namespace AssetProcessor for (const JobDependencyInternal& jobDependencyInternal : job.m_jobDependencyList) { // Loop over all the builderUuid and check whether the corresponding entry exists in the jobsFingerprint map. - // If an entry exists, it implies than we have already send the job over to the RCController + // If an entry exists, it implies than we have already send the job over to the RCController for (auto builderIter = jobDependencyInternal.m_builderUuidList.begin(); builderIter != jobDependencyInternal.m_builderUuidList.end(); ++builderIter) { JobIndentifier jobIdentifier(JobDesc(jobDependencyInternal.m_jobDependency.m_sourceFile.m_sourceFileDependencyPath, @@ -3299,7 +3297,7 @@ namespace AssetProcessor auto jobFound = m_jobFingerprintMap.find(jobIdentifier); if (jobFound == m_jobFingerprintMap.end()) { - // Job cannot be processed, since one of its dependent job hasn't been fingerprinted + // Job cannot be processed, since one of its dependent job hasn't been fingerprinted return false; } } @@ -3317,7 +3315,7 @@ namespace AssetProcessor // and call the CreateJobs function on the builder. // it bundles the results up in a JobToProcessEntry struct, while it is doing this: JobToProcessEntry entry; - + AZ::Uuid sourceUUID = AssetUtilities::CreateSafeSourceUUIDFromName(databasePathToFile.toUtf8().constData()); // first, we put the source UUID in the map so that its present for any other queries: @@ -3375,14 +3373,14 @@ namespace AssetProcessor builderInfo.m_createJobFunction(createJobsRequest, createJobsResponse); AssetProcessor::StatsCapture::EndCaptureStat(statKey.toUtf8().constData()); } - + AssetProcessor::SetThreadLocalJobId(0); bool isBuilderMissingFingerprint = (createJobsResponse.m_result == AssetBuilderSDK::CreateJobsResultCode::Success && !createJobsResponse.m_createJobOutputs.empty() && !createJobsResponse.m_createJobOutputs[0].m_additionalFingerprintInfo.empty() && builderInfo.m_analysisFingerprint.empty()); - + if (createJobsResponse.m_result == AssetBuilderSDK::CreateJobsResultCode::Failed || isBuilderMissingFingerprint) { AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Createjobs Failed: %s.\n", normalizedPath.toUtf8().constData()); @@ -3393,7 +3391,7 @@ namespace AssetProcessor char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; AZ::IO::FileIOBase::GetInstance()->ResolvePath(fullPathToLogFile.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - + JobDetails jobdetail; jobdetail.m_jobEntry = JobEntry( scanFolder->ScanPath(), @@ -3486,9 +3484,9 @@ namespace AssetProcessor scanFolder->ScanPath(), actualRelativePath, databasePathToFile, - builderInfo.m_busId, - *infoForPlatform, - jobDescriptor.m_jobKey.c_str(), 0, GenerateNewJobRunKey(), + builderInfo.m_busId, + *infoForPlatform, + jobDescriptor.m_jobKey.c_str(), 0, GenerateNewJobRunKey(), sourceUUID); newJob.m_jobEntry.m_checkExclusiveLock = jobDescriptor.m_checkExclusiveLock; newJob.m_jobParam = AZStd::move(jobDescriptor.m_jobParameters); @@ -3506,7 +3504,7 @@ namespace AssetProcessor newJob.m_jobDependencyList.push_back(JobDependencyInternal(jobDependency)); ++numJobDependencies; } - + // note that until analysis completes, the jobId is not set and neither is the destination pat JobDesc jobDesc(newJob.m_jobEntry.m_databaseSourceName.toUtf8().data(), newJob.m_jobEntry.m_jobKey.toUtf8().data(), newJob.m_jobEntry.m_platformInfo.m_identifier); m_jobDescToBuilderUuidMap[jobDesc].insert(builderInfo.m_busId); @@ -3515,7 +3513,7 @@ namespace AssetProcessor JobIndentifier jobIdentifier(jobDesc, builderInfo.m_busId); { AZStd::lock_guard lock(AssetProcessor::ProcessingJobInfoBus::GetOrCreateContext().m_contextMutex); - m_jobFingerprintMap.erase(jobIdentifier); + m_jobFingerprintMap.erase(jobIdentifier); } entry.m_jobsToAnalyze.push_back(AZStd::move(newJob)); @@ -3578,7 +3576,7 @@ namespace AssetProcessor // instead of a UUID, a path has been provided, prepare and use that. We need to turn it into a database path QString encodedFileData = QString::fromUtf8(sourceDependency.m_sourceFileDependencyPath.c_str()); encodedFileData = AssetUtilities::NormalizeFilePath(encodedFileData); - + if (sourceDependency.m_sourceDependencyType == AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Wildcards) { int wildcardIndex = encodedFileData.indexOf("*"); @@ -3653,7 +3651,7 @@ namespace AssetProcessor } // Convert to relative paths - for (auto dependencyItr = resolvedDependencyList.begin(); dependencyItr != resolvedDependencyList.end();) + for (auto dependencyItr = resolvedDependencyList.begin(); dependencyItr != resolvedDependencyList.end();) { QString relativePath, scanFolder; if (m_platformConfig->ConvertToRelativePath(*dependencyItr, relativePath, scanFolder)) @@ -3705,7 +3703,7 @@ namespace AssetProcessor return (!resultDatabaseSourceName.isEmpty()); } - + void AssetProcessorManager::UpdateSourceFileDependenciesDatabase(JobToProcessEntry& entry) { using namespace AzToolsFramework::AssetDatabase; @@ -3738,7 +3736,7 @@ namespace AssetProcessor QString resolvedDatabaseName; if (!ResolveSourceFileDependencyPath(sourceDependency.second, resolvedDatabaseName,resolvedDependencyList)) { - // ResolveDependencyPath should only fail in a data error, otherwise it always outputs something, + // ResolveDependencyPath should only fail in a data error, otherwise it always outputs something, // even if that something starts with the placeholder. continue; } @@ -3759,7 +3757,7 @@ namespace AssetProcessor SourceFileDependencyEntry newDependencyEntry( sourceDependency.first, entry.m_sourceFileInfo.m_databasePath.toUtf8().constData(), - resolvedDatabaseName.toUtf8().constData(), + resolvedDatabaseName.toUtf8().constData(), sourceDependency.second.m_sourceDependencyType == AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Wildcards ? SourceFileDependencyEntry::DEP_SourceLikeMatch : SourceFileDependencyEntry::DEP_SourceToSource, !sourceDependency.second.m_sourceFileDependencyUUID.IsNull()); // If the UUID is null, then record that this dependency came from a (resolved) path newDependencies.push_back(AZStd::move(newDependencyEntry)); @@ -3803,7 +3801,7 @@ namespace AssetProcessor } // get all the old dependencies and remove them. This function is comprehensive on all dependencies - // for a given source file so we can just eliminate all of them from that same source file and replace + // for a given source file so we can just eliminate all of them from that same source file and replace // them with all of the new ones for the given source file: AZStd::unordered_set oldDependencies; m_stateData->QueryDependsOnSourceBySourceDependency( @@ -4018,7 +4016,7 @@ namespace AssetProcessor result.m_watchFolder = QString::fromUtf8(scanFolder.m_scanFolder.c_str()); result.m_sourceRelativeToWatchFolder = result.m_sourceDatabaseName; - { + { // this scope exists to restrict the duration of the below lock. AZStd::lock_guard lock(m_sourceUUIDToSourceInfoMapMutex); m_sourceUUIDToSourceInfoMap.insert(AZStd::make_pair(sourceUuid, result)); @@ -4045,9 +4043,9 @@ namespace AssetProcessor auto jobPair = m_jobsToProcess.insert(AZStd::move(jobDetail)); if (!jobPair.second) { - // if we are here it means that this job was already found in the jobs to process list + // if we are here it means that this job was already found in the jobs to process list // and therefore insert failed, we will try to update the iterator manually here. - // Note that if insert fails the original object is not destroyed and therefore we can use move again. + // Note that if insert fails the original object is not destroyed and therefore we can use move again. // we just replaced a job, so we have to decrement its count. UpdateAnalysisTrackerForFile(jobPair.first->m_jobEntry, AnalysisTrackerUpdateType::JobFinished); @@ -4068,7 +4066,7 @@ namespace AssetProcessor QSet absoluteSourceFilePathQueue; QString databasePath; QString scanFolder; - + auto callbackFunction = [this, &absoluteSourceFilePathQueue](SourceFileDependencyEntry& entry) { QString relativeDatabaseName = QString::fromUtf8(entry.m_source.c_str()); @@ -4111,7 +4109,7 @@ namespace AssetProcessor sourceDatabaseEntry.m_sourceName = relativeSourceFilePath.toUtf8().constData(); sourceDatabaseEntry.m_sourceGuid = AssetUtilities::CreateSafeSourceUUIDFromName(sourceDatabaseEntry.m_sourceName.c_str()); - + if (!m_stateData->SetSource(sourceDatabaseEntry)) { AZ_Error(AssetProcessor::ConsoleChannel, false, "Failed to add source to the database!!!"); @@ -4260,7 +4258,7 @@ namespace AssetProcessor { AZ_TracePrintf(DebugChannel, "Builder %s analysis fingerprint changed. Files assigned to it will be re-analyzed.\n", priorBuilderUUID.ToString().c_str()); } - + if (builderIsDirty) { m_anyBuilderChange = true; @@ -4414,7 +4412,7 @@ namespace AssetProcessor source.m_analysisFingerprint.append(builderFP.ToString()); } - m_pathDependencyManager->RetryDeferredDependencies(source); + m_pathDependencyManager->QueueSourceForDependencyResolution(source); m_stateData->SetSource(source); databaseSourceName = source.m_sourceName.c_str(); @@ -4593,7 +4591,7 @@ namespace AssetProcessor { continue; } - + QString firstMatchingFile = m_platformConfig->FindFirstMatchingFile(dep); if (firstMatchingFile.isEmpty()) { @@ -4787,7 +4785,7 @@ namespace AssetProcessor assetIter->m_entry.m_sourceFileUUID); jobdetail.m_autoFail = true; jobdetail.m_critical = true; - jobdetail.m_priority = INT_MAX; // front of the queue. + jobdetail.m_priority = INT_MAX; // front of the queue. jobdetail.m_scanFolder = m_platformConfig->GetScanFolderForFile(assetIter->m_entry.GetAbsoluteSourcePath()); // the new lines make it easier to copy and paste the file names. jobdetail.m_jobParam[AZ_CRC(AutoFailReasonKey)] = autoFailReason; @@ -4859,6 +4857,6 @@ namespace AssetProcessor return filesFound; } - + } // namespace AssetProcessor diff --git a/Code/Tools/AssetProcessor/native/tests/BaseAssetProcessorTest.h b/Code/Tools/AssetProcessor/native/tests/BaseAssetProcessorTest.h index 71d3fa0f6d..be7e78d097 100644 --- a/Code/Tools/AssetProcessor/native/tests/BaseAssetProcessorTest.h +++ b/Code/Tools/AssetProcessor/native/tests/BaseAssetProcessorTest.h @@ -40,12 +40,14 @@ protected: void SetupEnvironment() override { // Setup code + AZ::Environment::Create(nullptr); qInstallMessageHandler(UnitTestMessageHandler); } void TeardownEnvironment() override { qInstallMessageHandler(nullptr); + AZ::Environment::Destroy(); } private: diff --git a/Code/Tools/AssetProcessor/native/tests/PathDependencyManagerTests.cpp b/Code/Tools/AssetProcessor/native/tests/PathDependencyManagerTests.cpp index b20d373307..1d6e92e47e 100644 --- a/Code/Tools/AssetProcessor/native/tests/PathDependencyManagerTests.cpp +++ b/Code/Tools/AssetProcessor/native/tests/PathDependencyManagerTests.cpp @@ -12,13 +12,23 @@ #include "AzToolsFramework/API/AssetDatabaseBus.h" #include "AssetDatabase/AssetDatabase.h" #include +#include +#include +#include +#include namespace UnitTests { class MockDatabaseLocationListener : public AzToolsFramework::AssetDatabase::AssetDatabaseRequests::Bus::Handler { public: - MOCK_METHOD1(GetAssetDatabaseLocation, bool(AZStd::string&)); + bool GetAssetDatabaseLocation(AZStd::string& location) override + { + location = m_databaseLocation; + return true; + } + + AZStd::string m_databaseLocation; }; namespace Util @@ -38,25 +48,45 @@ namespace UnitTests } } - struct PathDependencyDeletionTest - : UnitTest::ScopedAllocatorSetupFixture - , UnitTest::TraceBusRedirector + struct PathDependencyBase + : UnitTest::TraceBusRedirector { - void SetUp() override; - void TearDown() override; + void Init(); + void Destroy(); QTemporaryDir m_tempDir; AZStd::string m_databaseLocation; - ::testing::NiceMock m_databaseLocationListener; + MockDatabaseLocationListener m_databaseLocationListener; AZStd::shared_ptr m_stateData; AZStd::unique_ptr m_platformConfig; + AZStd::unique_ptr m_serializeContext; + AZ::Entity* m_jobManagerEntity{}; + AZ::ComponentDescriptor* m_descriptor{}; }; - void PathDependencyDeletionTest::SetUp() + struct PathDependencyDeletionTest + : UnitTest::ScopedAllocatorSetupFixture + , PathDependencyBase + { + void SetUp() override + { + PathDependencyBase::Init(); + } + + void TearDown() override + { + PathDependencyBase::Destroy(); + } + }; + + void PathDependencyBase::Init() { using namespace ::testing; using namespace AzToolsFramework::AssetDatabase; + ::UnitTest::TestRunner::Instance().m_suppressAsserts = false; + ::UnitTest::TestRunner::Instance().m_suppressErrors = false; + BusConnect(); QDir tempPath(m_tempDir.path()); @@ -68,21 +98,39 @@ namespace UnitTests // ":memory:" databases are one-instance-only, and even if another connection is opened to ":memory:" it would // not share with others created using ":memory:" and get a unique database instead. m_databaseLocation = tempPath.absoluteFilePath("test_database.sqlite").toUtf8().constData(); - - ON_CALL(m_databaseLocationListener, GetAssetDatabaseLocation(_)) - .WillByDefault( - DoAll( // set the 0th argument ref (string) to the database location and return true. - SetArgReferee<0>(m_databaseLocation), - Return(true))); + m_databaseLocationListener.m_databaseLocation = m_databaseLocation; m_stateData = AZStd::shared_ptr(new AssetProcessor::AssetDatabaseConnection()); m_stateData->OpenDatabase(); m_platformConfig = AZStd::make_unique(); + + AZ::AllocatorInstance::Create(); + AZ::AllocatorInstance::Create(); + + m_serializeContext = AZStd::make_unique(); + m_descriptor = AZ::JobManagerComponent::CreateDescriptor(); + m_descriptor->Reflect(m_serializeContext.get()); + + m_jobManagerEntity = aznew AZ::Entity{}; + m_jobManagerEntity->CreateComponent(); + m_jobManagerEntity->Init(); + m_jobManagerEntity->Activate(); } - void PathDependencyDeletionTest::TearDown() + void PathDependencyBase::Destroy() { + m_stateData = nullptr; + m_platformConfig = nullptr; + + m_jobManagerEntity->Deactivate(); + delete m_jobManagerEntity; + + delete m_descriptor; + + AZ::AllocatorInstance::Destroy(); + AZ::AllocatorInstance::Destroy(); + BusDisconnect(); } @@ -91,7 +139,7 @@ namespace UnitTests using namespace AzToolsFramework::AssetDatabase; // Add a product to the db with an unmet dependency - ScanFolderDatabaseEntry scanFolder("folder", "test", "test", ""); + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); m_stateData->SetScanFolder(scanFolder); SourceDatabaseEntry source1, source2; @@ -110,7 +158,8 @@ namespace UnitTests Util::CreateSourceJobAndProduct(m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.txt", "product2.jpg"); - manager.RetryDeferredDependencies(source2); + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); } TEST_F(PathDependencyDeletionTest, ExistingSourceWithUnmetDependency_RemovedFromDB_DependentProductCreatedWithoutError) @@ -118,7 +167,7 @@ namespace UnitTests using namespace AzToolsFramework::AssetDatabase; // Add a product to the db with an unmet dependency - ScanFolderDatabaseEntry scanFolder("folder", "test", "test", ""); + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); m_stateData->SetScanFolder(scanFolder); SourceDatabaseEntry source1, source2; @@ -137,7 +186,8 @@ namespace UnitTests Util::CreateSourceJobAndProduct(m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.txt", "product2.jpg"); - manager.RetryDeferredDependencies(source2); + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); } TEST_F(PathDependencyDeletionTest, NewSourceWithUnmetDependency_RemovedFromDB_DependentSourceCreatedWithoutError) @@ -147,7 +197,7 @@ namespace UnitTests AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); // Add a product to the db with an unmet dependency - ScanFolderDatabaseEntry scanFolder("folder", "test", "test", ""); + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); m_stateData->SetScanFolder(scanFolder); SourceDatabaseEntry source1, source2; @@ -166,7 +216,8 @@ namespace UnitTests Util::CreateSourceJobAndProduct(m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.txt", "product2.jpg"); - manager.RetryDeferredDependencies(source2); + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); } TEST_F(PathDependencyDeletionTest, NewSourceWithUnmetDependency_RemovedFromDB_DependentProductCreatedWithoutError) @@ -176,7 +227,7 @@ namespace UnitTests AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); // Add a product to the db with an unmet dependency - ScanFolderDatabaseEntry scanFolder("folder", "test", "test", ""); + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); m_stateData->SetScanFolder(scanFolder); SourceDatabaseEntry source1, source2; @@ -195,7 +246,8 @@ namespace UnitTests Util::CreateSourceJobAndProduct(m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.txt", "product2.jpg"); - manager.RetryDeferredDependencies(source2); + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); } TEST_F(PathDependencyDeletionTest, NewSourceWithUnmetDependency_Wildcard_RemovedFromDB_DependentSourceCreatedWithoutError) @@ -205,7 +257,7 @@ namespace UnitTests AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); // Add a product to the db with an unmet dependency - ScanFolderDatabaseEntry scanFolder("folder", "test", "test", ""); + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); m_stateData->SetScanFolder(scanFolder); SourceDatabaseEntry source1, source2; @@ -224,6 +276,266 @@ namespace UnitTests Util::CreateSourceJobAndProduct(m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.txt", "product2.jpg"); - manager.RetryDeferredDependencies(source2); + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); } + + using PathDependencyTests = PathDependencyDeletionTest; + + TEST_F(PathDependencyTests, SourceAndProductHaveSameName_SourceFileDependency_MatchesSource) + { + using namespace AzToolsFramework::AssetDatabase; + + AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); + + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); + m_stateData->SetScanFolder(scanFolder); + + SourceDatabaseEntry source1, source2; + JobDatabaseEntry job1, job2; + ProductDatabaseEntry product1, product2, product3; + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, source1, job1, product1, "source1.txt", "product1.jpg"); + + AssetBuilderSDK::ProductPathDependencySet set; + set.insert(AssetBuilderSDK::ProductPathDependency("*.xml", AssetBuilderSDK::ProductPathDependencyType::SourceFile)); + + manager.SaveUnresolvedDependenciesToDatabase(set, product1, "pc"); + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.xml", "source2.xml"); + + // Create a 2nd product for this source + product3 = ProductDatabaseEntry{ job2.m_jobID, product2.m_subID + 1, "source2.txt", AZ::Data::AssetType::CreateRandom() }; + ASSERT_TRUE(m_stateData->SetProduct(product3)); + + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); + + ProductDependencyDatabaseEntryContainer productDependencies; + m_stateData->GetProductDependencies(productDependencies); + + EXPECT_EQ(productDependencies.size(), 3); + } + + TEST_F(PathDependencyTests, SourceAndProductHaveSameName_ProductFileDependency_MatchesProduct) + { + using namespace AzToolsFramework::AssetDatabase; + + AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); + + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); + m_stateData->SetScanFolder(scanFolder); + + SourceDatabaseEntry source1, source2; + JobDatabaseEntry job1, job2; + ProductDatabaseEntry product1, product2, product3; + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, source1, job1, product1, "source1.txt", "product1.jpg"); + + AssetBuilderSDK::ProductPathDependencySet set; + set.insert(AssetBuilderSDK::ProductPathDependency("*.xml", AssetBuilderSDK::ProductPathDependencyType::ProductFile)); + + manager.SaveUnresolvedDependenciesToDatabase(set, product1, "pc"); + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, source2, job2, product2, "source2.xml", "source2.xml"); + + // Create a 2nd product for this source + product3 = ProductDatabaseEntry{job2.m_jobID, product2.m_subID + 1, "source2.txt", AZ::Data::AssetType::CreateRandom()}; + ASSERT_TRUE(m_stateData->SetProduct(product3)); + + manager.QueueSourceForDependencyResolution(source2); + manager.ProcessQueuedDependencyResolves(); + + ProductDependencyDatabaseEntryContainer productDependencies; + m_stateData->GetProductDependencies(productDependencies); + + EXPECT_EQ(productDependencies.size(), 2); + } + + struct PathDependencyBenchmarks + : UnitTest::ScopedAllocatorFixture + , PathDependencyBase + { + static inline constexpr int NumTestDependencies = 4; // Must be a multiple of 4 + static inline constexpr int NumTestProducts = 2; // Must be a multiple of 2 + + AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer m_products; + AzToolsFramework::AssetDatabase::SourceDatabaseEntry m_source1, m_source2, m_source4; + AzToolsFramework::AssetDatabase::JobDatabaseEntry m_job1, m_job2, m_job4; + AzToolsFramework::AssetDatabase::ProductDatabaseEntry m_product1, m_product2, m_product4; + AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer m_dependencies; + + void SetupTestData() + { + using namespace AzToolsFramework::AssetDatabase; + + ScanFolderDatabaseEntry scanFolder("folder", "test", "test", 0); + ASSERT_TRUE(m_stateData->SetScanFolder(scanFolder)); + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, m_source1, m_job1, m_product1, "source1.txt", "product1.jpg"); + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, m_source4, m_job4, m_product4, "source4.txt", "product4.jpg"); + + for (int i = 0; i < NumTestDependencies / 2; ++i) + { + m_dependencies.emplace_back( + m_product1.m_productID, AZ::Uuid::CreateNull(), 0, 0, "pc", 0, + AZStd::string::format("folder/folder2/%d_*2.jpg", i).c_str()); + ++i; + m_dependencies.emplace_back( + m_product1.m_productID, AZ::Uuid::CreateNull(), 0, 0, "mac", 0, + AZStd::string::format("folder/folder2/%d_*2.jpg", i).c_str()); + } + + for (int i = 0; i < NumTestDependencies / 2; ++i) + { + m_dependencies.emplace_back( + m_product4.m_productID, AZ::Uuid::CreateNull(), 0, 0, "pc", 0, + AZStd::string::format("folder/folder2/%d_*2.jpg", i).c_str()); + ++i; + m_dependencies.emplace_back( + m_product4.m_productID, AZ::Uuid::CreateNull(), 0, 0, "mac", 0, + AZStd::string::format("folder/folder2/%d_*2.jpg", i).c_str()); + } + + ASSERT_TRUE(m_stateData->SetProductDependencies(m_dependencies)); + + Util::CreateSourceJobAndProduct( + m_stateData.get(), scanFolder.m_scanFolderID, m_source2, m_job2, m_product2, "source2.txt", "product2.jpg"); + + auto job3 = JobDatabaseEntry( + m_source2.m_sourceID, "jobkey", 1111, "mac", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, + 4444); + ASSERT_TRUE(m_stateData->SetJob(job3)); + + for (int i = 0; i < NumTestProducts; ++i) + { + m_products.emplace_back( + m_job2.m_jobID, i, AZStd::string::format("pc/folder/folder2/%d_product2.jpg", i).c_str(), + AZ::Data::AssetType::CreateRandom()); + ++i; + m_products.emplace_back( + job3.m_jobID, i, AZStd::string::format("mac/folder/folder2/%d_product2.jpg", i).c_str(), + AZ::Data::AssetType::CreateRandom()); + } + + ASSERT_TRUE(m_stateData->SetProducts(m_products)); + } + + void DoTest() + { + AssetProcessor::PathDependencyManager manager(m_stateData, m_platformConfig.get()); + + manager.QueueSourceForDependencyResolution(m_source2); + manager.ProcessQueuedDependencyResolves(); + } + + void VerifyResult() + { + using namespace AzToolsFramework::AssetDatabase; + + ProductDependencyDatabaseEntryContainer productDependencies; + m_stateData->GetProductDependencies(productDependencies); + + for (int i = 0; i < NumTestDependencies / 2 && i < NumTestProducts; ++i) + { + const auto& product = m_products[i]; + int found = 0; + + for (const auto& unresolvedProductDependency : productDependencies) + { + if (unresolvedProductDependency.m_dependencySourceGuid == m_source2.m_sourceGuid && + unresolvedProductDependency.m_dependencySubID == product.m_subID && + unresolvedProductDependency.m_productPK == m_product1.m_productID) + { + ++found; + } + + if (unresolvedProductDependency.m_dependencySourceGuid == m_source2.m_sourceGuid && + unresolvedProductDependency.m_dependencySubID == product.m_subID && + unresolvedProductDependency.m_productPK == m_product4.m_productID) + { + ++found; + } + + if (found == 2) + break; + } + + EXPECT_TRUE(found == 2) << product.m_productName.c_str() << " was not found"; + } + + EXPECT_EQ(productDependencies.size(), NumTestDependencies * 2); + } + }; + + // For some reason, BENCHMARK_F doesn't seem to call the destructor + // So we'll wrap the class and handle the new/delete ourselves + struct PathDependencyBenchmarksWrapperClass : public ::benchmark::Fixture + { + void SetUp([[maybe_unused]] const benchmark::State& st) override + { + m_benchmarks = new PathDependencyBenchmarks(); + m_benchmarks->Init(); + m_benchmarks->SetupTestData(); + } + + void SetUp([[maybe_unused]] benchmark::State& st) override + { + m_benchmarks = new PathDependencyBenchmarks(); + m_benchmarks->Init(); + m_benchmarks->SetupTestData(); + } + + void TearDown([[maybe_unused]] benchmark::State& st) override + { + m_benchmarks->Destroy(); + delete m_benchmarks; + } + + void TearDown([[maybe_unused]] const benchmark::State& st) override + { + m_benchmarks->Destroy(); + delete m_benchmarks; + } + + PathDependencyBenchmarks* m_benchmarks = {}; + }; + + struct PathDependencyTestValidation + : PathDependencyBenchmarks, ::testing::Test + { + void SetUp() override + { + PathDependencyBase::Init(); + } + void TearDown() override + { + PathDependencyBase::Destroy(); + } + }; + + TEST_F(PathDependencyTestValidation, DeferredWildcardDependencyResolution) + { + SetupTestData(); + DoTest(); + VerifyResult(); + } + + BENCHMARK_F(PathDependencyBenchmarksWrapperClass, BM_DeferredWildcardDependencyResolution)(benchmark::State& state) + { + for (auto _ : state) + { + m_benchmarks->m_stateData->SetProductDependencies(m_benchmarks->m_dependencies); + + m_benchmarks->DoTest(); + } + } + } diff --git a/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp b/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp index 58f76f8da6..0908d0fdb9 100644 --- a/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp +++ b/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp @@ -15,6 +15,10 @@ #include #include +#include +#include +#include +#include using namespace AssetProcessor; @@ -26,6 +30,7 @@ public: friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies); friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_DeferredResolution); + friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, SameFilenameForAllPlatforms); friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_SourcePath); @@ -176,8 +181,21 @@ void AssetProcessorManagerTest::SetUp() AssetProcessorTest::SetUp(); + AZ::AllocatorInstance::Create(); + AZ::AllocatorInstance::Create(); + m_data = AZStd::make_unique(); + m_data->m_serializeContext = AZStd::make_unique(); + + m_data->m_descriptor = AZ::JobManagerComponent::CreateDescriptor(); + m_data->m_descriptor->Reflect(m_data->m_serializeContext.get()); + + m_data->m_jobManagerEntity = aznew AZ::Entity{}; + m_data->m_jobManagerEntity->CreateComponent(); + m_data->m_jobManagerEntity->Init(); + m_data->m_jobManagerEntity->Activate(); + m_config.reset(new AssetProcessor::PlatformConfiguration()); m_mockApplicationManager.reset(new AssetProcessor::MockApplicationManager()); @@ -256,6 +274,10 @@ void AssetProcessorManagerTest::SetUp() void AssetProcessorManagerTest::TearDown() { + m_data->m_jobManagerEntity->Deactivate(); + delete m_data->m_jobManagerEntity; + delete m_data->m_descriptor; + m_data = nullptr; QObject::disconnect(m_idleConnection); @@ -271,6 +293,9 @@ void AssetProcessorManagerTest::TearDown() m_qApp.reset(); m_scopeDir.reset(); + AZ::AllocatorInstance::Destroy(); + AZ::AllocatorInstance::Destroy(); + AssetProcessor::AssetProcessorTest::TearDown(); } @@ -1270,7 +1295,8 @@ TEST_F(AbsolutePathProductDependencyTest, AbsolutePathProductDependency_RetryDef AZ::Data::AssetType::CreateNull()); m_assetProcessorManager->m_stateData->SetProduct(matchingProductForDependency); - m_assetProcessorManager->m_pathDependencyManager->RetryDeferredDependencies(matchingSource); + m_assetProcessorManager->m_pathDependencyManager->QueueSourceForDependencyResolution(matchingSource); + m_assetProcessorManager->m_pathDependencyManager->ProcessQueuedDependencyResolves(); // The product dependency ID shouldn't change when it goes from unresolved to resolved. AZStd::vector resolvedProductDependencies; @@ -1405,6 +1431,7 @@ bool PathDependencyTest::ProcessAsset(TestAsset& asset, const OutputAssetSet& ou // tell the APM that the asset has been processed and allow it to bubble through its event queue: m_isIdling = false; m_assetProcessorManager->AssetProcessed(capturedDetails[jobSet].m_jobEntry, processJobResponse); + m_assetProcessorManager->CheckForIdle(); jobSet++; } @@ -2646,6 +2673,44 @@ TEST_F(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDepende ASSERT_NE(SearchDependencies(dependencyContainer, asset1.m_products[0]), SearchDependencies(dependencyContainer, asset1.m_products[1])); } +TEST_F(MultiplatformPathDependencyTest, SameFilenameForAllPlatforms) +{ + TestAsset asset2("asset2"); + bool result = ProcessAsset( + asset2, { { ".output" }, { ".output" } }, { { "*1.output", AssetBuilderSDK::ProductPathDependencyType::ProductFile } }, "subfolder1/", + ".txt"); + + ASSERT_TRUE(result); + + TestAsset asset1("asset1"); + result = ProcessAsset(asset1, { { ".output" }, { ".output" } }, {}); + + ASSERT_TRUE(result); + + AssetDatabaseConnection* sharedConnection = m_assetProcessorManager->m_stateData.get(); + ASSERT_TRUE(sharedConnection); + + AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer dependencyContainer; + + sharedConnection->GetProductDependencies(dependencyContainer); + int resolvedCount = 0; + int unresolvedCount = 0; + for (const auto& dep : dependencyContainer) + { + if (dep.m_unresolvedPath.empty()) + { + resolvedCount++; + } + else + { + unresolvedCount++; + } + } + ASSERT_EQ(resolvedCount, 2); + ASSERT_EQ(unresolvedCount, 2); + VerifyDependencies(dependencyContainer, { asset1.m_products[0], asset1.m_products[1] }, { "*1.output", "*1.output" }); +} + TEST_F(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_SourcePath) { // One product will be pc, one will be console (order is non-deterministic) @@ -4185,7 +4250,7 @@ TEST_F(LockedFileTest, DeleteFile_LockedProduct_DeleteFails) auto theFile = m_data->m_absolutePath[1].toUtf8(); const char* theFileString = theFile.constData(); auto [sourcePath, productPath] = *m_data->m_productPaths.find(theFileString); - + { QFile file(theFileString); file.remove(); @@ -4257,7 +4322,7 @@ TEST_F(LockedFileTest, DeleteFile_LockedProduct_DeletesWhenReleased) EXPECT_FALSE(QFile::exists(productPath)); EXPECT_EQ(m_data->m_deletedSources.size(), 1); - + EXPECT_GT(m_deleteCounter, 1); // Make sure the AP tried more than once to delete the file m_errorAbsorber->ExpectAsserts(0); } @@ -5364,7 +5429,7 @@ AZStd::vector WildcardSourceDependencyTest::FileAddedTest(const Q void WildcardSourceDependencyTest::SetUp() { AssetProcessorManagerTest::SetUp(); - + QDir tempPath(m_tempDir.path()); // Add a non-recursive scan folder. Only files directly inside of this folder should be picked up, subfolders are ignored @@ -5454,7 +5519,7 @@ TEST_F(WildcardSourceDependencyTest, Relative_Broad) { // Expect all files except for the 2 invalid ones (e and f) AZStd::vector resolvedPaths; - + ASSERT_TRUE(Test("*.foo", resolvedPaths)); ASSERT_THAT(resolvedPaths, ::testing::UnorderedElementsAre("a.foo", "b.foo", "folder/one/c.foo", "folder/one/d.foo", "1a.foo", "1b.foo")); } @@ -5585,7 +5650,7 @@ TEST_F(WildcardSourceDependencyTest, Relative_CacheFolder) { AZStd::vector resolvedPaths; QDir tempPath(m_tempDir.path()); - + ASSERT_TRUE(Test("*cache.foo", resolvedPaths)); ASSERT_THAT(resolvedPaths, ::testing::UnorderedElementsAre()); } @@ -5635,7 +5700,7 @@ TEST_F(WildcardSourceDependencyTest, FilesRemovedAfterInitialCache) ASSERT_EQ(excludedFolders.size(), 3); } - + m_fileStateCache->SignalDeleteEvent(tempPath.absoluteFilePath("subfolder2/redirected/folder/two/ignored")); const auto& excludedFolders = excludedFolderCacheInterface->GetExcludedFolders(); diff --git a/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.h b/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.h index 7bbef41f44..c532b08016 100644 --- a/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.h +++ b/Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.h @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include #include "resourcecompiler/rccontroller.h" @@ -39,7 +41,7 @@ class AssetProcessorManagerTest : public AssetProcessor::AssetProcessorTest { public: - + AssetProcessorManagerTest(); virtual ~AssetProcessorManagerTest() @@ -67,16 +69,19 @@ protected: { AZStd::string m_databaseLocation; ::testing::NiceMock m_databaseLocationListener; + AZ::Entity* m_jobManagerEntity{}; + AZ::ComponentDescriptor* m_descriptor{}; + AZStd::unique_ptr m_serializeContext; }; AZStd::unique_ptr m_data; - + private: int m_argc; char** m_argv; AZStd::unique_ptr m_scopeDir; - AZStd::unique_ptr m_qApp; + AZStd::unique_ptr m_qApp; }; struct AbsolutePathProductDependencyTest diff --git a/Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp b/Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp index 7543e9ec8b..c62d822171 100644 --- a/Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp @@ -51,7 +51,7 @@ namespace AssetProcessor case AZ::SettingsRegistryInterface::VisitAction::Begin: { // Only continue traversal if the path is exactly the AssetProcessorSettingsKey (which indicates the start of traversal) - // or if a "Platform *" object and it's children are being traversed + // or if a "Platform *" object and it's children are being traversed if (jsonPath == AssetProcessorSettingsKey) { return AZ::SettingsRegistryInterface::VisitResponse::Continue; @@ -631,7 +631,7 @@ namespace AssetProcessor for (const AssetBuilderSDK::PlatformInfo& platform : m_enabledPlatforms) { AZStd::string_view currentRCParams = assetRecognizer.m_defaultParams; - // The "/Amazon/AssetProcessor/Settings/RC */" entry will be queried + // The "/Amazon/AssetProcessor/Settings/RC */" entry will be queried AZ::IO::Path overrideParamsKey = AZ::IO::Path(AZ::IO::PosixPathSeparator); overrideParamsKey /= path; overrideParamsKey /= platform.m_identifier; @@ -644,7 +644,7 @@ namespace AssetProcessor } else { - // otherwise check for tags associated with the platform + // otherwise check for tags associated with the platform for (const AZStd::string& tag : platform.m_tags) { overrideParamsKey.ReplaceFilename(AZ::IO::PathView(tag)); @@ -1416,6 +1416,8 @@ namespace AssetProcessor return QString(); } + auto* fileStateInterface = AZ::Interface::Get(); + for (int pathIdx = 0; pathIdx < m_scanFolders.size(); ++pathIdx) { AssetProcessor::ScanFolderInfo scanFolderInfo = m_scanFolders[pathIdx]; @@ -1430,7 +1432,7 @@ namespace AssetProcessor QDir rooted(scanFolderInfo.ScanPath()); QString absolutePath = rooted.absoluteFilePath(tempRelativeName); AssetProcessor::FileStateInfo fileStateInfo; - auto* fileStateInterface = AZ::Interface::Get(); + if (fileStateInterface) { if (fileStateInterface->GetFileInfo(absolutePath, &fileStateInfo)) @@ -1499,7 +1501,7 @@ namespace AssetProcessor QRegExp nameMatch{ posixRelativeName, Qt::CaseInsensitive, QRegExp::Wildcard }; AZStd::stack dirs; dirs.push(sourceFolderDir.absolutePath()); - + while (!dirs.empty()) { QString absolutePath = dirs.top(); @@ -1528,7 +1530,7 @@ namespace AssetProcessor continue; } } - + QString pathMatch{ sourceFolderDir.relativeFilePath(dirIterator.filePath()) }; if (nameMatch.exactMatch(pathMatch)) { diff --git a/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp b/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp index 6bcd0dec01..a6cbfd8077 100644 --- a/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp @@ -131,7 +131,7 @@ namespace AssetUtilsInternal } } } while (!timer.hasExpired(waitTimeInSeconds * 1000)); //We will keep retrying until the timer has expired the inputted timeout - + // once we're done, regardless of success or failure, we 'unlock' those files for further process. // if we failed, also re-trigger them to rebuild (the bool param at the end of the ebus call) QString normalized = AssetUtilities::NormalizeFilePath(outputFile); @@ -870,23 +870,27 @@ namespace AssetUtilities return true; } - QString StripAssetPlatform(AZStd::string_view relativeProductPath) + AZStd::string_view StripAssetPlatformNoCopy(AZStd::string_view relativeProductPath) { // Skip over the assetPlatform path segment if it is matches one of the platform defaults // Otherwise return the path unchanged - AZStd::string_view strippedProductPath{ relativeProductPath }; - if (AZStd::optional pathSegment = AZ::StringFunc::TokenizeNext(strippedProductPath, AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR); - pathSegment.has_value()) + + AZStd::string_view originalPath = relativeProductPath; + AZStd::optional firstPathSegment = AZ::StringFunc::TokenizeNext(relativeProductPath, AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR); + + if (firstPathSegment && AzFramework::PlatformHelper::GetPlatformIdFromName(*firstPathSegment) != AzFramework::PlatformId::Invalid) { - AZ::IO::FixedMaxPathString assetPlatformSegmentLower{ *pathSegment }; - AZStd::to_lower(assetPlatformSegmentLower.begin(), assetPlatformSegmentLower.end()); - if (AzFramework::PlatformHelper::GetPlatformIdFromName(assetPlatformSegmentLower) != AzFramework::PlatformId::Invalid) - { - return QString::fromUtf8(strippedProductPath.data(), aznumeric_cast(strippedProductPath.size())); - } + return relativeProductPath; } - return QString::fromUtf8(relativeProductPath.data(), aznumeric_cast(relativeProductPath.size())); + return originalPath; + } + + QString StripAssetPlatform(AZStd::string_view relativeProductPath) + { + AZStd::string_view result = StripAssetPlatformNoCopy(relativeProductPath); + + return QString::fromUtf8(result.data(), aznumeric_cast(result.size())); } QString NormalizeFilePath(const QString& filePath) diff --git a/Code/Tools/AssetProcessor/native/utilities/assetUtils.h b/Code/Tools/AssetProcessor/native/utilities/assetUtils.h index 46ec5d6145..18cf5422de 100644 --- a/Code/Tools/AssetProcessor/native/utilities/assetUtils.h +++ b/Code/Tools/AssetProcessor/native/utilities/assetUtils.h @@ -145,7 +145,7 @@ namespace AssetUtilities //! Strips the first "asset platform" from the first path segment of a relative product path //! This is meant for removing the asset platform for paths such as "pc/MyAssetFolder/MyAsset.asset" //! Therefore the result here becomes "MyAssetFolder/MyAsset" - //! + //! //! Similarly invoking this function on relative path that begins with the "server" platform //! "server/AssetFolder/Server.asset2" -> "AssetFolder/Server.asset2" //! This function does not strip an asset platform from anywhere, but the first path segment @@ -153,6 +153,10 @@ namespace AssetUtilities //! would return a copy of the relative path QString StripAssetPlatform(AZStd::string_view relativeProductPath); + //! Same as StripAssetPlatform, but does not perform any string copies + //! The return result is only valid for as long as the original input is valid + AZStd::string_view StripAssetPlatformNoCopy(AZStd::string_view relativeProductPath); + //! Converts all slashes to forward slashes, removes double slashes, //! replaces all indirections such as '.' or '..' as appropriate. //! On windows, the drive letter (if present) is converted to uppercase. From 3f0bd9285372e41b3634b26aa9b342da9a527913 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Thu, 13 Jan 2022 10:28:58 -0600 Subject: [PATCH 170/272] Removed some unused EditorUtils functions Signed-off-by: Chris Galvan --- Code/Editor/Util/EditorUtils.cpp | 17 -- Code/Editor/Util/EditorUtils.h | 165 ------------------ .../Editor/Animation/Util/UiEditorUtils.cpp | 17 -- 3 files changed, 199 deletions(-) diff --git a/Code/Editor/Util/EditorUtils.cpp b/Code/Editor/Util/EditorUtils.cpp index adae34773a..47264a51ab 100644 --- a/Code/Editor/Util/EditorUtils.cpp +++ b/Code/Editor/Util/EditorUtils.cpp @@ -176,23 +176,6 @@ QString TrimTrailingZeros(QString str) return str; } -////////////////////////////////////////////////////////////////////////// -// This function is supposed to format float in user-friendly way, -// omitting the exponent notation. -// -// Why not using printf? Its formatting rules has following drawbacks: -// %g - will use exponent for small numbers; -// %.Nf - doesn't allow to control total amount of significant numbers, -// which exposes limited precision during binary-to-decimal fraction -// conversion. -////////////////////////////////////////////////////////////////////////// -void FormatFloatForUI(QString& str, int significantDigits, double value) -{ - str = TrimTrailingZeros(QString::number(value, 'f', significantDigits)); - return; -} -//////////////////////////////////////////////////////////////////////////- - ////////////////////////////////////////////////////////////////////////// QColor ColorLinearToGamma(ColorF col) { diff --git a/Code/Editor/Util/EditorUtils.h b/Code/Editor/Util/EditorUtils.h index e950d75012..5a69633d0f 100644 --- a/Code/Editor/Util/EditorUtils.h +++ b/Code/Editor/Util/EditorUtils.h @@ -212,22 +212,6 @@ namespace XmlHelpers ////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// Drag Drop helper functions -////////////////////////////////////////////////////////////////////////// -namespace EditorDragDropHelpers -{ - inline QString GetAnimationNameClipboardFormat() - { - return QStringLiteral("application/x-animation-browser-copy"); - } - - inline QString GetFragmentClipboardFormat() - { - return QStringLiteral("application/x-preview-fragment-properties"); - } -} - ////////////////////////////////////////////////////////////////////////// /*! @@ -292,116 +276,6 @@ public: } }; - -////////////////////////////////////////////////////////////////////////// -// -// Convert String representation of color to RGB integer value. -// -////////////////////////////////////////////////////////////////////////// -inline QColor String2Color(const QString& val) -{ - unsigned int r = 0, g = 0, b = 0; - int res = 0; - res = azsscanf(val.toUtf8().data(), "R:%d,G:%d,B:%d", &r, &g, &b); - if (res != 3) - { - res = azsscanf(val.toUtf8().data(), "R:%d G:%d B:%d", &r, &g, &b); - } - if (res != 3) - { - res = azsscanf(val.toUtf8().data(), "%d,%d,%d", &r, &g, &b); - } - if (res != 3) - { - res = azsscanf(val.toUtf8().data(), "%d %d %d", &r, &g, &b); - } - if (res != 3) - { - azsscanf(val.toUtf8().data(), "%x", &r); - return r; - } - - return QColor(r, g, b); -} - -// Converts QColor to Vector. -inline Vec3 Rgb2Vec(const QColor& color) -{ - return Vec3(aznumeric_cast(color.redF()), aznumeric_cast(color.greenF()), aznumeric_cast(color.blueF())); -} - -// Converts QColor to ColorF. -inline ColorF Rgb2ColorF(const QColor& color) -{ - return ColorF(aznumeric_cast(color.redF()), aznumeric_cast(color.greenF()), aznumeric_cast(color.blueF()), 1.0f); -} - -// Converts QColor to Vector. -inline QColor Vec2Rgb(const Vec3& color) -{ - return QColor(aznumeric_cast(color.x * 255), aznumeric_cast(color.y * 255), aznumeric_cast(color.z * 255)); -} - -// Converts ColorF to QColor. -inline QColor ColorF2Rgb(const ColorF& color) -{ - return QColor(aznumeric_cast(color.r * 255), aznumeric_cast(color.g * 255), aznumeric_cast(color.b * 255)); -} - -////////////////////////////////////////////////////////////////////////// -// Tokenize string. -////////////////////////////////////////////////////////////////////////// -inline QString TokenizeString(const QString& s, LPCSTR pszTokens, int& iStart) -{ - assert(iStart >= 0); - - QByteArray str = s.toUtf8(); - - if (pszTokens == nullptr) - { - return str; - } - - auto pszPlace = str.begin() + iStart; - auto pszEnd = str.end(); - if (pszPlace < pszEnd) - { - int nIncluding = (int)strspn(pszPlace, pszTokens); - ; - - if ((pszPlace + nIncluding) < pszEnd) - { - pszPlace += nIncluding; - int nExcluding = (int)strcspn(pszPlace, pszTokens); - - int iFrom = iStart + nIncluding; - int nUntil = nExcluding; - iStart = iFrom + nUntil + 1; - - return (str.mid(iFrom, nUntil)); - } - } - - // return empty string, done tokenizing - iStart = -1; - return ""; -} - -// This template function will join strings from a vector into a single string, using a separator char -template -inline void JoinStrings(const QList& rStrings, QString& rDestStr, char aSeparator = ',') -{ - for (size_t i = 0, iCount = rStrings.size(); i < iCount; ++i) - { - rDestStr += rStrings[i]; - - if (i < iCount - 1) - { - rDestStr += aSeparator; - } - } -} - // This function will split a string containing separated strings, into a vector of strings // better version of TokenizeString inline void SplitString(const QString& rSrcStr, QStringList& rDestStrings, char aSeparator = ',') @@ -435,45 +309,6 @@ inline void SplitString(const QString& rSrcStr, QStringList& rDestStrings, char } } -// Format unsigned number to string with 1000s separator -inline QString FormatWithThousandsSeperator(const unsigned int number) -{ - QString string; - - string = QString::number(number); - - for (int p = string.length() - 3; p > 0; p -= 3) - { - string.insert(p, ','); - } - - return string; -} - - -void FormatFloatForUI(QString& str, int significantDigits, double value); - -////////////////////////////////////////////////////////////////////////// -// Simply sub string searching case insensitive. -////////////////////////////////////////////////////////////////////////// -inline const char* strstri(const char* pString, const char* pSubstring) -{ - int i, j, k; - for (i = 0; pString[i]; i++) - { - for (j = i, k = 0; tolower(pString[j]) == tolower(pSubstring[k]); j++, k++) - { - if (!pSubstring[k + 1]) - { - return (pString + i); - } - } - } - - return nullptr; -} - - inline bool CheckVirtualKey(Qt::MouseButton button) { return (qApp->property("pressedMouseButtons").toInt() & button) != 0; diff --git a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp index 41f7300002..85270df355 100644 --- a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp +++ b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp @@ -92,23 +92,6 @@ QString TrimTrailingZeros(QString str) return str; } -////////////////////////////////////////////////////////////////////////// -// This function is supposed to format float in user-friendly way, -// omitting the exponent notation. -// -// Why not using printf? Its formatting rules has following drawbacks: -// %g - will use exponent for small numbers; -// %.Nf - doesn't allow to control total amount of significant numbers, -// which exposes limited precision during binary-to-decimal fraction -// conversion. -////////////////////////////////////////////////////////////////////////// -void FormatFloatForUI(QString& str, int significantDigits, double value) -{ - str = TrimTrailingZeros(QString::number(value, 'f', significantDigits)); - return; -} -//////////////////////////////////////////////////////////////////////////- - ////////////////////////////////////////////////////////////////////////// QColor ColorLinearToGamma(ColorF col) { From 62e7483b0e7a025369c09fcd92bcf326ea71a131 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Thu, 13 Jan 2022 14:44:59 -0600 Subject: [PATCH 171/272] Switched GradientSignal to use GemTestEnvironment. (#6886) This allows actual Shape components to be used instead of MockShapes, which is important for the benchmarks to get accurate results as Mocks are extremely expensive. It also removes a lot of unnecessary mock handling and test setup code. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../EditorGradientSignalPreviewTests.cpp | 38 +++-- .../Code/Tests/GradientSignalImageTests.cpp | 31 ++-- .../Tests/GradientSignalReferencesTests.cpp | 38 ++--- .../Tests/GradientSignalServicesTests.cpp | 10 +- .../Code/Tests/GradientSignalSurfaceTests.cpp | 10 +- .../Code/Tests/GradientSignalTest.cpp | 47 +++--- .../Code/Tests/GradientSignalTestFixtures.cpp | 134 ++++++++---------- .../Code/Tests/GradientSignalTestFixtures.h | 84 +++++------ .../Code/Tests/ImageAssetTests.cpp | 21 +-- 9 files changed, 193 insertions(+), 220 deletions(-) diff --git a/Gems/GradientSignal/Code/Tests/EditorGradientSignalPreviewTests.cpp b/Gems/GradientSignal/Code/Tests/EditorGradientSignalPreviewTests.cpp index e8bd9f2dff..83892f1c69 100644 --- a/Gems/GradientSignal/Code/Tests/EditorGradientSignalPreviewTests.cpp +++ b/Gems/GradientSignal/Code/Tests/EditorGradientSignalPreviewTests.cpp @@ -29,21 +29,34 @@ namespace UnitTest { GradientSignalTest::SetUp(); - // Set up job manager with two threads so that we can run and test the preview job logic. - AZ::JobManagerDesc desc; - AZ::JobManagerThreadDesc threadDesc; - desc.m_workerThreads.push_back(threadDesc); - desc.m_workerThreads.push_back(threadDesc); - m_jobManager = aznew AZ::JobManager(desc); - m_jobContext = aznew AZ::JobContext(*m_jobManager); - AZ::JobContext::SetGlobalContext(m_jobContext); + auto globalContext = AZ::JobContext::GetGlobalContext(); + if (globalContext) + { + AZ_Assert( + globalContext->GetJobManager().GetNumWorkerThreads() >= 2, + "Job Manager previously started by test environment with too few threads for this test."); + } + else + { + // Set up job manager with two threads so that we can run and test the preview job logic. + AZ::JobManagerDesc desc; + AZ::JobManagerThreadDesc threadDesc; + desc.m_workerThreads.push_back(threadDesc); + desc.m_workerThreads.push_back(threadDesc); + m_jobManager = aznew AZ::JobManager(desc); + m_jobContext = aznew AZ::JobContext(*m_jobManager); + AZ::JobContext::SetGlobalContext(m_jobContext); + } } void TearDown() override { - AZ::JobContext::SetGlobalContext(nullptr); - delete m_jobContext; - delete m_jobManager; + if (m_jobContext) + { + AZ::JobContext::SetGlobalContext(nullptr); + delete m_jobContext; + delete m_jobManager; + } GradientSignalTest::TearDown(); } @@ -180,4 +193,5 @@ namespace UnitTest } } -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); +// This uses a custom test hook so that we can load LmbrCentral and use Shape components in our unit tests. +AZ_UNIT_TEST_HOOK(new UnitTest::GradientSignalTestEnvironment); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp index 5cd3c7edf6..8ec190000d 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalImageTests.cpp @@ -14,10 +14,13 @@ #include #include #include +#include #include #include +#include + namespace UnitTest { struct GradientSignalImageTestsFixture @@ -89,23 +92,21 @@ namespace UnitTest test.m_imageSize, test.m_imageSize, static_cast(test.m_pixel.GetX()), static_cast(test.m_pixel.GetY())); config.m_tilingX = test.m_tiling; config.m_tilingY = test.m_tiling; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); // Create the Gradient Transform Component. GradientSignal::GradientTransformConfig gradientTransformConfig; gradientTransformConfig.m_wrappingType = test.m_wrappingType; - CreateComponent(entity.get(), gradientTransformConfig); + entity->CreateComponent(gradientTransformConfig); - // Create a mock Shape component that describes the bounds that we're using to map our ImageGradient into world space. - CreateComponent(entity.get()); - MockShapeComponentHandler mockShapeHandler(entity->GetId()); - mockShapeHandler.m_GetLocalBounds = AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds); + LmbrCentral::BoxShapeConfig boxConfig(AZ::Vector3(shapeHalfBounds * 2.0f)); + auto boxComponent = entity->CreateComponent(LmbrCentral::AxisAlignedBoxShapeComponentTypeId); + boxComponent->SetConfiguration(boxConfig); - // Create a mock Transform component that locates our ImageGradient in the center of our desired mock Shape. - MockTransformHandler mockTransformHandler; - mockTransformHandler.m_GetLocalTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)); - mockTransformHandler.m_GetWorldTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)); - mockTransformHandler.BusConnect(entity->GetId()); + // Create a transform that locates our gradient in the center of our desired mock Shape. + auto transform = entity->CreateComponent(); + transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); + transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); // All components are created, so activate the entity ActivateEntity(entity.get()); @@ -365,7 +366,7 @@ namespace UnitTest mockShapeTransformHandler.BusConnect(mockShape->GetId()); // Create the mock shape that maps our 3x3 image to a 3x3 sample space in the world. - CreateComponent(mockShape.get()); + mockShape->CreateComponent(); MockShapeComponentHandler mockShapeComponentHandler(mockShape->GetId()); // Create a 2x2 box shape (shapes are inclusive, so that's 3x3 sampling space), so that each pixel in the image directly maps to 1 meter in the box. mockShapeComponentHandler.m_GetEncompassingAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(2.0f)); @@ -379,7 +380,7 @@ namespace UnitTest // Create an ImageGradient with a 3x3 asset with the center pixel set. GradientSignal::ImageGradientConfig gradientConfig; gradientConfig.m_imageAsset = ImageAssetMockAssetHandler::CreateSpecificPixelImageAsset(3, 3, 1, 1); - CreateComponent(entity.get(), gradientConfig); + entity->CreateComponent(gradientConfig); // Create the test GradientTransform GradientSignal::GradientTransformConfig config; @@ -400,7 +401,7 @@ namespace UnitTest config.m_overrideRotate = false; config.m_overrideScale = false; config.m_is3d = false; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); // Set up the transform on the gradient entity. MockTransformHandler mockTransformHandler; @@ -409,7 +410,7 @@ namespace UnitTest mockTransformHandler.BusConnect(entity->GetId()); // Put a default shape on our gradient entity. This is only used for previews, so it doesn't matter what it gets set to. - CreateComponent(entity.get()); + entity->CreateComponent(); MockShapeComponentHandler mockShapeHandler(entity->GetId()); ActivateEntity(entity.get()); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp index cc91c58fce..72bdfa202e 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp @@ -55,7 +55,7 @@ namespace UnitTest config.m_layers.push_back(layer); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -88,7 +88,7 @@ namespace UnitTest config.m_smoothStep.m_falloffStrength = falloffStrength; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -391,7 +391,7 @@ namespace UnitTest GradientSignal::ReferenceGradientConfig referenceGradientConfig1; referenceGradientConfig1.m_gradientSampler.m_ownerEntityId = referenceGradientEntity1->GetId(); referenceGradientConfig1.m_gradientSampler.m_gradientId = constantGradientEntity->GetId(); - CreateComponent(referenceGradientEntity1.get(), referenceGradientConfig1); + referenceGradientEntity1->CreateComponent(referenceGradientConfig1); ActivateEntity(referenceGradientEntity1.get()); EXPECT_TRUE(referenceGradientConfig1.m_gradientSampler.ValidateGradientEntityId()); @@ -400,7 +400,7 @@ namespace UnitTest GradientSignal::ReferenceGradientConfig referenceGradientConfig2; referenceGradientConfig2.m_gradientSampler.m_ownerEntityId = referenceGradientEntity2->GetId(); referenceGradientConfig2.m_gradientSampler.m_gradientId = referenceGradientEntity1->GetId(); - CreateComponent(referenceGradientEntity2.get(), referenceGradientConfig2); + referenceGradientEntity2->CreateComponent(referenceGradientConfig2); ActivateEntity(referenceGradientEntity2.get()); EXPECT_TRUE(referenceGradientConfig2.m_gradientSampler.ValidateGradientEntityId()); @@ -409,7 +409,7 @@ namespace UnitTest GradientSignal::ReferenceGradientConfig referenceGradientConfig3; referenceGradientConfig3.m_gradientSampler.m_ownerEntityId = referenceGradientEntity3->GetId(); referenceGradientConfig3.m_gradientSampler.m_gradientId = referenceGradientEntity3->GetId(); - CreateComponent(referenceGradientEntity3.get(), referenceGradientConfig3); + referenceGradientEntity3->CreateComponent(referenceGradientConfig3); ActivateEntity(referenceGradientEntity3.get()); EXPECT_FALSE(referenceGradientConfig3.m_gradientSampler.ValidateGradientEntityId()); EXPECT_EQ(referenceGradientConfig3.m_gradientSampler.m_gradientId, AZ::EntityId()); @@ -422,19 +422,19 @@ namespace UnitTest GradientSignal::ReferenceGradientConfig referenceGradientConfig4; referenceGradientConfig4.m_gradientSampler.m_ownerEntityId = referenceGradientEntity4->GetId(); referenceGradientConfig4.m_gradientSampler.m_gradientId = referenceGradientEntity5->GetId(); - CreateComponent(referenceGradientEntity4.get(), referenceGradientConfig4); + referenceGradientEntity4->CreateComponent(referenceGradientConfig4); ActivateEntity(referenceGradientEntity4.get()); GradientSignal::ReferenceGradientConfig referenceGradientConfig5; referenceGradientConfig5.m_gradientSampler.m_ownerEntityId = referenceGradientEntity5->GetId(); referenceGradientConfig5.m_gradientSampler.m_gradientId = referenceGradientEntity6->GetId(); - CreateComponent(referenceGradientEntity5.get(), referenceGradientConfig5); + referenceGradientEntity5->CreateComponent(referenceGradientConfig5); ActivateEntity(referenceGradientEntity5.get()); GradientSignal::ReferenceGradientConfig referenceGradientConfig6; referenceGradientConfig6.m_gradientSampler.m_ownerEntityId = referenceGradientEntity6->GetId(); referenceGradientConfig6.m_gradientSampler.m_gradientId = referenceGradientEntity4->GetId(); - CreateComponent(referenceGradientEntity6.get(), referenceGradientConfig6); + referenceGradientEntity6->CreateComponent(referenceGradientConfig6); ActivateEntity(referenceGradientEntity6.get()); EXPECT_FALSE(referenceGradientConfig6.m_gradientSampler.ValidateGradientEntityId()); @@ -456,7 +456,7 @@ namespace UnitTest // Create an AABB from -1 to 1, so points at coorindates 0 and 1 fall on it, but any points at coordinate 2 won't. auto entityShape = CreateEntity(); - CreateComponent(entityShape.get()); + entityShape->CreateComponent(); MockShapeComponentHandler mockShapeComponentHandler(entityShape->GetId()); mockShapeComponentHandler.m_GetEncompassingAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-1.0f), AZ::Vector3(1.0f)); @@ -466,7 +466,7 @@ namespace UnitTest config.m_falloffType = GradientSignal::FalloffType::Outer; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -481,7 +481,7 @@ namespace UnitTest // Create our test shape from -1 to 0, so we have a corner directly on (0, 0). auto entityShape = CreateEntity(); - CreateComponent(entityShape.get()); + entityShape->CreateComponent(); MockShapeComponentHandler mockShapeComponentHandler(entityShape->GetId()); mockShapeComponentHandler.m_GetEncompassingAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-1.0f), AZ::Vector3(0.0f)); @@ -512,7 +512,7 @@ namespace UnitTest } auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -533,7 +533,7 @@ namespace UnitTest // We're pinning a shape, so the bounding box of (0, 0, 0) - (10, 10, 10) will be the one that applies. auto entityShape = CreateEntity(); - CreateComponent(entityShape.get()); + entityShape->CreateComponent(); MockShapeComponentHandler mockShapeComponentHandler(entityShape->GetId()); mockShapeComponentHandler.m_GetEncompassingAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3::CreateZero(), AZ::Vector3(10.0f)); @@ -551,7 +551,7 @@ namespace UnitTest config.m_altitudeMax = 24.0f; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -584,7 +584,7 @@ namespace UnitTest config.m_altitudeMax = 10.0f; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -612,7 +612,7 @@ namespace UnitTest config.m_altitudeMax = 15.0f; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -649,7 +649,7 @@ namespace UnitTest config.m_altitudeMax = 15.0f; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -684,7 +684,7 @@ namespace UnitTest config.m_surfaceTagList.push_back(AZ_CRC("test_mask", 0x7a16e9ff)); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -711,7 +711,7 @@ namespace UnitTest config.m_surfaceTagList.push_back(AZ_CRC("test_mask", 0x7a16e9ff)); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp index ec770f038d..449719af67 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp @@ -31,7 +31,7 @@ namespace UnitTest config.m_value = expectedOutput; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); GradientSignal::GradientSampler gradientSampler; @@ -75,7 +75,7 @@ namespace UnitTest config.m_gradientSampler.m_gradientId = entityMock->GetId(); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -109,7 +109,7 @@ namespace UnitTest config.m_gradientSampler.m_gradientId = entityMock->GetId(); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -147,7 +147,7 @@ namespace UnitTest config.m_gradientSampler.m_gradientId = entityMock->GetId(); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -185,7 +185,7 @@ namespace UnitTest config.m_gradientSampler.m_gradientId = entityMock->GetId(); auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp index 702965c0de..a716fc79b8 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp @@ -44,11 +44,9 @@ namespace UnitTest // This lets our component register with surfaceData successfully. MockSurfaceDataSystem mockSurfaceDataSystem; - // Create a mock shape entity in case we want to use it. + // Create a mock shape entity in case our gradient test uses shape constraints. // The mock shape is a cube that goes from -0.5 to 0.5 in space. - auto mockShapeEntity = CreateEntity(); - CreateComponent(mockShapeEntity.get()); - MockShapeComponentHandler mockShapeHandler(mockShapeEntity->GetId()); + auto mockShapeEntity = CreateTestEntity(0.5f); ActivateEntity(mockShapeEntity.get()); // For ease of testing, use a constant gradient as our input gradient. @@ -76,8 +74,8 @@ namespace UnitTest // Create the test entity with the GradientSurfaceData component and the required gradient dependency auto entity = CreateEntity(); - CreateComponent(entity.get(), constantGradientConfig); - CreateComponent(entity.get(), config); + entity->CreateComponent(constantGradientConfig); + entity->CreateComponent(config); ActivateEntity(entity.get()); // Get our registered modifier handle (and verify that it's valid) diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTest.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTest.cpp index adc35e6738..13e535e072 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTest.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTest.cpp @@ -27,14 +27,12 @@ namespace UnitTest void TestLevelsGradientComponent(int dataSize, const AZStd::vector& inputData, const AZStd::vector& expectedOutput, float inputMin, float inputMid, float inputMax, float outputMin, float outputMax) { - auto entityMock = CreateEntity(); + auto entityMock = CreateTestEntity(1.0f); const AZ::EntityId id = entityMock->GetId(); UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entityMock.get(), gradientTransformConfig); - CreateComponent(entityMock.get()); - MockShapeComponentHandler mockShapeHandler(entityMock->GetId()); + entityMock->CreateComponent(gradientTransformConfig); ActivateEntity(entityMock.get()); @@ -47,7 +45,7 @@ namespace UnitTest config.m_outputMax = outputMax; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -56,14 +54,12 @@ namespace UnitTest void TestPosterizeGradientComponent(int dataSize, const AZStd::vector& inputData, const AZStd::vector& expectedOutput, GradientSignal::PosterizeGradientConfig::ModeType posterizeMode, int bands) { - auto entityMock = CreateEntity(); + auto entityMock = CreateTestEntity(0.5f); const AZ::EntityId id = entityMock->GetId(); UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entityMock.get(), gradientTransformConfig); - CreateComponent(entityMock.get()); - MockShapeComponentHandler mockShapeHandler(entityMock->GetId()); + entityMock->CreateComponent(gradientTransformConfig); ActivateEntity(entityMock.get()); @@ -73,7 +69,7 @@ namespace UnitTest config.m_bands = bands; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -82,14 +78,12 @@ namespace UnitTest void TestSmoothStepGradientComponent(int dataSize, const AZStd::vector& inputData, const AZStd::vector& expectedOutput, float midpoint, float range, float softness) { - auto entityMock = CreateEntity(); + auto entityMock = CreateTestEntity(0.5f); const AZ::EntityId id = entityMock->GetId(); UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entityMock.get(), gradientTransformConfig); - CreateComponent(entityMock.get()); - MockShapeComponentHandler mockShapeHandler(entityMock->GetId()); + entityMock->CreateComponent(gradientTransformConfig); ActivateEntity(entityMock.get()); @@ -100,7 +94,7 @@ namespace UnitTest config.m_smoothStep.m_falloffStrength = softness; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -108,14 +102,12 @@ namespace UnitTest void TestThresholdGradientComponent(int dataSize, const AZStd::vector& inputData, const AZStd::vector& expectedOutput, float threshold) { - auto entityMock = CreateEntity(); + auto entityMock = CreateTestEntity(0.5f); const AZ::EntityId id = entityMock->GetId(); UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entityMock.get(), gradientTransformConfig); - CreateComponent(entityMock.get()); - MockShapeComponentHandler mockShapeHandler(entityMock->GetId()); + entityMock->CreateComponent(gradientTransformConfig); ActivateEntity(entityMock.get()); @@ -124,7 +116,7 @@ namespace UnitTest config.m_threshold = threshold; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); @@ -167,11 +159,11 @@ namespace UnitTest AZStd::vector expectedOutput = { AZ_TRAIT_UNIT_TEST_PERLINE_GRADIANT_GOLDEN_VALUES_7878 }; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entity.get(), gradientTransformConfig); - CreateComponent(entity.get()); + entity->CreateComponent(gradientTransformConfig); + entity->CreateComponent(); MockShapeComponentHandler mockShapeHandler(entity->GetId()); ActivateEntity(entity.get()); @@ -197,11 +189,11 @@ namespace UnitTest config.m_randomSeed = 5656; auto entity = CreateEntity(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); GradientSignal::GradientTransformConfig gradientTransformConfig; - CreateComponent(entity.get(), gradientTransformConfig); - CreateComponent(entity.get()); + entity->CreateComponent(gradientTransformConfig); + entity->CreateComponent(); MockShapeComponentHandler mockShapeHandler(entity->GetId()); ActivateEntity(entity.get()); @@ -546,4 +538,5 @@ namespace UnitTest } } -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); +// This uses custom test / benchmark hooks so that we can load LmbrCentral and use Shape components in our unit tests and benchmarks. +AZ_UNIT_TEST_HOOK(new UnitTest::GradientSignalTestEnvironment, UnitTest::GradientSignalBenchmarkEnvironment); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp index 154e9032b2..d81370f6a8 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp @@ -10,7 +10,9 @@ #include #include +#include #include +#include // Base gradient components #include @@ -36,65 +38,48 @@ namespace UnitTest { + void GradientSignalTestEnvironment::AddGemsAndComponents() + { + AddDynamicModulePaths({ "LmbrCentral" }); + + AddComponentDescriptors({ + AzFramework::TransformComponent::CreateDescriptor(), + + GradientSignal::ConstantGradientComponent::CreateDescriptor(), + GradientSignal::DitherGradientComponent::CreateDescriptor(), + GradientSignal::GradientSurfaceDataComponent::CreateDescriptor(), + GradientSignal::GradientTransformComponent::CreateDescriptor(), + GradientSignal::ImageGradientComponent::CreateDescriptor(), + GradientSignal::InvertGradientComponent::CreateDescriptor(), + GradientSignal::LevelsGradientComponent::CreateDescriptor(), + GradientSignal::MixedGradientComponent::CreateDescriptor(), + GradientSignal::PerlinGradientComponent::CreateDescriptor(), + GradientSignal::PosterizeGradientComponent::CreateDescriptor(), + GradientSignal::RandomGradientComponent::CreateDescriptor(), + GradientSignal::ReferenceGradientComponent::CreateDescriptor(), + GradientSignal::ShapeAreaFalloffGradientComponent::CreateDescriptor(), + GradientSignal::SmoothStepGradientComponent::CreateDescriptor(), + GradientSignal::SurfaceAltitudeGradientComponent::CreateDescriptor(), + GradientSignal::SurfaceMaskGradientComponent::CreateDescriptor(), + GradientSignal::SurfaceSlopeGradientComponent::CreateDescriptor(), + GradientSignal::ThresholdGradientComponent::CreateDescriptor(), + + MockShapeComponent::CreateDescriptor(), + }); + } + void GradientSignalBaseFixture::SetupCoreSystems() { - m_app = AZStd::make_unique(); - ASSERT_TRUE(m_app != nullptr); - - AZ::ComponentApplication::Descriptor componentAppDesc; - - m_systemEntity = m_app->Create(componentAppDesc); - ASSERT_TRUE(m_systemEntity != nullptr); - m_app->AddEntity(m_systemEntity); - - AZ::AllocatorInstance::Create(); - AZ::Data::AssetManager::Descriptor desc; - AZ::Data::AssetManager::Create(desc); - m_mockHandler = new ImageAssetMockAssetHandler(); + m_mockHandler = new UnitTest::ImageAssetMockAssetHandler(); AZ::Data::AssetManager::Instance().RegisterHandler(m_mockHandler, azrtti_typeid()); - - m_mockShapeHandlers = new AZStd::vector>>(); } void GradientSignalBaseFixture::TearDownCoreSystems() { - // Clear any mock shape handlers that we've created for our test entities. - delete m_mockShapeHandlers; - AZ::Data::AssetManager::Instance().UnregisterHandler(m_mockHandler); delete m_mockHandler; // delete after removing from the asset manager AzFramework::LegacyAssetEventBus::ClearQueuedEvents(); - AZ::Data::AssetManager::Destroy(); - AZ::AllocatorInstance::Destroy(); - - m_app->Destroy(); - m_app.reset(); - m_systemEntity = nullptr; - } - - AZStd::unique_ptr> GradientSignalBaseFixture::CreateMockShape( - const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId) - { - AZStd::unique_ptr> mockShape = - AZStd::make_unique>(shapeEntityId); - - ON_CALL(*mockShape, GetEncompassingAabb).WillByDefault(testing::Return(spawnerBox)); - ON_CALL(*mockShape, GetTransformAndLocalBounds) - .WillByDefault( - [spawnerBox](AZ::Transform& transform, AZ::Aabb& bounds) - { - transform = AZ::Transform::CreateTranslation(spawnerBox.GetCenter()); - bounds = spawnerBox.GetTranslated(-spawnerBox.GetCenter()); - }); - ON_CALL(*mockShape, IsPointInside) - .WillByDefault( - [spawnerBox](const AZ::Vector3& point) -> bool - { - return spawnerBox.Contains(point); - }); - - return mockShape; } AZStd::unique_ptr GradientSignalBaseFixture::CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox) @@ -130,16 +115,12 @@ namespace UnitTest // Create the base entity AZStd::unique_ptr testEntity = CreateEntity(); - // Create a mock Shape component that describes the bounds that we're using to map our gradient into world space. - CreateComponent(testEntity.get()); - - // Create and keep a reference to a mock shape handler that will respond to shape requests for the mock shape. - auto mockShapeHandler = - CreateMockShape(AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds), testEntity->GetId()); - m_mockShapeHandlers->push_back(AZStd::move(mockShapeHandler)); + LmbrCentral::BoxShapeConfig boxConfig(AZ::Vector3(shapeHalfBounds * 2.0f)); + auto boxComponent = testEntity->CreateComponent(LmbrCentral::AxisAlignedBoxShapeComponentTypeId); + boxComponent->SetConfiguration(boxConfig); // Create a transform that locates our gradient in the center of our desired mock Shape. - auto transform = CreateComponent(testEntity.get()); + auto transform = testEntity->CreateComponent(); transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds))); @@ -152,7 +133,7 @@ namespace UnitTest auto entity = CreateTestEntity(shapeHalfBounds); GradientSignal::ConstantGradientConfig config; config.m_value = 0.75f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -168,12 +149,12 @@ namespace UnitTest config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed); config.m_tilingX = 1.0f; config.m_tilingY = 1.0f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); // Create a Gradient Transform Component with arbitrary parameters. GradientSignal::GradientTransformConfig gradientTransformConfig; gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity.get(), gradientTransformConfig); + entity->CreateComponent(gradientTransformConfig); ActivateEntity(entity.get()); return entity; @@ -188,12 +169,12 @@ namespace UnitTest config.m_frequency = 1.1f; config.m_octave = 4; config.m_randomSeed = 12345; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); // Create a Gradient Transform Component with arbitrary parameters. GradientSignal::GradientTransformConfig gradientTransformConfig; gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity.get(), gradientTransformConfig); + entity->CreateComponent(gradientTransformConfig); ActivateEntity(entity.get()); return entity; @@ -205,12 +186,12 @@ namespace UnitTest auto entity = CreateTestEntity(shapeHalfBounds); GradientSignal::RandomGradientConfig config; config.m_randomSeed = 12345; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); // Create a Gradient Transform Component with arbitrary parameters. GradientSignal::GradientTransformConfig gradientTransformConfig; gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None; - CreateComponent(entity.get(), gradientTransformConfig); + entity->CreateComponent(gradientTransformConfig); ActivateEntity(entity.get()); return entity; @@ -224,7 +205,7 @@ namespace UnitTest config.m_shapeEntityId = entity->GetId(); config.m_falloffWidth = 16.0f; config.m_falloffType = GradientSignal::FalloffType::InnerOuter; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -238,10 +219,11 @@ namespace UnitTest GradientSignal::DitherGradientConfig config; config.m_gradientSampler.m_gradientId = inputGradientId; config.m_useSystemPointsPerUnit = false; - config.m_pointsPerUnit = 1.0f; + // Use a number other than 1.0f for pointsPerUnit to ensure the dither math is getting exercised properly. + config.m_pointsPerUnit = 0.25f; config.m_patternOffset = AZ::Vector3::CreateZero(); config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -254,7 +236,7 @@ namespace UnitTest auto entity = CreateTestEntity(shapeHalfBounds); GradientSignal::InvertGradientConfig config; config.m_gradientSampler.m_gradientId = inputGradientId; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -272,7 +254,7 @@ namespace UnitTest config.m_inputMax = 0.9f; config.m_outputMin = 0.0f; config.m_outputMax = 1.0f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -298,7 +280,7 @@ namespace UnitTest layer.m_gradientSampler.m_opacity = 0.75f; config.m_layers.push_back(layer); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -313,7 +295,7 @@ namespace UnitTest config.m_gradientSampler.m_gradientId = inputGradientId; config.m_mode = GradientSignal::PosterizeGradientConfig::ModeType::Ps; config.m_bands = 5; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -327,7 +309,7 @@ namespace UnitTest GradientSignal::ReferenceGradientConfig config; config.m_gradientSampler.m_gradientId = inputGradientId; config.m_gradientSampler.m_ownerEntityId = entity->GetId(); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -343,7 +325,7 @@ namespace UnitTest config.m_smoothStep.m_falloffMidpoint = 0.75f; config.m_smoothStep.m_falloffRange = 0.125f; config.m_smoothStep.m_falloffStrength = 0.25f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -357,7 +339,7 @@ namespace UnitTest GradientSignal::ThresholdGradientConfig config; config.m_gradientSampler.m_gradientId = inputGradientId; config.m_threshold = 0.75f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -370,7 +352,7 @@ namespace UnitTest GradientSignal::SurfaceAltitudeGradientConfig config; config.m_altitudeMin = -5.0f; config.m_altitudeMax = 15.0f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -382,7 +364,7 @@ namespace UnitTest auto entity = CreateTestEntity(shapeHalfBounds); GradientSignal::SurfaceMaskGradientConfig config; config.m_surfaceTagList.push_back(AZ_CRC_CE("test_mask")); - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; @@ -399,7 +381,7 @@ namespace UnitTest config.m_smoothStep.m_falloffMidpoint = 0.75f; config.m_smoothStep.m_falloffRange = 0.125f; config.m_smoothStep.m_falloffStrength = 0.25f; - CreateComponent(entity.get(), config); + entity->CreateComponent(config); ActivateEntity(entity.get()); return entity; diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h index 478f1c1d92..5fda88ea27 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h @@ -9,9 +9,39 @@ #include #include +#include namespace UnitTest { + // The GradientSignal unit tests need to use the GemTestEnvironment to load the LmbrCentral Gem so that Shape components can be used + // in the unit tests and benchmarks. + class GradientSignalTestEnvironment + : public AZ::Test::GemTestEnvironment + { + public: + void AddGemsAndComponents() override; + }; + +#ifdef HAVE_BENCHMARK + //! The Benchmark environment is used for one time setup and tear down of shared resources + class GradientSignalBenchmarkEnvironment + : public AZ::Test::BenchmarkEnvironmentBase + , public GradientSignalTestEnvironment + + { + protected: + void SetUpBenchmark() override + { + SetupEnvironment(); + } + + void TearDownBenchmark() override + { + TeardownEnvironment(); + } + }; +#endif + // Base test fixture used for GradientSignal unit tests and benchmark tests class GradientSignalBaseFixture { @@ -30,24 +60,6 @@ namespace UnitTest entity->Activate(); } - template - Component* CreateComponent(AZ::Entity* entity, const Configuration& config) - { - m_app->RegisterComponentDescriptor(Component::CreateDescriptor()); - return entity->CreateComponent(config); - } - - template - Component* CreateComponent(AZ::Entity* entity) - { - m_app->RegisterComponentDescriptor(Component::CreateDescriptor()); - return entity->CreateComponent(); - } - - // Create a mock shape that will respond to the shape bus with proper responses for the given input box. - AZStd::unique_ptr> CreateMockShape( - const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId); - // Create a mock SurfaceDataSystem that will respond to requests for surface points with mock responses for points inside // the given input box. AZStd::unique_ptr CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox); @@ -77,27 +89,22 @@ namespace UnitTest AZStd::unique_ptr BuildTestSurfaceMaskGradient(float shapeHalfBounds); AZStd::unique_ptr BuildTestSurfaceSlopeGradient(float shapeHalfBounds); - AZStd::unique_ptr m_app; - AZ::Entity* m_systemEntity = nullptr; - ImageAssetMockAssetHandler* m_mockHandler = nullptr; - AZStd::vector>>* m_mockShapeHandlers = nullptr; + UnitTest::ImageAssetMockAssetHandler* m_mockHandler = nullptr; }; struct GradientSignalTest : public GradientSignalBaseFixture - , public UnitTest::AllocatorsTestFixture + , public ::testing::Test { protected: void SetUp() override { - UnitTest::AllocatorsTestFixture::SetUp(); SetupCoreSystems(); } void TearDown() override { TearDownCoreSystems(); - UnitTest::AllocatorsTestFixture::TearDown(); } void TestFixedDataSampler(const AZStd::vector& expectedOutput, int size, AZ::EntityId gradientEntityId); @@ -106,41 +113,36 @@ namespace UnitTest #ifdef HAVE_BENCHMARK class GradientSignalBenchmarkFixture : public GradientSignalBaseFixture - , public UnitTest::AllocatorsBenchmarkFixture - , public UnitTest::TraceBusRedirector + , public ::benchmark::Fixture { public: - void internalSetUp(const benchmark::State& state) + void internalSetUp() { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - UnitTest::AllocatorsBenchmarkFixture::SetUp(state); SetupCoreSystems(); } - void internalTearDown(const benchmark::State& state) + void internalTearDown() { TearDownCoreSystems(); - UnitTest::AllocatorsBenchmarkFixture::TearDown(state); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); } protected: - void SetUp(const benchmark::State& state) override + void SetUp([[maybe_unused]] const benchmark::State& state) override { - internalSetUp(state); + internalSetUp(); } - void SetUp(benchmark::State& state) override + void SetUp([[maybe_unused]] benchmark::State& state) override { - internalSetUp(state); + internalSetUp(); } - void TearDown(const benchmark::State& state) override + void TearDown([[maybe_unused]] const benchmark::State& state) override { - internalTearDown(state); + internalTearDown(); } - void TearDown(benchmark::State& state) override + void TearDown([[maybe_unused]] benchmark::State& state) override { - internalTearDown(state); + internalTearDown(); } }; #endif diff --git a/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp b/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp index 0111f10c3a..7b1c260d45 100644 --- a/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp +++ b/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -64,26 +65,8 @@ namespace } } - class ImageAssetTest - : public ::testing::Test + class ImageAssetTest : public ::testing::Test { - protected: - AZ::ComponentApplication m_app; - AZ::Entity* m_systemEntity = nullptr; - - void SetUp() override - { - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_memoryBlocksByteSize = 128 * 1024 * 1024; - m_systemEntity = m_app.Create(appDesc); - m_app.AddEntity(m_systemEntity); - } - - void TearDown() override - { - m_app.Destroy(); - m_systemEntity = nullptr; - } }; #if AZ_TRAIT_DISABLE_FAILED_GRADIENT_SIGNAL_TESTS From 79431f5e5fbec10608e0de865c6474b0bead2c32 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Thu, 13 Jan 2022 14:50:54 -0600 Subject: [PATCH 172/272] First batch of GetValues() overrides (#6852) * Benchmarks and tests for Image and Constant GetValues Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Verify GetValues for Perlin and Random Gradients Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Standardized the assert format for GetValues(). Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * More GetValues unit tests and test cleanup Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed typos Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * GetValues() unit tests for surface gradients. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Benchmarks for ShapeAreaFalloff Gradient Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for all remaining gradients and cleaned up the helper methods. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Renamed class for better report formatting. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added missing Mocks dependencies for the Editor tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * First batch of specific GetValues() overrides. Each one is measurably faster than the generic version. Also, in ShapeAreaFalloffGradient, I optimized and simplified the logic a bit, so GetValue() is marginally faster too. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Components/ConstantGradientComponent.h | 1 + .../Components/ImageGradientComponent.h | 1 + .../Components/PerlinGradientComponent.h | 1 + .../Components/RandomGradientComponent.h | 3 + .../ShapeAreaFalloffGradientComponent.h | 1 + .../Components/ConstantGradientComponent.cpp | 16 +++++ .../Components/ImageGradientComponent.cpp | 33 ++++++++++ .../Components/PerlinGradientComponent.cpp | 34 ++++++++++ .../Components/RandomGradientComponent.cpp | 65 +++++++++++++++---- .../ShapeAreaFalloffGradientComponent.cpp | 59 ++++++++++++++--- 10 files changed, 194 insertions(+), 20 deletions(-) diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h index cb27914b8a..af896f0933 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h @@ -62,6 +62,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h index 8214436f83..9fc98124cb 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h @@ -69,6 +69,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; // AZ::Data::AssetBus overrides... void OnAssetReady(AZ::Data::Asset asset) override; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h index ef171f5319..1b39f7f17b 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h @@ -70,6 +70,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; private: PerlinGradientConfig m_configuration; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h index b0dbd964a0..274442a2c0 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h @@ -61,6 +61,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; private: RandomGradientConfig m_configuration; @@ -73,5 +74,7 @@ namespace GradientSignal // RandomGradientRequestBus overrides... int GetRandomSeed() const override; void SetRandomSeed(int seed) override; + + float GetRandomValue(const AZ::Vector3& position, AZStd::size_t seed) const; }; } diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h index d7c2344fd2..df86c38069 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h @@ -69,6 +69,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp index 86e8a5abc6..2b1487f75e 100644 --- a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp @@ -134,6 +134,22 @@ namespace GradientSignal return m_configuration.m_value; } + void ConstantGradientComponent::GetValues( + [[maybe_unused]] AZStd::array_view positions, AZStd::array_view outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + for (auto& outValue : outValues) + { + float& writableOutValue = const_cast(outValue); + writableOutValue = m_configuration.m_value; + } + } + float ConstantGradientComponent::GetConstantValue() const { return m_configuration.m_value; diff --git a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp index 269bfbc2df..06a3674188 100644 --- a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp @@ -219,6 +219,39 @@ namespace GradientSignal return 0.0f; } + void ImageGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + AZ::Vector3 uvw; + bool wasPointRejected = false; + + AZStd::shared_lock imageLock(m_imageMutex); + + for (size_t index = 0; index < positions.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + + m_gradientTransform.TransformPositionToUVWNormalized(positions[index], uvw, wasPointRejected); + + if (!wasPointRejected) + { + outValue = GetValueFromImageAsset( + m_configuration.m_imageAsset, uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); + } + else + { + outValue = 0.0f; + } + } + } + AZStd::string ImageGradientComponent::GetImageAssetPath() const { AZStd::string assetPathString; diff --git a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp index 3096afa3dc..667d8c30a7 100644 --- a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp @@ -203,6 +203,40 @@ namespace GradientSignal return 0.0f; } + void PerlinGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + AZ::Vector3 uvw; + bool wasPointRejected = false; + + AZStd::shared_lock lock(m_transformMutex); + + for (size_t index = 0; index < positions.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + + m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected); + + if (!wasPointRejected) + { + outValue = m_perlinImprovedNoise->GenerateOctaveNoise( + uvw.GetX(), uvw.GetY(), uvw.GetZ(), m_configuration.m_octave, m_configuration.m_amplitude, + m_configuration.m_frequency); + } + else + { + outValue = 0.0f; + } + } + } + int PerlinGradientComponent::GetRandomSeed() const { return m_configuration.m_randomSeed; diff --git a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp index 1b6753560c..ae51bdd4ac 100644 --- a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp @@ -145,6 +145,22 @@ namespace GradientSignal m_gradientTransform = newTransform; } + float RandomGradientComponent::GetRandomValue(const AZ::Vector3& position, AZStd::size_t seed) const + { + // generating stable pseudo-random noise from a position based hash + float x = position.GetX(); + float y = position.GetY(); + AZStd::size_t result = 0; + + AZStd::hash_combine(result, x * seed + y); + AZStd::hash_combine(result, y * seed + x); + AZStd::hash_combine(result, x * y * seed); + + // always returns [0.0,1.0] + return static_cast(result % std::numeric_limits::max()) / static_cast(std::numeric_limits::max()); + } + + float RandomGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { @@ -158,23 +174,50 @@ namespace GradientSignal if (!wasPointRejected) { - //generating stable pseudo-random noise from a position based hash - float x = uvw.GetX(); - float y = uvw.GetY(); - AZStd::size_t result = 0; - const AZStd::size_t seed = m_configuration.m_randomSeed + AZStd::size_t(2); // Add 2 to avoid seeds 0 and 1, which can create strange patterns with this particular algorithm + const AZStd::size_t seed = m_configuration.m_randomSeed + + AZStd::size_t(2); // Add 2 to avoid seeds 0 and 1, which can create strange patterns with this particular algorithm - AZStd::hash_combine(result, x * seed + y); - AZStd::hash_combine(result, y * seed + x); - AZStd::hash_combine(result, x * y * seed); - - //always returns [0.0,1.0] - return static_cast(result % std::numeric_limits::max()) / static_cast(std::numeric_limits::max()); + return GetRandomValue(uvw, seed); } return 0.0f; } + void RandomGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + AZ::Vector3 uvw; + bool wasPointRejected = false; + const AZStd::size_t seed = m_configuration.m_randomSeed + + AZStd::size_t(2); // Add 2 to avoid seeds 0 and 1, which can create strange patterns with this particular algorithm + + AZStd::shared_lock lock(m_transformMutex); + + for (size_t index = 0; index < positions.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + + m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected); + + if (!wasPointRejected) + { + outValue = GetRandomValue(uvw, seed); + } + else + { + outValue = 0.0f; + } + } + } + + int RandomGradientComponent::GetRandomSeed() const { return m_configuration.m_randomSeed; diff --git a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp index 9e1a250900..f2416f4fb6 100644 --- a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp @@ -157,21 +157,62 @@ namespace GradientSignal float ShapeAreaFalloffGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - AZ_PROFILE_FUNCTION(Entity); - float distance = 0.0f; LmbrCentral::ShapeComponentRequestsBus::EventResult(distance, m_configuration.m_shapeEntityId, &LmbrCentral::ShapeComponentRequestsBus::Events::DistanceFromPoint, sampleParams.m_position); - // In the special case of 0 falloff, make sure that all points inside the shape (0 distance) return - // 1.0, and all points outside the shape return 0. - if (m_configuration.m_falloffWidth == 0.0f) + // Since this is outer falloff, distance should give us values from 1.0 at the minimum distance to 0.0 at the maximum distance. + // The statement is written specifically to handle the 0 falloff case as well. For 0 falloff, all points inside the shape + // (0 distance) return 1.0, and all points outside the shape return 0. This works because division by 0 gives infinity, which gets + // clamped by the GetMax() to 0. However, if distance == 0, it would give us NaN, so we have the separate conditional check to + // handle that case and clamp to 1.0. + return (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / m_configuration.m_falloffWidth), 0.0f); + } + + void ShapeAreaFalloffGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + { + if (positions.size() != outValues.size()) { - return (distance > 0.0f) ? 0.0f : 1.0f; + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; } - // Since this is outer falloff, distance should give us values from 1.0 at the minimum distance - // to 0.0 at the maximum distance. - return GetRatio(m_configuration.m_falloffWidth, 0.0f, distance); + bool shapeConnected = false; + const float falloffWidth = m_configuration.m_falloffWidth; + + LmbrCentral::ShapeComponentRequestsBus::Event( + m_configuration.m_shapeEntityId, + [falloffWidth, positions, &outValues, &shapeConnected](LmbrCentral::ShapeComponentRequestsBus::Events* shapeRequests) + { + shapeConnected = true; + + for (size_t index = 0; index < positions.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + + float distance = shapeRequests->DistanceFromPoint(positions[index]); + + // Since this is outer falloff, distance should give us values from 1.0 at the minimum distance to 0.0 at the maximum + // distance. The statement is written specifically to handle the 0 falloff case as well. For 0 falloff, all points + // inside the shape (0 distance) return 1.0, and all points outside the shape return 0. This works because division by 0 + // gives infinity, which gets clamped by the GetMax() to 0. However, if distance == 0, it would give us NaN, so we have + // the separate conditional check to handle that case and clamp to 1.0. + outValue = (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / falloffWidth), 0.0f); + } + }); + + // If there's no shape, there's no falloff. + if (!shapeConnected) + { + for (size_t index = 0; index < positions.size(); index++) + { + // The const_cast is necessary for now since array_view currently only supports const entries. + // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. + auto& outValue = const_cast(outValues[index]); + outValue = 1.0f; + } + } } AZ::EntityId ShapeAreaFalloffGradientComponent::GetShapeEntityId() const From 34d74857f5e940b8e18a971e7b053fb6805c48b2 Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Thu, 13 Jan 2022 12:55:36 -0800 Subject: [PATCH 173/272] [development] fix for a possible MSVC compiler bug (#6870) Replaced a variable with the name "interface" to avoid conflict with MSVC keyword Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- .../AssetProcessor/native/tests/SourceFileRelocatorTests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Tools/AssetProcessor/native/tests/SourceFileRelocatorTests.cpp b/Code/Tools/AssetProcessor/native/tests/SourceFileRelocatorTests.cpp index d7801abb3d..8d52ba23bd 100644 --- a/Code/Tools/AssetProcessor/native/tests/SourceFileRelocatorTests.cpp +++ b/Code/Tools/AssetProcessor/native/tests/SourceFileRelocatorTests.cpp @@ -793,9 +793,9 @@ namespace UnitTests TEST_F(SourceFileRelocatorTest, TestInterface) { - auto* interface = AZ::Interface::Get(); + auto* sourceFileRelocator = AZ::Interface::Get(); - ASSERT_NE(interface, nullptr); + ASSERT_NE(sourceFileRelocator, nullptr); } TEST_F(SourceFileRelocatorTest, Move_Real_Succeeds) From 193f529b9c8469930252b20d9fd15bd2bbc9bf60 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Thu, 13 Jan 2022 12:56:34 -0800 Subject: [PATCH 174/272] Add an LyShine client API target (#6829) * Reduce the need to link with LyShine static lib in other gems Signed-off-by: abrmich * Add UiBasics.Builders to VirtualGamepad.Builders alias Signed-off-by: abrmich * Add UiBasics to LyShine gem's metadata Signed-off-by: abrmich * Change include to a forward declaration Signed-off-by: abrmich --- Gems/GameStateSamples/Code/CMakeLists.txt | 2 +- Gems/LyShine/Code/CMakeLists.txt | 19 ++++---- Gems/LyShine/Code/Editor/GuideHelpers.cpp | 2 +- .../Code/Editor/ViewportCanvasBackground.cpp | 2 +- .../Code/Editor/ViewportDragInteraction.h | 2 +- Gems/LyShine/Code/Editor/ViewportHelpers.h | 2 +- Gems/LyShine/Code/Editor/ViewportIcon.cpp | 12 ++--- Gems/LyShine/Code/Editor/ViewportIcon.h | 2 +- Gems/LyShine/Code/Editor/ViewportWidget.cpp | 2 +- Gems/LyShine/Code/Include/LyShine/IDraw2d.h | 44 +++++++++++++++++++ Gems/LyShine/Code/Include/LyShine/ILyShine.h | 9 ++++ Gems/LyShine/Code/Source/Draw2d.cpp | 38 +--------------- .../Code/{Include/LyShine => Source}/Draw2d.h | 3 -- Gems/LyShine/Code/Source/LyShine.cpp | 10 ++++- Gems/LyShine/Code/Source/LyShine.h | 1 + Gems/LyShine/Code/Source/LyShineDebug.cpp | 22 +++++----- .../LyShine/Code/Source/UiCanvasComponent.cpp | 2 +- Gems/LyShine/Code/Source/UiCanvasManager.cpp | 6 +-- Gems/LyShine/Code/Source/UiFaderComponent.cpp | 2 +- Gems/LyShine/Code/Source/UiImageComponent.cpp | 2 +- .../Code/Source/UiImageSequenceComponent.cpp | 2 +- Gems/LyShine/Code/Source/UiMaskComponent.cpp | 2 +- Gems/LyShine/Code/Source/UiRenderer.cpp | 4 +- Gems/LyShine/Code/Source/UiTextComponent.cpp | 10 ++--- Gems/LyShine/Code/lyshine_static_files.cmake | 4 +- Gems/LyShine/gem.json | 3 +- Gems/LyShineExamples/Code/CMakeLists.txt | 4 +- .../Code/Source/UiCustomImageComponent.cpp | 2 +- Gems/MessagePopup/Code/CMakeLists.txt | 4 +- Gems/UiBasics/CMakeLists.txt | 1 + Gems/VirtualGamepad/Code/CMakeLists.txt | 4 +- 31 files changed, 125 insertions(+), 99 deletions(-) rename Gems/LyShine/Code/{Include/LyShine => Source}/Draw2d.h (98%) diff --git a/Gems/GameStateSamples/Code/CMakeLists.txt b/Gems/GameStateSamples/Code/CMakeLists.txt index 5d1d180de0..a07bef6a06 100644 --- a/Gems/GameStateSamples/Code/CMakeLists.txt +++ b/Gems/GameStateSamples/Code/CMakeLists.txt @@ -21,7 +21,7 @@ ly_add_target( INTERFACE Gem::GameState Gem::LocalUser - Gem::LyShine.Static + Gem::LyShine.Clients.API Gem::SaveData.Static Gem::MessagePopup.Static Legacy::CryCommon diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 4f2c4e90a7..2b550b0e36 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -58,10 +58,13 @@ ly_add_target( # by default, load the above "Gem::LyShine" module in Client and Server applications: ly_create_alias(NAME LyShine.Clients NAMESPACE Gem TARGETS Gem::LyShine) ly_create_alias(NAME LyShine.Servers NAMESPACE Gem TARGETS Gem::LyShine) +# create an alias for other gems to depend on an LyShine public API (may be converted to a target in the future): +ly_create_alias(NAME LyShine.Clients.API NAMESPACE Gem TARGETS Gem::LyShine.Clients) +ly_create_alias(NAME LyShine.Servers.API NAMESPACE Gem TARGETS Gem::LyShine.Servers) if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( - NAME LyShine.Editor.Static STATIC + NAME LyShine.Tools.Static STATIC NAMESPACE Gem AUTOMOC AUTOUIC @@ -73,7 +76,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) . Source Editor - PUBLIC Include BUILD_DEPENDENCIES PRIVATE @@ -100,7 +102,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_target( - NAME LyShine.Editor GEM_MODULE + NAME LyShine.Tools GEM_MODULE NAMESPACE Gem FILES_CMAKE lyshine_common_module_files.cmake @@ -112,18 +114,18 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) . Source Editor - PUBLIC Include BUILD_DEPENDENCIES PRIVATE Legacy::CryCommon AZ::AzToolsFramework - Gem::LyShine.Editor.Static + Gem::LyShine.Tools.Static Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor RUNTIME_DEPENDENCIES Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor + Gem::UiBasics.Tools ) # by naming this target LyShine.Builders it ensures that it is loaded @@ -179,10 +181,9 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) Gem::LyShine.Builders.Static Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor + RUNTIME_DEPENDENCIES + Gem::UiBasics.Builders ) - - # by default, load the above "Gem::LyShine.Editor" module in dev tools: - ly_create_alias(NAME LyShine.Tools NAMESPACE Gem TARGETS Gem::LyShine.Editor) endif() ################################################################################ @@ -241,7 +242,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTest Legacy::CryCommon AZ::AssetBuilderSDK - Gem::LyShine.Editor.Static + Gem::LyShine.Tools.Static Gem::LyShine.Builders.Static Gem::LmbrCentral.Editor Gem::TextureAtlas diff --git a/Gems/LyShine/Code/Editor/GuideHelpers.cpp b/Gems/LyShine/Code/Editor/GuideHelpers.cpp index eb5966568e..b6d7acc57a 100644 --- a/Gems/LyShine/Code/Editor/GuideHelpers.cpp +++ b/Gems/LyShine/Code/Editor/GuideHelpers.cpp @@ -173,7 +173,7 @@ namespace GuideHelpers // the line is drawn as the inverse of the background color AZ::Color guideColor(1.0f, 1.0f, 1.0f, 1.0f); - CDraw2d::RenderState renderState; + IDraw2d::RenderState renderState; renderState.m_blendState.m_blendSource = AZ::RHI::BlendFactor::ColorDestInverse; renderState.m_blendState.m_blendDest = AZ::RHI::BlendFactor::Zero; diff --git a/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp b/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp index 668c4e8024..b1961de0a1 100644 --- a/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp +++ b/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp @@ -50,7 +50,7 @@ void ViewportCanvasBackground::Draw(Draw2dHelper& draw2d, const AZ::Vector2& can // now draw the same as Stretched but with UV's adjusted const AZ::Vector2 uvs[4] = { AZ::Vector2(0, 0), AZ::Vector2(uvScale.GetX(), 0), AZ::Vector2(uvScale.GetX(), uvScale.GetY()), AZ::Vector2(0, uvScale.GetY()) }; AZ::Color colorWhite(1.0f, 1.0f, 1.0f, 1.0f); - CDraw2d::VertexPosColUV verts[4]; + IDraw2d::VertexPosColUV verts[4]; for (int i = 0; i < 4; ++i) { verts[i].position = positions[i]; diff --git a/Gems/LyShine/Code/Editor/ViewportDragInteraction.h b/Gems/LyShine/Code/Editor/ViewportDragInteraction.h index 3b26b66308..6b48fc0133 100644 --- a/Gems/LyShine/Code/Editor/ViewportDragInteraction.h +++ b/Gems/LyShine/Code/Editor/ViewportDragInteraction.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include //! Abstract base class for drag interactions in the UI Editor viewport window. class ViewportDragInteraction diff --git a/Gems/LyShine/Code/Editor/ViewportHelpers.h b/Gems/LyShine/Code/Editor/ViewportHelpers.h index 8068f4af65..f2722fb6b8 100644 --- a/Gems/LyShine/Code/Editor/ViewportHelpers.h +++ b/Gems/LyShine/Code/Editor/ViewportHelpers.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace ViewportHelpers { diff --git a/Gems/LyShine/Code/Editor/ViewportIcon.cpp b/Gems/LyShine/Code/Editor/ViewportIcon.cpp index 3f0fdfaba0..33f2f40ffe 100644 --- a/Gems/LyShine/Code/Editor/ViewportIcon.cpp +++ b/Gems/LyShine/Code/Editor/ViewportIcon.cpp @@ -6,7 +6,7 @@ * */ #include "EditorCommon.h" -#include +#include #include #include @@ -15,7 +15,7 @@ float ViewportIcon::m_dpiScaleFactor = 1.0f; ViewportIcon::ViewportIcon(const char* textureFilename) { - m_image = CDraw2d::LoadTexture(textureFilename); + m_image = Draw2dHelper::LoadTexture(textureFilename); } ViewportIcon::~ViewportIcon() @@ -48,7 +48,7 @@ void ViewportIcon::DrawImageAligned(Draw2dHelper& draw2d, AZ::Vector2& pivot, fl opacity); } -void ViewportIcon::DrawImageTiled(Draw2dHelper& draw2d, CDraw2d::VertexPosColUV* verts) +void ViewportIcon::DrawImageTiled(Draw2dHelper& draw2d, IDraw2d::VertexPosColUV* verts) { // Use default blending and rounding modes IDraw2d::Rounding rounding = IDraw2d::Rounding::Nearest; @@ -63,7 +63,7 @@ void ViewportIcon::DrawAxisAlignedBoundingBox(Draw2dHelper& draw2d, AZ::Vector2 float endTexCoordU = fabsf((bound1.GetX() - bound0.GetX()) * pixelLengthForDottedLineTexture); float endTexCoordV = fabsf((bound1.GetY() - bound0.GetY()) * pixelLengthForDottedLineTexture); - CDraw2d::VertexPosColUV verts[2]; + IDraw2d::VertexPosColUV verts[2]; { verts[0].color = dottedColor; verts[1].color = dottedColor; @@ -158,7 +158,7 @@ void ViewportIcon::Draw(Draw2dHelper& draw2d, AZ::Vector2 anchorPos, const AZ::M AZ::Matrix4x4 moveFromPivotSpaceMat = AZ::Matrix4x4::CreateTranslation(pivot3); AZ::Matrix4x4 newTransform = transform * moveFromPivotSpaceMat * rotMat * moveToPivotSpaceMat; - CDraw2d::VertexPosColUV verts[4]; + IDraw2d::VertexPosColUV verts[4]; // points are a clockwise quad static const AZ::Vector2 uvs[4] = { AZ::Vector2(0.0f, 0.0f), AZ::Vector2(1.0f, 0.0f), AZ::Vector2(1.0f, 1.0f), AZ::Vector2(0.0f, 1.0f) @@ -251,7 +251,7 @@ void ViewportIcon::DrawDistanceLine(Draw2dHelper& draw2d, AZ::Vector2 start, AZ: const float pixelLengthForDottedLineTexture = 8.0f; float endTexCoordU = length / pixelLengthForDottedLineTexture; - CDraw2d::VertexPosColUV verts[2]; + IDraw2d::VertexPosColUV verts[2]; verts[0].position = start; verts[0].color = dottedColor; diff --git a/Gems/LyShine/Code/Editor/ViewportIcon.h b/Gems/LyShine/Code/Editor/ViewportIcon.h index f815b244e9..fadd829bcf 100644 --- a/Gems/LyShine/Code/Editor/ViewportIcon.h +++ b/Gems/LyShine/Code/Editor/ViewportIcon.h @@ -20,7 +20,7 @@ public: void DrawImageAligned(Draw2dHelper& draw2d, AZ::Vector2& pivot, float opacity); - void DrawImageTiled(Draw2dHelper& draw2d, CDraw2d::VertexPosColUV* verts); + void DrawImageTiled(Draw2dHelper& draw2d, IDraw2d::VertexPosColUV* verts); void Draw(Draw2dHelper& draw2d, AZ::Vector2 anchorPos, const AZ::Matrix4x4& transform, float iconRot = 0.0f, AZ::Color color = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f)) const; diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.cpp b/Gems/LyShine/Code/Editor/ViewportWidget.cpp index 993f57aeeb..b481e9cbf1 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.cpp +++ b/Gems/LyShine/Code/Editor/ViewportWidget.cpp @@ -16,7 +16,6 @@ #include #include -#include #include "LyShine.h" #include "UiRenderer.h" @@ -27,6 +26,7 @@ #include "RulerWidget.h" #include "CanvasHelpers.h" #include "AssetDropHelpers.h" +#include "Draw2d.h" #include "QtHelpers.h" #include diff --git a/Gems/LyShine/Code/Include/LyShine/IDraw2d.h b/Gems/LyShine/Code/Include/LyShine/IDraw2d.h index 620b8c23c9..77dc5ac601 100644 --- a/Gems/LyShine/Code/Include/LyShine/IDraw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/IDraw2d.h @@ -482,6 +482,50 @@ public: // static member functions return nullptr; } + //! Helper to load a texture + static AZ::Data::Instance LoadTexture(const AZStd::string& pathName) + { + if (gEnv && gEnv->pLyShine) // [LYSHINE_ATOM_TODO][GHI #3569] Remove LyShine global interface pointer from legacy global environment + { + return gEnv->pLyShine->LoadTexture(pathName); + } + + return nullptr; + } + + //! Given a position and size and an alignment return the top left corner of the aligned quad + static AZ::Vector2 Align(AZ::Vector2 position, AZ::Vector2 size, IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment) + { + AZ::Vector2 result = AZ::Vector2::CreateZero(); + switch (horizontalAlignment) + { + case IDraw2d::HAlign::Left: + result.SetX(position.GetX()); + break; + case IDraw2d::HAlign::Center: + result.SetX(position.GetX() - size.GetX() * 0.5f); + break; + case IDraw2d::HAlign::Right: + result.SetX(position.GetX() - size.GetX()); + break; + } + + switch (verticalAlignment) + { + case IDraw2d::VAlign::Top: + result.SetY(position.GetY()); + break; + case IDraw2d::VAlign::Center: + result.SetY(position.GetY() - size.GetY() * 0.5f); + break; + case IDraw2d::VAlign::Bottom: + result.SetY(position.GetY() - size.GetY()); + break; + } + + return result; + } + //! Round the X and Y coordinates of a point using the given rounding policy template static T RoundXY(T value, IDraw2d::Rounding roundingType) diff --git a/Gems/LyShine/Code/Include/LyShine/ILyShine.h b/Gems/LyShine/Code/Include/LyShine/ILyShine.h index 7832497d8c..71ca6ec074 100644 --- a/Gems/LyShine/Code/Include/LyShine/ILyShine.h +++ b/Gems/LyShine/Code/Include/LyShine/ILyShine.h @@ -9,12 +9,18 @@ #include #include +#include class IDraw2d; class ISprite; struct IUiAnimationSystem; class UiEntityContext; +namespace AZ::RPI +{ + class Image; +} + // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the LYSHINE_EXPORTS // symbol defined in the StdAfx.h. this symbol should not be defined on any project @@ -82,6 +88,9 @@ public: //! Check if a sprite's texture asset exists. The .sprite sidecar file is optional and is not checked virtual bool DoesSpriteTextureAssetExist(const AZStd::string& pathname) = 0; + //! Load an image asset by texture pathname + virtual AZ::Data::Instance LoadTexture(const AZStd::string& pathName) = 0; + //! Perform post-initialization (script system will be available) virtual void PostInit() = 0; diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index 2838ed4877..ff8c7f1c6d 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -6,7 +6,7 @@ * */ -#include +#include "Draw2d.h" #include #include "LyShinePassDataBus.h" @@ -215,7 +215,7 @@ void CDraw2d::DrawImageAligned(AZ::Data::Instance image, AZ::Vec HAlign horizontalAlignment, VAlign verticalAlignment, float opacity, float rotation, const AZ::Vector2* minMaxTexCoords, ImageOptions* imageOptions) { - AZ::Vector2 alignedPosition = Align(position, size, horizontalAlignment, verticalAlignment); + AZ::Vector2 alignedPosition = Draw2dHelper::Align(position, size, horizontalAlignment, verticalAlignment); DrawImage(image, alignedPosition, size, opacity, rotation, &position, minMaxTexCoords, imageOptions); } @@ -524,40 +524,6 @@ void CDraw2d::SetSortKey(int64_t key) // PUBLIC STATIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -AZ::Vector2 CDraw2d::Align(AZ::Vector2 position, AZ::Vector2 size, - HAlign horizontalAlignment, VAlign verticalAlignment) -{ - AZ::Vector2 result = AZ::Vector2::CreateZero(); - switch (horizontalAlignment) - { - case HAlign::Left: - result.SetX(position.GetX()); - break; - case HAlign::Center: - result.SetX(position.GetX() - size.GetX() * 0.5f); - break; - case HAlign::Right: - result.SetX(position.GetX() - size.GetX()); - break; - } - - switch (verticalAlignment) - { - case VAlign::Top: - result.SetY(position.GetY()); - break; - case VAlign::Center: - result.SetY(position.GetY() - size.GetY() * 0.5f); - break; - case VAlign::Bottom: - result.SetY(position.GetY() - size.GetY()); - break; - } - - return result; -} - //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Data::Instance CDraw2d::LoadTexture(const AZStd::string& pathName) { diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Source/Draw2d.h similarity index 98% rename from Gems/LyShine/Code/Include/LyShine/Draw2d.h rename to Gems/LyShine/Code/Source/Draw2d.h index d138f41b03..6d400c6b55 100644 --- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h +++ b/Gems/LyShine/Code/Source/Draw2d.h @@ -180,9 +180,6 @@ private: public: // static member functions - //! Given a position and size and an alignment return the top left corner of the aligned quad - static AZ::Vector2 Align(AZ::Vector2 position, AZ::Vector2 size, HAlign horizontalAlignment, VAlign verticalAlignment); - //! Helper to load a texture static AZ::Data::Instance LoadTexture(const AZStd::string& pathName); diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index 683d72f4ab..5a704329ef 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -43,11 +43,11 @@ #include "Sprite.h" #include "UiSerialize.h" #include "UiRenderer.h" +#include "Draw2d.h" #include #include #include -#include #if defined(LYSHINE_INTERNAL_UNIT_TEST) #include "TextMarkup.h" @@ -355,6 +355,12 @@ bool CLyShine::DoesSpriteTextureAssetExist(const AZStd::string& pathname) return CSprite::DoesSpriteTextureAssetExist(pathname); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +AZ::Data::Instance CLyShine::LoadTexture(const AZStd::string& pathname) +{ + return CDraw2d::LoadTexture(pathname); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void CLyShine::PostInit() { @@ -691,7 +697,7 @@ void CLyShine::RenderUiCursor() AZ::RHI::Size cursorSize = m_uiCursorTexture->GetDescriptor().m_size; const AZ::Vector2 dimensions(aznumeric_cast(cursorSize.m_width), aznumeric_cast(cursorSize.m_height)); - CDraw2d::ImageOptions imageOptions; + IDraw2d::ImageOptions imageOptions; imageOptions.m_clamp = true; const float opacity = 1.0f; const float rotation = 0.0f; diff --git a/Gems/LyShine/Code/Source/LyShine.h b/Gems/LyShine/Code/Source/LyShine.h index 82f902a9f8..eab52258c1 100644 --- a/Gems/LyShine/Code/Source/LyShine.h +++ b/Gems/LyShine/Code/Source/LyShine.h @@ -72,6 +72,7 @@ public: ISprite* LoadSprite(const AZStd::string& pathname) override; ISprite* CreateSprite(const AZStd::string& renderTargetName) override; bool DoesSpriteTextureAssetExist(const AZStd::string& pathname) override; + AZ::Data::Instance LoadTexture(const AZStd::string& pathname) override; void PostInit() override; diff --git a/Gems/LyShine/Code/Source/LyShineDebug.cpp b/Gems/LyShine/Code/Source/LyShineDebug.cpp index bb57e70857..7e99652f45 100644 --- a/Gems/LyShine/Code/Source/LyShineDebug.cpp +++ b/Gems/LyShine/Code/Source/LyShineDebug.cpp @@ -7,7 +7,7 @@ */ #include "LyShineDebug.h" #include "IConsole.h" -#include +#include #include @@ -377,7 +377,7 @@ static void DebugDrawColoredBox(AZ::Vector2 pos, AZ::Vector2 size, AZ::Color col { IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); imageOptions.color = color.GetAsVector3(); auto whiteTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White); draw2d->DrawImageAligned(whiteTexture, pos, size, horizontalAlignment, verticalAlignment, @@ -392,7 +392,7 @@ static void DebugDrawStringWithSizeBox(AZStd::string_view font, unsigned int eff { IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); - CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); + IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); if (!font.empty()) { textOptions.fontName = font; @@ -618,7 +618,7 @@ static AZ::Vector2 DebugDrawFontColorTestBox(AZ::Vector2 pos, const char* string float pointSize = 32.0f; const float spacing = 6.0f; - CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); + IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.effectIndex = 1; // no drop shadow baked in textOptions.color = color; @@ -742,7 +742,7 @@ static void DebugDraw2dImageColor() AZ::Data::Instance texture = GetMonoAlphaTestTexture(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->DrawText( "Testing image colors, image is black and white, top row is opacity=1, bottom row is opacity = 0.5", @@ -780,7 +780,7 @@ static void DebugDraw2dImageBlendMode() AZ::Data::Instance texture = GetColorAlphaTestTexture(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->DrawText("Testing blend modes, src blend changes across x-axis, dst blend changes across y axis", AZ::Vector2(20, 20), 16); @@ -801,7 +801,7 @@ static void DebugDraw2dImageBlendMode() AZ::Vector2 pos(xStart + xSpacing * srcIndex, yStart + ySpacing * dstIndex); // first draw a background with varying color and alpha - CDraw2d::VertexPosColUV verts[4] = + IDraw2d::VertexPosColUV verts[4] = { { // top left AZ::Vector2(pos.GetX(), pos.GetY()), @@ -828,7 +828,7 @@ static void DebugDraw2dImageBlendMode() // Draw the image with this color - CDraw2d::RenderState renderState; + IDraw2d::RenderState renderState; renderState.m_blendState.m_blendSource = g_srcBlendModes[srcIndex]; renderState.m_blendState.m_blendDest = g_dstBlendModes[dstIndex]; draw2d->DrawImage(texture, pos, size, 1.0f, 0.0f, 0, 0, &imageOptions); @@ -845,7 +845,7 @@ static void DebugDraw2dImageUVs() AZ::Data::Instance texture = GetColorTestTexture(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->DrawText( "Testing DrawImage with minMaxTexCoords. Full image, top left quadrant, middle section, full flipped", @@ -894,7 +894,7 @@ static void DebugDraw2dImagePixelRounding() AZ::Data::Instance texture = GetColorTestTexture(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->DrawText("Testing DrawImage pixel rounding options", AZ::Vector2(20, 20), 16); @@ -933,7 +933,7 @@ static void DebugDraw2dLineBasic() { IDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); - CDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); + IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->DrawText("Testing DrawLine", AZ::Vector2(20, 20), 16); diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index 0a21f92119..ea6e3681a3 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index 70646246f0..fc373f17f6 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -6,7 +6,7 @@ * */ #include "UiCanvasManager.h" -#include +#include #include "UiCanvasFileObject.h" #include "UiCanvasComponent.h" @@ -1020,7 +1020,7 @@ void UiCanvasManager::DebugDisplayCanvasData(int setting) const // local function to write a line of text (with a background rect) and increment Y offset AZStd::function WriteLine = [&](const char* buffer, const AZ::Vector3& color) { - CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); + IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.color = color; AZ::Vector2 textSize = draw2d->GetTextSize(buffer, fontSize, &textOptions); AZ::Vector2 rectTopLeft = AZ::Vector2(xOffset - 2, yOffset); @@ -1174,7 +1174,7 @@ void UiCanvasManager::DebugDisplayDrawCallData() const // local function to write a line of text (with a background rect) and increment Y offset AZStd::function WriteLine = [&](const char* buffer, const AZ::Vector3& color) { - CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); + IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.color = color; AZ::Vector2 textSize = draw2d->GetTextSize(buffer, fontSize, &textOptions); AZ::Vector2 rectTopLeft = AZ::Vector2(xOffset - 2, yOffset); diff --git a/Gems/LyShine/Code/Source/UiFaderComponent.cpp b/Gems/LyShine/Code/Source/UiFaderComponent.cpp index e1f5153e99..e84e5162b5 100644 --- a/Gems/LyShine/Code/Source/UiFaderComponent.cpp +++ b/Gems/LyShine/Code/Source/UiFaderComponent.cpp @@ -7,7 +7,7 @@ */ #include "UiFaderComponent.h" #include "RenderGraph.h" -#include +#include #include #include diff --git a/Gems/LyShine/Code/Source/UiImageComponent.cpp b/Gems/LyShine/Code/Source/UiImageComponent.cpp index baf210a629..a8b4210d6b 100644 --- a/Gems/LyShine/Code/Source/UiImageComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageComponent.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp index 4e7d22d96a..3559dc6306 100644 --- a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp @@ -9,7 +9,7 @@ #include "Sprite.h" #include "RenderGraph.h" -#include +#include #include #include #include diff --git a/Gems/LyShine/Code/Source/UiMaskComponent.cpp b/Gems/LyShine/Code/Source/UiMaskComponent.cpp index 09975d1351..67ba8ee0fb 100644 --- a/Gems/LyShine/Code/Source/UiMaskComponent.cpp +++ b/Gems/LyShine/Code/Source/UiMaskComponent.cpp @@ -6,7 +6,7 @@ * */ #include "UiMaskComponent.h" -#include +#include #include #include diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index 3b835dec92..a9c56ece90 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC MEMBER FUNCTIONS @@ -449,7 +449,7 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) // local function to write a line of text (with a background rect) and increment Y offset AZStd::function WriteLine = [&](const char* buffer, const AZ::Vector3& color) { - CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); + IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.color = color; AZ::Vector2 textSize = draw2d->GetTextSize(buffer, fontSize, &textOptions); AZ::Vector2 rectTopLeft = AZ::Vector2(xOffset - 2, yOffset); diff --git a/Gems/LyShine/Code/Source/UiTextComponent.cpp b/Gems/LyShine/Code/Source/UiTextComponent.cpp index 01cfd49e99..aa0235470a 100644 --- a/Gems/LyShine/Code/Source/UiTextComponent.cpp +++ b/Gems/LyShine/Code/Source/UiTextComponent.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include @@ -1105,7 +1105,7 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname, else { // Load the texture - m_texture = CDraw2d::LoadTexture(m_filepath); + m_texture = Draw2dHelper::LoadTexture(m_filepath); if (m_texture) { AZ::RHI::Size size = m_texture->GetDescriptor().m_size; @@ -1157,7 +1157,7 @@ bool UiTextComponent::InlineImage::OnAtlasUnloaded(const TextureAtlasNamespace:: else { // Load the texture - m_texture = CDraw2d::LoadTexture(m_filepath); + m_texture = Draw2dHelper::LoadTexture(m_filepath); } return true; } @@ -2675,7 +2675,7 @@ void UiTextComponent::GetClickableTextRects(UiClickableTextInterface::ClickableT } else { - alignedPosition = CDraw2d::Align(pos, drawBatchLine.lineSize, m_textHAlignment, IDraw2d::VAlign::Top); // y is already aligned + alignedPosition = Draw2dHelper::Align(pos, drawBatchLine.lineSize, m_textHAlignment, IDraw2d::VAlign::Top); // y is already aligned } alignedPosition.SetY(alignedPosition.GetY() + newlinePosYIncrement); @@ -4043,7 +4043,7 @@ void UiTextComponent::RenderDrawBatchLines( } else { - alignedPosition = CDraw2d::Align(pos, drawBatchLine.lineSize, m_textHAlignment, IDraw2d::VAlign::Top); // y is already aligned + alignedPosition = Draw2dHelper::Align(pos, drawBatchLine.lineSize, m_textHAlignment, IDraw2d::VAlign::Top); // y is already aligned } alignedPosition.SetY(alignedPosition.GetY() + newlinePosYIncrement); diff --git a/Gems/LyShine/Code/lyshine_static_files.cmake b/Gems/LyShine/Code/lyshine_static_files.cmake index 1adbe1b796..925658e756 100644 --- a/Gems/LyShine/Code/lyshine_static_files.cmake +++ b/Gems/LyShine/Code/lyshine_static_files.cmake @@ -7,8 +7,6 @@ # set(FILES - Source/Draw2d.cpp - Include/LyShine/Draw2d.h Include/LyShine/IDraw2d.h Include/LyShine/IRenderGraph.h Include/LyShine/ISprite.h @@ -88,6 +86,8 @@ set(FILES Include/LyShine/Bus/World/UiCanvasOnMeshBus.h Include/LyShine/Bus/World/UiCanvasRefBus.h Include/LyShine/Bus/Tools/UiSystemToolsBus.h + Source/Draw2d.cpp + Source/Draw2d.h Source/LyShine.cpp Source/LyShine.h Source/LyShinePassDataBus.h diff --git a/Gems/LyShine/gem.json b/Gems/LyShine/gem.json index f3c3fc2c67..8dcac6404a 100644 --- a/Gems/LyShine/gem.json +++ b/Gems/LyShine/gem.json @@ -24,6 +24,7 @@ "Atom_Bootstrap", "AtomFont", "TextureAtlas", - "AtomToolsFramework" + "AtomToolsFramework", + "UiBasics" ] } diff --git a/Gems/LyShineExamples/Code/CMakeLists.txt b/Gems/LyShineExamples/Code/CMakeLists.txt index 6e8f53d5cd..40032d6342 100644 --- a/Gems/LyShineExamples/Code/CMakeLists.txt +++ b/Gems/LyShineExamples/Code/CMakeLists.txt @@ -21,7 +21,7 @@ ly_add_target( Gem::LmbrCentral PUBLIC Legacy::CryCommon - Gem::LyShine.Static + Gem::LyShine.Clients.API ) ly_add_target( @@ -42,7 +42,7 @@ ly_add_target( # if enabled, LyShineExamples is used by all kinds of applications, however, the dependency to LmbrCentral is different # per application type -ly_create_alias(NAME LyShineExamples.Builders NAMESPACE Gem TARGETS Gem::LyShineExamples Gem::LmbrCentral.Editor) +ly_create_alias(NAME LyShineExamples.Builders NAMESPACE Gem TARGETS Gem::LyShineExamples Gem::UiBasics.Builders Gem::LmbrCentral.Editor) ly_create_alias(NAME LyShineExamples.Tools NAMESPACE Gem TARGETS Gem::LyShineExamples Gem::LmbrCentral.Editor) ly_create_alias(NAME LyShineExamples.Clients NAMESPACE Gem TARGETS Gem::LyShineExamples Gem::LmbrCentral) ly_create_alias(NAME LyShineExamples.Servers NAMESPACE Gem TARGETS Gem::LyShineExamples Gem::LmbrCentral) diff --git a/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp b/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp index 542e18b98c..e8b0e4370a 100644 --- a/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp +++ b/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/Gems/MessagePopup/Code/CMakeLists.txt b/Gems/MessagePopup/Code/CMakeLists.txt index 51ec1a3bd1..2ed9c71632 100644 --- a/Gems/MessagePopup/Code/CMakeLists.txt +++ b/Gems/MessagePopup/Code/CMakeLists.txt @@ -19,7 +19,7 @@ ly_add_target( BUILD_DEPENDENCIES PUBLIC Legacy::CryCommon - Gem::LyShine + Gem::LyShine.Clients.API ) ly_add_target( @@ -39,4 +39,4 @@ ly_add_target( # MessagePopup is used only in client applications ly_create_alias(NAME MessagePopup.Clients NAMESPACE Gem TARGETS Gem::MessagePopup) - +ly_create_alias(NAME MessagePopup.Builders NAMESPACE Gem TARGETS Gem::UiBasics.Builders) diff --git a/Gems/UiBasics/CMakeLists.txt b/Gems/UiBasics/CMakeLists.txt index 8d71bd08c7..9c3cf01d26 100644 --- a/Gems/UiBasics/CMakeLists.txt +++ b/Gems/UiBasics/CMakeLists.txt @@ -9,4 +9,5 @@ # This will export its "SourcePaths" to the generated "cmake_dependencies..assetbuilder.setreg" if(PAL_TRAIT_BUILD_HOST_TOOLS) ly_create_alias(NAME UiBasics.Builders NAMESPACE Gem) + ly_create_alias(NAME UiBasics.Tools NAMESPACE Gem) endif() diff --git a/Gems/VirtualGamepad/Code/CMakeLists.txt b/Gems/VirtualGamepad/Code/CMakeLists.txt index d32834633f..6700004a30 100644 --- a/Gems/VirtualGamepad/Code/CMakeLists.txt +++ b/Gems/VirtualGamepad/Code/CMakeLists.txt @@ -21,7 +21,7 @@ ly_add_target( AZ::AzCore AZ::AzFramework Legacy::CryCommon - Gem::LyShine + Gem::LyShine.Clients.API ) ly_add_target( @@ -42,4 +42,4 @@ ly_add_target( # the virtual gamepad is needed everywhere except servers: ly_create_alias(NAME VirtualGamepad.Clients NAMESPACE Gem TARGETS Gem::VirtualGamepad) ly_create_alias(NAME VirtualGamepad.Tools NAMESPACE Gem TARGETS Gem::VirtualGamepad) -ly_create_alias(NAME VirtualGamepad.Builders NAMESPACE Gem TARGETS Gem::VirtualGamepad) +ly_create_alias(NAME VirtualGamepad.Builders NAMESPACE Gem TARGETS Gem::VirtualGamepad Gem::UiBasics.Builders) From 13d6451b6a806e23aa00e664a90d5c7a4d272381 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Thu, 13 Jan 2022 13:24:48 -0800 Subject: [PATCH 175/272] update parser and unit tests to respect the new way slots are added to user function nodes Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../Grammar/AbstractCodeModel.cpp | 70 +- ...nitTest_PromotedUserVariables.scriptcanvas | 858 +++++++++++++ ...PromotedUserVariablesFunction.scriptcanvas | 1100 +++++++++++++++++ .../Tests/ScriptCanvas_RuntimeInterpreted.cpp | 5 + 4 files changed, 2012 insertions(+), 21 deletions(-) create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariables.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariablesFunction.scriptcanvas diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 299718fd0f..b2194e1bd0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -240,7 +240,6 @@ namespace ScriptCanvas // #sc_user_slot_variable_ux consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering m_sourceVariableByDatum.insert(AZStd::make_pair(datum, &variablePair.second)); } - } for (auto& sourceVariable : sortedVariables) @@ -1714,6 +1713,7 @@ namespace ScriptCanvas auto iter = m_inputVariableByNodelingInSlot.find(input); if (iter != m_inputVariableByNodelingInSlot.end()) { + // #sc_user_slot_variable_ux don't add variable name if not necessary VariablePtr variable = iter->second; const Slot* slot = iter->first; variable->m_name = call->ModScope()->AddVariableName(slot->GetName()); @@ -4644,35 +4644,59 @@ namespace ScriptCanvas void AbstractCodeModel::ParseNodelingVariables(const Node& node, NodelingType nodelingType) { - // #sc_user_slot_variable_ux adjust once datums are more coordinated - auto createVariablesSlots = [&](AZStd::unordered_map& variablesBySlots, const AZStd::vector& slots, bool slotHasDatum) + // This function accounts for all the ways users have been able to introduce input/output data in their SC function definitions. + // They have been able to create slots, variables, or both. This function reads the datums to create the correct ACM + // variable per required SC user variable. It uses slots as the key, and checks datums in the SC variable list for possible + // matches. + auto createVariablesSlots = [&](AZStd::unordered_map& variablesBySlots, const AZStd::vector& slots, bool errorOnMissingDatum) { for (const auto& slot : slots) { auto variable = AZStd::make_shared(); + auto variableDatum = slot->FindDatum(); + bool initializeDatum = true; - if (slotHasDatum) + if (variableDatum) { - auto variableDatum = slot->FindDatum(); - if (!variableDatum) - { - AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("Datum missing from Slot %s on Node %s", slot->GetName().data(), node.GetNodeName().c_str()))); - return; - } + initializeDatum = false; + } + else if (errorOnMissingDatum) + { + AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("Datum missing from Slot %s on Node %s", slot->GetName().data(), node.GetNodeName().c_str()))); + return; + } - // #sc_user_slot_variable_ux consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering -// auto iter = m_sourceVariableByDatum.find(variableDatum); -// if (iter == m_sourceVariableByDatum.end()) -// { -// AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("Datum missing from Slot %s on Node %s", slot->GetName().data(), node.GetNodeName().c_str()))); -// return; -// } -// variable->m_sourceVariableId = iter->second->GetVariableId(); + // find the other variable + auto iter = m_sourceVariableByDatum.find(variableDatum); + if (iter != m_sourceVariableByDatum.end()) + { + initializeDatum = false; + } + else if (!variableDatum && errorOnMissingDatum) + { + AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("Datum missing from Slot %s on Node %s", slot->GetName().data(), node.GetNodeName().c_str()))); + return; + } + + VariablePtr premadeVariable = iter != m_sourceVariableByDatum.end() + ? AZStd::const_pointer_cast(FindVariable(iter->second->GetVariableId())) + : VariablePtr(); + + if (premadeVariable) + { + initializeDatum = false; + variable = premadeVariable; + } + + variable->m_sourceSlotId = slot->GetId(); + + if (!premadeVariable && variableDatum) + { variable->m_datum = *variableDatum; } - else + + if (initializeDatum) { - // make a new datum and a source slot id and all that variable->m_datum.SetType(slot->GetDataType()); } @@ -4680,7 +4704,11 @@ namespace ScriptCanvas variable->m_sourceSlotId = slot->GetId(); variable->m_isFromFunctionDefinitionSlot = true; variablesBySlots.insert({ slot, variable }); - m_variables.push_back(variable); + + if (!premadeVariable) + { + m_variables.push_back(variable); + } } }; diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariables.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariables.scriptcanvas new file mode 100644 index 0000000000..6ac83f4b62 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariables.scriptcanvas @@ -0,0 +1,858 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "ScriptCanvasData", + "ClassData": { + "m_scriptCanvas": { + "Id": { + "id": 8475300026301128284 + }, + "Name": "Script Canvas Graph", + "Components": { + "Component_[11907165653188402756]": { + "$type": "EditorGraphVariableManagerComponent", + "Id": 11907165653188402756 + }, + "Component_[3578973614457412392]": { + "$type": "{4D755CA9-AB92-462C-B24F-0B3376F19967} Graph", + "Id": 3578973614457412392, + "m_graphData": { + "m_nodes": [ + { + "Id": { + "id": 16019084446641 + }, + "Name": "SC-Node(Start)", + "Components": { + "Component_[1767232296153779726]": { + "$type": "Start", + "Id": 1767232296153779726, + "Slots": [ + { + "id": { + "m_id": "{635D7286-4B19-44D4-8F5E-1B4A0CF85C9E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled when the entity that owns this graph is fully activated.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 7910364941488 + }, + "Name": "SC-Node(Mark Complete)", + "Components": { + "Component_[1885955816756801547]": { + "$type": "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF} Method", + "Id": 1885955816756801547, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{31ABE549-E2E3-440E-884C-9F7FD4185C1D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "EntityId: 0", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{4FFA1776-D933-4475-BB3C-5BD7FAD47E2B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{F8687B16-9C64-4B5E-B000-035D9B3712EF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0E8012D1-A36B-4BCC-86C9-7D4F93816923}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + } + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Mark Complete", + "className": "Unit Testing", + "inputSlots": [ + { + "m_id": "{31ABE549-E2E3-440E-884C-9F7FD4185C1D}" + }, + { + "m_id": "{4FFA1776-D933-4475-BB3C-5BD7FAD47E2B}" + } + ], + "prettyClassName": "Unit Testing" + } + } + }, + { + "Id": { + "id": 16611789933489 + }, + "Name": "SC-Node(Expect Equal)", + "Components": { + "Component_[6935885723653735789]": { + "$type": "MethodOverloaded", + "Id": 6935885723653735789, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{E2AB1183-3D7C-479C-88D5-8C90042F9D3F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "EntityId: 0", + "DisplayDataType": { + "m_type": 1 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{8D954D4E-D65E-47E4-8979-BAE900582B38}" + }, + "DynamicTypeOverride": 1, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "OverloadContract" + } + ], + "slotName": "Candidate", + "toolTip": "left of ==", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{17DA7626-AA06-4574-8F27-9DE230F03639}" + }, + "DynamicTypeOverride": 1, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "OverloadContract" + } + ], + "slotName": "Reference", + "toolTip": "right of ==", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{B442C3D0-F6F5-4689-982B-67CDF723D505}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "DisplayDataType": { + "m_type": 5 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{33531BA3-2152-4F66-BFDA-CEAC2EB631C7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{A8A9AB24-E5B2-4947-85CC-F87AD9F97FEB}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + } + }, + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Candidate" + }, + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 7.0, + "label": "Reference" + }, + { + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Expect Equal", + "className": "Unit Testing", + "inputSlots": [ + { + "m_id": "{E2AB1183-3D7C-479C-88D5-8C90042F9D3F}" + }, + { + "m_id": "{8D954D4E-D65E-47E4-8979-BAE900582B38}" + }, + { + "m_id": "{17DA7626-AA06-4574-8F27-9DE230F03639}" + }, + { + "m_id": "{B442C3D0-F6F5-4689-982B-67CDF723D505}" + } + ], + "orderedInputSlotIds": [ + { + "m_id": "{E2AB1183-3D7C-479C-88D5-8C90042F9D3F}" + }, + { + "m_id": "{8D954D4E-D65E-47E4-8979-BAE900582B38}" + }, + { + "m_id": "{17DA7626-AA06-4574-8F27-9DE230F03639}" + }, + { + "m_id": "{B442C3D0-F6F5-4689-982B-67CDF723D505}" + } + ], + "outputSlotIds": [ + {} + ] + } + } + }, + { + "Id": { + "id": 15443558828977 + }, + "Name": "FunctionCallNode", + "Components": { + "Component_[9383725529787702808]": { + "$type": "FunctionCallNode", + "Id": 9383725529787702808, + "Slots": [ + { + "id": { + "m_id": "{32BD3CC0-AA44-4B1F-966D-4FF1561E4BC5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "IncrementNumber", + "DisplayGroup": { + "Value": 921414446 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{EBE31443-CFB9-41B1-8DBA-127DB07A405A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "IncrementMe", + "DisplayGroup": { + "Value": 921414446 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{7FDF8233-D26E-4EBE-9D68-1074FD9B9999}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "DisplayGroup": { + "Value": 921414446 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{3A29CBC7-A727-4DBD-8319-0D31D299A9F0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Incremented", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 2732307328 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 6.0, + "label": "IncrementMe" + } + ], + "m_sourceId": "{5F36B80D-9546-478E-AD33-BF4AFEC8FF01}", + "m_asset": { + "assetId": { + "guid": "{35A24A1D-57B7-5B0A-89C9-8BBA7657ECA5}", + "subId": 3756448882 + }, + "assetHint": "scriptcanvas/unittests/ly_sc_unittest_promoteduservariablesfunction.scriptcanvas_fn_compiled" + }, + "m_slotExecutionMap": { + "ins": [ + { + "_slotId": { + "m_id": "{32BD3CC0-AA44-4B1F-966D-4FF1561E4BC5}" + }, + "_inputs": [ + { + "_slotId": { + "m_id": "{EBE31443-CFB9-41B1-8DBA-127DB07A405A}" + }, + "_interfaceSourceId": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + } + } + ], + "_outs": [ + { + "_slotId": { + "m_id": "{7FDF8233-D26E-4EBE-9D68-1074FD9B9999}" + }, + "_name": "Out", + "_outputs": [ + { + "_slotId": { + "m_id": "{3A29CBC7-A727-4DBD-8319-0D31D299A9F0}" + }, + "_interfaceSourceId": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + } + } + ], + "_interfaceSourceId": "{E9A0BF28-5910-4B0B-B82F-6519BCC1A33A}" + } + ], + "_parsedName": "IncrementNumber_scvm", + "_interfaceSourceId": "{5F36B80D-9546-478E-AD33-BF4AFEC8FF01}" + } + ] + }, + "m_slotExecutionMapSourceInterface": { + "ins": [ + { + "displayName": "IncrementNumber", + "parsedName": "IncrementNumber_scvm", + "inputs": [ + { + "displayName": "IncrementMe", + "parsedName": "IncrementMe_scvm_1", + "datum": { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0 + }, + "sourceID": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + } + } + ], + "outs": [ + { + "displayName": "Out", + "parsedName": "Out", + "outputs": [ + { + "displayName": "Incremented", + "parsedName": "Incremented_scvm_1", + "type": { + "m_type": 3 + }, + "sourceID": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + } + } + ], + "sourceID": "{E9A0BF28-5910-4B0B-B82F-6519BCC1A33A}" + } + ], + "isPure": true, + "sourceID": "{5F36B80D-9546-478E-AD33-BF4AFEC8FF01}" + } + ], + "outKeys": [ + { + "Value": 3119148441 + } + ], + "namespacePath": [ + "scriptcanvas", + "unittests", + "ly_sc_unittest_promoteduservariablesfunction_vm" + ] + } + } + } + } + ], + "m_connections": [ + { + "Id": { + "id": 16482940914609 + }, + "Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Function Call Node: IncrementNumber)", + "Components": { + "Component_[1325606044371455697]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 1325606044371455697, + "sourceEndpoint": { + "nodeId": { + "id": 16019084446641 + }, + "slotId": { + "m_id": "{635D7286-4B19-44D4-8F5E-1B4A0CF85C9E}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 15443558828977 + }, + "slotId": { + "m_id": "{32BD3CC0-AA44-4B1F-966D-4FF1561E4BC5}" + } + } + } + } + }, + { + "Id": { + "id": 17672646855601 + }, + "Name": "srcEndpoint=(Function Call Node: Out), destEndpoint=(Expect Equal: In)", + "Components": { + "Component_[553888750995224414]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 553888750995224414, + "sourceEndpoint": { + "nodeId": { + "id": 15443558828977 + }, + "slotId": { + "m_id": "{7FDF8233-D26E-4EBE-9D68-1074FD9B9999}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 16611789933489 + }, + "slotId": { + "m_id": "{33531BA3-2152-4F66-BFDA-CEAC2EB631C7}" + } + } + } + } + }, + { + "Id": { + "id": 18003359337393 + }, + "Name": "srcEndpoint=(Function Call Node: Incremented), destEndpoint=(Expect Equal: Candidate)", + "Components": { + "Component_[6929789752232921563]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 6929789752232921563, + "sourceEndpoint": { + "nodeId": { + "id": 15443558828977 + }, + "slotId": { + "m_id": "{3A29CBC7-A727-4DBD-8319-0D31D299A9F0}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 16611789933489 + }, + "slotId": { + "m_id": "{8D954D4E-D65E-47E4-8979-BAE900582B38}" + } + } + } + } + }, + { + "Id": { + "id": 8902502386864 + }, + "Name": "srcEndpoint=(Expect Equal: Out), destEndpoint=(Mark Complete: In)", + "Components": { + "Component_[11962156650601495433]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11962156650601495433, + "sourceEndpoint": { + "nodeId": { + "id": 16611789933489 + }, + "slotId": { + "m_id": "{A8A9AB24-E5B2-4947-85CC-F87AD9F97FEB}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 7910364941488 + }, + "slotId": { + "m_id": "{F8687B16-9C64-4B5E-B000-035D9B3712EF}" + } + } + } + } + } + ] + }, + "m_assetType": "{1D497BC7-F97F-0000-80C2-359B6A010000}", + "versionData": { + "_grammarVersion": 1, + "_runtimeVersion": 1, + "_fileVersion": 1 + }, + "GraphCanvasData": [ + { + "Key": { + "id": 7910364941488 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 620.0, + 320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{69405A2B-8669-41A0-9660-74C8ECCE8B84}" + } + } + } + }, + { + "Key": { + "id": 15443558828977 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 100.0, + 100.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{61B5E23D-2C56-4183-9606-AC0A4B788B7E}" + } + } + } + }, + { + "Key": { + "id": 16019084446641 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -80.0, + 60.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{A7B4E93B-07A1-43DC-BE07-4DC5A1D64352}" + } + } + } + }, + { + "Key": { + "id": 16611789933489 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 300.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5EDF60ED-BF05-4AC4-85D9-5988FFE7C2A7}" + } + } + } + }, + { + "Key": { + "id": 8475300026301128284 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData" + } + } + } + } + ], + "StatisticsHelper": { + "InstanceCounter": [ + { + "Key": 4053150093067829293, + "Value": 1 + }, + { + "Key": 4199610336680704683, + "Value": 1 + }, + { + "Key": 6740857896271713458, + "Value": 1 + }, + { + "Key": 10204019744198319120, + "Value": 1 + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariablesFunction.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariablesFunction.scriptcanvas new file mode 100644 index 0000000000..0fe5b1a730 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PromotedUserVariablesFunction.scriptcanvas @@ -0,0 +1,1100 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "ScriptCanvasData", + "ClassData": { + "m_scriptCanvas": { + "Id": { + "id": 8918912361393065975 + }, + "Name": "Script Canvas Graph", + "Components": { + "Component_[14098532328271403379]": { + "$type": "EditorGraphVariableManagerComponent", + "Id": 14098532328271403379, + "m_variableData": { + "m_nameVariableMap": [ + { + "Key": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + }, + "Value": { + "Datum": { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0 + }, + "VariableId": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + }, + "VariableName": "IncrementMe", + "Scope": 1 + } + }, + { + "Key": { + "m_id": "{71AAA826-F605-4EA7-8445-76CBCE253BE0}" + }, + "Value": { + "Datum": { + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false + }, + "VariableId": { + "m_id": "{71AAA826-F605-4EA7-8445-76CBCE253BE0}" + }, + "VariableName": "OnlyOne", + "Scope": 1 + } + }, + { + "Key": { + "m_id": "{793CF8BD-AF82-484E-AFD3-54EA328D9663}" + }, + "Value": { + "Datum": { + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "alsoTwo" + }, + "VariableId": { + "m_id": "{793CF8BD-AF82-484E-AFD3-54EA328D9663}" + }, + "VariableName": "alsoTwo", + "Scope": 1 + } + }, + { + "Key": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + }, + "Value": { + "Datum": { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Incremented" + }, + "VariableId": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + }, + "VariableName": "Incremented", + "Scope": 1 + } + } + ] + } + }, + "Component_[2840022707551160176]": { + "$type": "{4D755CA9-AB92-462C-B24F-0B3376F19967} Graph", + "Id": 2840022707551160176, + "m_graphData": { + "m_nodes": [ + { + "Id": { + "id": 7454919658417 + }, + "Name": "SC Node(SetVariable)", + "Components": { + "Component_[13386694676262750118]": { + "$type": "SetVariableNode", + "Id": 13386694676262750118, + "Slots": [ + { + "id": { + "m_id": "{22483279-E500-40D5-A61B-2C78DAC3319A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled sends the variable referenced by this node to a Data Output slot", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{17296A41-81F9-444D-BA2E-B8DAD7C62B10}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after the referenced variable has been pushed to the Data Output slot", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{8D9CBBAD-5F75-4397-8139-B7FE79C48DFD}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{A21214FF-8D17-48B1-9A29-E805230F8942}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + } + ], + "m_variableId": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + }, + "m_variableDataInSlotId": { + "m_id": "{8D9CBBAD-5F75-4397-8139-B7FE79C48DFD}" + }, + "m_variableDataOutSlotId": { + "m_id": "{A21214FF-8D17-48B1-9A29-E805230F8942}" + } + } + } + }, + { + "Id": { + "id": 3946110127280 + }, + "Name": "SC Node(GetVariable)", + "Components": { + "Component_[14162979093169706711]": { + "$type": "GetVariableNode", + "Id": 14162979093169706711, + "Slots": [ + { + "id": { + "m_id": "{D0D0EC9C-927F-42DB-AD22-412F374326CD}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled sends the property referenced by this node to a Data Output slot", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{484C5712-DB44-4A98-8199-11E47AC3D837}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after the referenced property has been pushed to the Data Output slot", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{71712AB8-E5BC-42EC-A07E-733D0D36F830}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "m_variableId": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + }, + "m_variableDataOutSlotId": { + "m_id": "{71712AB8-E5BC-42EC-A07E-733D0D36F830}" + } + } + } + }, + { + "Id": { + "id": 5620968623025 + }, + "Name": "SC-Node(FunctionDefinitionNode)", + "Components": { + "Component_[15563419574622171620]": { + "$type": "FunctionDefinitionNode", + "Id": 15563419574622171620, + "Slots": [ + { + "id": { + "m_id": "{8362D954-5F68-4DAB-94B3-1EFA2B2774FB}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisplayGroupConnectedSlotLimitContract", + "limit": 1, + "displayGroup": "NodelingSlotDisplayGroup", + "errorMessage": "Execution nodes can only be connected to either the Input or Output, and not both at the same time." + }, + { + "$type": "DisallowReentrantExecutionContract" + } + ], + "slotName": " ", + "DisplayGroup": { + "Value": 3992535411 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "isVisibile": false, + "id": { + "m_id": "{8F6E144D-A6A4-4A5D-8D47-D4FB5E165EAC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisplayGroupConnectedSlotLimitContract", + "limit": 1, + "displayGroup": "NodelingSlotDisplayGroup", + "errorMessage": "Execution nodes can only be connected to either the Input or Output, and not both at the same time." + } + ], + "slotName": " ", + "DisplayGroup": { + "Value": 3992535411 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{67EC591D-BB4D-4D92-8FBE-617561EFD79D}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Incremented", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 452080683 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{81088CD0-BC45-4EB8-A823-DE442BF0541C}" + }, + "IsUserAdded": true + } + ], + "Datums": [ + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Incremented" + } + ], + "m_displayName": "Out", + "m_identifier": "{E9A0BF28-5910-4B0B-B82F-6519BCC1A33A}", + "m_isExecutionEntry": false + } + } + }, + { + "Id": { + "id": 4731910392753 + }, + "Name": "SC-Node(FunctionDefinitionNode)", + "Components": { + "Component_[18278450953448842587]": { + "$type": "FunctionDefinitionNode", + "Id": 18278450953448842587, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{52C8B76A-CC38-4358-9971-02B6F7E05030}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisplayGroupConnectedSlotLimitContract", + "limit": 1, + "displayGroup": "NodelingSlotDisplayGroup", + "errorMessage": "Execution nodes can only be connected to either the Input or Output, and not both at the same time." + }, + { + "$type": "DisallowReentrantExecutionContract" + } + ], + "slotName": " ", + "DisplayGroup": { + "Value": 3992535411 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{4C0849D0-627F-41BA-A8EE-A201074D5E52}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisplayGroupConnectedSlotLimitContract", + "limit": 1, + "displayGroup": "NodelingSlotDisplayGroup", + "errorMessage": "Execution nodes can only be connected to either the Input or Output, and not both at the same time." + } + ], + "slotName": " ", + "DisplayGroup": { + "Value": 3992535411 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CFDCE169-7DE0-4DD9-A599-F0EA7360CF8A}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "IncrementMe", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 452080683 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{55F1434B-40C1-40AA-91C8-A65D6F2AFDC3}" + }, + "IsUserAdded": true + } + ], + "m_displayName": "IncrementNumber", + "m_identifier": "{5F36B80D-9546-478E-AD33-BF4AFEC8FF01}" + } + } + }, + { + "Id": { + "id": 8502891678641 + }, + "Name": "SC-Node(OperatorAdd)", + "Components": { + "Component_[6948954108967528756]": { + "$type": "OperatorAdd", + "Id": 6948954108967528756, + "Slots": [ + { + "id": { + "m_id": "{4546CCB4-B493-435F-BAEC-B76996DBDC8F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{52C93C3F-A8DC-47E5-98A6-5B6A15C83F92}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{9D5A6AF3-99FE-4449-83DD-261AF2107F36}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{440FC98B-34B5-418A-9000-6E8B6BFBFDC7}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{A0113449-B8EA-441F-871E-A34F10A281AF}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Result", + "toolTip": "The result of the specified operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + { + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 1.0, + "label": "Number" + } + ] + } + } + } + ], + "m_connections": [ + { + "Id": { + "id": 11118526761905 + }, + "Name": "srcEndpoint=(Add (+): Result), destEndpoint=(Set Variable: Number)", + "Components": { + "Component_[4894099700298815938]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4894099700298815938, + "sourceEndpoint": { + "nodeId": { + "id": 8502891678641 + }, + "slotId": { + "m_id": "{A0113449-B8EA-441F-871E-A34F10A281AF}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 7454919658417 + }, + "slotId": { + "m_id": "{8D9CBBAD-5F75-4397-8139-B7FE79C48DFD}" + } + } + } + } + }, + { + "Id": { + "id": 11466419112881 + }, + "Name": "srcEndpoint=(Add (+): Out), destEndpoint=(Set Variable: In)", + "Components": { + "Component_[17374411643043616824]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 17374411643043616824, + "sourceEndpoint": { + "nodeId": { + "id": 8502891678641 + }, + "slotId": { + "m_id": "{52C93C3F-A8DC-47E5-98A6-5B6A15C83F92}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 7454919658417 + }, + "slotId": { + "m_id": "{22483279-E500-40D5-A61B-2C78DAC3319A}" + } + } + } + } + }, + { + "Id": { + "id": 11857261136817 + }, + "Name": "srcEndpoint=(Set Variable: Out), destEndpoint=(New Output: )", + "Components": { + "Component_[13113299305621275439]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 13113299305621275439, + "sourceEndpoint": { + "nodeId": { + "id": 7454919658417 + }, + "slotId": { + "m_id": "{17296A41-81F9-444D-BA2E-B8DAD7C62B10}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 5620968623025 + }, + "slotId": { + "m_id": "{8362D954-5F68-4DAB-94B3-1EFA2B2774FB}" + } + } + } + } + }, + { + "Id": { + "id": 4817988488368 + }, + "Name": "srcEndpoint=(IncrementNumber: ), destEndpoint=(Get Variable: In)", + "Components": { + "Component_[2259136399829712910]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 2259136399829712910, + "sourceEndpoint": { + "nodeId": { + "id": 4731910392753 + }, + "slotId": { + "m_id": "{4C0849D0-627F-41BA-A8EE-A201074D5E52}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 3946110127280 + }, + "slotId": { + "m_id": "{D0D0EC9C-927F-42DB-AD22-412F374326CD}" + } + } + } + } + }, + { + "Id": { + "id": 5084276460720 + }, + "Name": "srcEndpoint=(Get Variable: Number), destEndpoint=(Add (+): Number)", + "Components": { + "Component_[10085458428308435370]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10085458428308435370, + "sourceEndpoint": { + "nodeId": { + "id": 3946110127280 + }, + "slotId": { + "m_id": "{71712AB8-E5BC-42EC-A07E-733D0D36F830}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8502891678641 + }, + "slotId": { + "m_id": "{9D5A6AF3-99FE-4449-83DD-261AF2107F36}" + } + } + } + } + }, + { + "Id": { + "id": 5423578877104 + }, + "Name": "srcEndpoint=(Get Variable: Out), destEndpoint=(Add (+): In)", + "Components": { + "Component_[4574112699302556330]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4574112699302556330, + "sourceEndpoint": { + "nodeId": { + "id": 3946110127280 + }, + "slotId": { + "m_id": "{484C5712-DB44-4A98-8199-11E47AC3D837}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8502891678641 + }, + "slotId": { + "m_id": "{4546CCB4-B493-435F-BAEC-B76996DBDC8F}" + } + } + } + } + } + ] + }, + "m_assetType": "{003738F8-FA01-0000-7300-000000000000}", + "versionData": { + "_grammarVersion": 1, + "_runtimeVersion": 1, + "_fileVersion": 1 + }, + "m_variableCounter": 4, + "GraphCanvasData": [ + { + "Key": { + "id": 3946110127280 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GetVariableNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 140.0, + -140.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".getVariable" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{D085EC42-2893-4FFF-BF65-5A7BDBAA7CC7}" + } + } + } + }, + { + "Key": { + "id": 4731910392753 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "NodelingTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -260.0, + -240.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".nodeling" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{DF821D33-9967-4B89-BA06-C2B8116DF1AB}" + } + } + } + }, + { + "Key": { + "id": 5620968623025 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "NodelingTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 640.0, + 160.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".nodeling" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{462CEE46-FA16-4DE3-B00C-236F49976D74}" + } + } + } + }, + { + "Key": { + "id": 7454919658417 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "SetVariableNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 660.0, + -160.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".setVariable" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{54BBBFA0-B4C7-4FA4-BE92-51E9FA1A422B}" + } + } + } + }, + { + "Key": { + "id": 8502891678641 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 320.0, + 60.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{AE983459-5498-46B7-A50B-7DF0A9D9886D}" + } + } + } + }, + { + "Key": { + "id": 8918912361393065975 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData", + "ViewParams": { + "Scale": 0.85, + "AnchorX": -196.4705810546875, + "AnchorY": -303.5294189453125 + } + } + } + } + } + ], + "StatisticsHelper": { + "InstanceCounter": [ + { + "Key": 1244476766431948410, + "Value": 1 + }, + { + "Key": 7011818094993955847, + "Value": 2 + }, + { + "Key": 8876278780785933991, + "Value": 1 + }, + { + "Key": 11663418749378679464, + "Value": 1 + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 9d75d3ed9d..3d88f014ff 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -935,3 +935,8 @@ TEST_F(ScriptCanvasTestFixture, InterpretedExecutionOutPerformance) { RunUnitTestGraph("LY_SC_UnitTest_ExecutionOutPerformance", ExecutionMode::Interpreted); } + +TEST_F(ScriptCanvasTestFixture, PromotedUserVariables) +{ + RunUnitTestGraph("LY_SC_UnitTest_PromotedUserVariables", ExecutionMode::Interpreted); +} From 42c523b27512f3697be50be637b18c400d9cec57 Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Thu, 13 Jan 2022 16:07:44 -0800 Subject: [PATCH 176/272] Add SetEnv and UnSetEnv for environment variable to util (#6884) * Add SetEnv and UnSetEnv for environment variable to util * Move utils to AzTest * enable for ios and android * fix wrong file path --- .../Android/platform_android_files.cmake | 1 + .../AzTest/Utils_Unimplemented.cpp | 25 +++++++++++++++++++ .../Common/UnixLike/AzTest/Utils_UnixLike.cpp | 25 +++++++++++++++++++ .../Common/WinAPI/AzTest/Utils_WinAPI.cpp | 25 +++++++++++++++++++ .../Platform/Linux/platform_linux_files.cmake | 1 + .../Platform/Mac/platform_mac_files.cmake | 1 + .../Windows/platform_windows_files.cmake | 1 + .../Platform/iOS/platform_ios_files.cmake | 1 + Code/Framework/AzTest/AzTest/Utils.h | 13 ++++++++++ 9 files changed, 93 insertions(+) create mode 100644 Code/Framework/AzTest/AzTest/Platform/Common/Unimplemented/AzTest/Utils_Unimplemented.cpp create mode 100644 Code/Framework/AzTest/AzTest/Platform/Common/UnixLike/AzTest/Utils_UnixLike.cpp create mode 100644 Code/Framework/AzTest/AzTest/Platform/Common/WinAPI/AzTest/Utils_WinAPI.cpp diff --git a/Code/Framework/AzTest/AzTest/Platform/Android/platform_android_files.cmake b/Code/Framework/AzTest/AzTest/Platform/Android/platform_android_files.cmake index e0f47c8fa6..83ae97fa20 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Android/platform_android_files.cmake +++ b/Code/Framework/AzTest/AzTest/Platform/Android/platform_android_files.cmake @@ -8,6 +8,7 @@ set(FILES ../Common/UnixLike/AzTest/ColorizedOutput_UnixLike.cpp + ../Common/UnixLike/AzTest/Utils_UnixLike.cpp ScopedAutoTempDirectory_Android.cpp Platform_Android.cpp AzTest_Traits_Platform.h diff --git a/Code/Framework/AzTest/AzTest/Platform/Common/Unimplemented/AzTest/Utils_Unimplemented.cpp b/Code/Framework/AzTest/AzTest/Platform/Common/Unimplemented/AzTest/Utils_Unimplemented.cpp new file mode 100644 index 0000000000..0f91ea1020 --- /dev/null +++ b/Code/Framework/AzTest/AzTest/Platform/Common/Unimplemented/AzTest/Utils_Unimplemented.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ +{ + namespace Test + { + bool SetEnv([[maybe_unused]] const char* envname, [[maybe_unused]] const char* envvalue, [[maybe_unused]] bool overwrite) + { + return false; + } + + bool UnsetEnv([[maybe_unused]] const char* envname) + { + return false; + } + } // namespace Test +} // namespace AZ diff --git a/Code/Framework/AzTest/AzTest/Platform/Common/UnixLike/AzTest/Utils_UnixLike.cpp b/Code/Framework/AzTest/AzTest/Platform/Common/UnixLike/AzTest/Utils_UnixLike.cpp new file mode 100644 index 0000000000..8efdb5d082 --- /dev/null +++ b/Code/Framework/AzTest/AzTest/Platform/Common/UnixLike/AzTest/Utils_UnixLike.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ +{ + namespace Test + { + bool SetEnv(const char* envname, const char* envvalue, bool overwrite) + { + return setenv(envname, envvalue, overwrite) != -1; + } + + bool UnsetEnv(const char* envname) + { + return unsetenv(envname) != -1; + } + } +} diff --git a/Code/Framework/AzTest/AzTest/Platform/Common/WinAPI/AzTest/Utils_WinAPI.cpp b/Code/Framework/AzTest/AzTest/Platform/Common/WinAPI/AzTest/Utils_WinAPI.cpp new file mode 100644 index 0000000000..a06cbf7ffe --- /dev/null +++ b/Code/Framework/AzTest/AzTest/Platform/Common/WinAPI/AzTest/Utils_WinAPI.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace AZ +{ + namespace Test + { + bool SetEnv(const char* envname, const char* envvalue, [[maybe_unused]] bool overwrite) + { + return _putenv_s(envname, envvalue); + } + + bool UnsetEnv(const char* envname) + { + return SetEnv(envname, "", 1); + } + } +} diff --git a/Code/Framework/AzTest/AzTest/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzTest/AzTest/Platform/Linux/platform_linux_files.cmake index 68ca9332c7..9c6692b409 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Linux/platform_linux_files.cmake +++ b/Code/Framework/AzTest/AzTest/Platform/Linux/platform_linux_files.cmake @@ -9,6 +9,7 @@ set(FILES ../Common/UnixLike/AzTest/ColorizedOutput_UnixLike.cpp ../Common/UnixLike/AzTest/ScopedAutoTempDirectory_UnixLike.cpp + ../Common/UnixLike/AzTest/Utils_UnixLike.cpp Platform_Linux.cpp AzTest_Traits_Platform.h AzTest_Traits_Linux.h diff --git a/Code/Framework/AzTest/AzTest/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzTest/AzTest/Platform/Mac/platform_mac_files.cmake index 3cbe35792c..cb641e2113 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Mac/platform_mac_files.cmake +++ b/Code/Framework/AzTest/AzTest/Platform/Mac/platform_mac_files.cmake @@ -9,6 +9,7 @@ set(FILES ../Common/UnixLike/AzTest/ColorizedOutput_UnixLike.cpp ../Common/UnixLike/AzTest/ScopedAutoTempDirectory_UnixLike.cpp + ../Common/UnixLike/AzTest/Utils_UnixLike.cpp Platform_Mac.cpp AzTest_Traits_Platform.h AzTest_Traits_Mac.h diff --git a/Code/Framework/AzTest/AzTest/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzTest/AzTest/Platform/Windows/platform_windows_files.cmake index 656b28a373..4730b383a2 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Windows/platform_windows_files.cmake +++ b/Code/Framework/AzTest/AzTest/Platform/Windows/platform_windows_files.cmake @@ -8,6 +8,7 @@ set(FILES ../Common/WinAPI/AzTest/ColorizedOutput_WinAPI.cpp + ../Common/WinAPI/AzTest/Utils_WinAPI.cpp Platform_Windows.cpp ScopedAutoTempDirectory_Windows.cpp AzTest_Traits_Platform.h diff --git a/Code/Framework/AzTest/AzTest/Platform/iOS/platform_ios_files.cmake b/Code/Framework/AzTest/AzTest/Platform/iOS/platform_ios_files.cmake index 64bbc27bc1..81875f71e5 100644 --- a/Code/Framework/AzTest/AzTest/Platform/iOS/platform_ios_files.cmake +++ b/Code/Framework/AzTest/AzTest/Platform/iOS/platform_ios_files.cmake @@ -9,6 +9,7 @@ set(FILES ../Common/UnixLike/AzTest/ColorizedOutput_UnixLike.cpp ../Common/Unimplemented/AzTest/ScopedAutoTempDirectory_Unimplemented.cpp + ../Common/UnixLike/AzTest/Utils_UnixLike.cpp Platform_iOS.cpp AzTest_Traits_Platform.h AzTest_Traits_iOS.h diff --git a/Code/Framework/AzTest/AzTest/Utils.h b/Code/Framework/AzTest/AzTest/Utils.h index 2778e163b3..e3b45e97f2 100644 --- a/Code/Framework/AzTest/AzTest/Utils.h +++ b/Code/Framework/AzTest/AzTest/Utils.h @@ -55,6 +55,19 @@ namespace AZ // Returns the path to the engine's root by cdup from the current execution path until engine.txt is found AZStd::string GetEngineRootPath(); + //! Create or modify environment variable. + //! @param envname The environment variable name + //! @param envvalue The environment variable name + //! @param overwrite If name does exist in the environment, then its value is changed to value if overwrite is nonzero; + //! if overwrite is zero, then the value of name is not changed + //! @returns Return true if successful, otherwise false + bool SetEnv(const char* envname, const char* envvalue, bool overwrite); + + //! Remove environment variable. + //! @param envname The environment variable name + //! @returns Return true if successful, otherwise false + bool UnsetEnv(const char* envname); + //! Provides a scoped object that will create a temporary operating-system specific folder on creation, and delete it and //! its contents on destruction. This class is only available on host platforms (Windows, Mac, and Linux) class ScopedAutoTempDirectory From 22cee244c19d2cb721840128cb11a64451d58800 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Thu, 13 Jan 2022 17:30:02 -0800 Subject: [PATCH 177/272] remove a ability to reset reference, do not display reference box on user added data slots Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 342273cb2e..0e158d3e08 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -1142,7 +1142,7 @@ namespace ScriptCanvasEditor { if (slot->IsVariableReference()) { - return true; + return !slot->IsUserAdded(); } else { @@ -1254,7 +1254,7 @@ namespace ScriptCanvasEditor return nullptr; } - if (slot->IsVariableReference()) + if (slot->IsVariableReference() && !slot->IsUserAdded()) { ScriptCanvasVariableReferenceDataInterface* dataInterface = aznew ScriptCanvasVariableReferenceDataInterface(&m_variableDataModel, GetScriptCanvasId(), scriptCanvasNodeId, scriptCanvasSlotId); GraphCanvas::NodePropertyDisplay* dataDisplay = nullptr; From 1431afb51a08535a0ceabc22f11a55c0e5f5bb93 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Thu, 13 Jan 2022 18:26:39 -0800 Subject: [PATCH 178/272] remove a ability to change type on user added slots Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 1176df61dc..573a3f6e57 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -3873,7 +3873,9 @@ namespace ScriptCanvasEditor contextMenu.AddMenuAction(aznew ConvertReferenceToVariableNodeAction(&contextMenu)); contextMenu.AddMenuAction(aznew ExposeSlotMenuAction(&contextMenu)); contextMenu.AddMenuAction(aznew CreateAzEventHandlerSlotMenuAction(&contextMenu)); - contextMenu.AddMenuAction(aznew SetDataSlotTypeMenuAction(&contextMenu)); + + // disabling until references can be changed + // contextMenu.AddMenuAction(aznew SetDataSlotTypeMenuAction(&contextMenu)); return HandleContextMenu(contextMenu, slotId, screenPoint, scenePoint); } From 5c603882b348bdf220eda73e90c2491217744079 Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Thu, 13 Jan 2022 19:57:22 -0700 Subject: [PATCH 179/272] Changed the Shader instanceId to the combined assetId and supervariant index Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../Include/Atom/RPI.Public/Shader/Shader.h | 5 --- .../Code/Source/RPI.Public/Shader/Shader.cpp | 44 ++++++++++--------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/Shader.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/Shader.h index 92b67c3a7a..be20d89d65 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/Shader.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/Shader.h @@ -136,11 +136,6 @@ namespace AZ //! This tag corresponds to the ShaderAsset object's DrawListName. RHI::DrawListTag GetDrawListTag() const; - //! Changes the supervariant of the shader to the specified supervariantIndex. - //! [GFX TODO][ATOM-15813]: this can be removed when the shader InstanceDatabase can support multiple shader - //! instances with different supervariants. - void ChangeSupervariant(SupervariantIndex supervariantIndex); - private: explicit Shader(const SupervariantIndex& supervariantIndex) : m_supervariantIndex(supervariantIndex){}; Shader() = delete; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp index b1ae460af6..3830d8ee42 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp @@ -25,21 +25,34 @@ namespace AZ Data::Instance Shader::FindOrCreate(const Data::Asset& shaderAsset, const Name& supervariantName) { auto anySupervariantName = AZStd::any(supervariantName); - Data::Instance shaderInstance = Data::InstanceDatabase::Instance().FindOrCreate( - Data::InstanceId::CreateFromAssetId(shaderAsset.GetId()), shaderAsset, &anySupervariantName); - if (shaderInstance) + // retrieve the supervariant index from the shader asset + SupervariantIndex supervariantIndex = shaderAsset->GetSupervariantIndex(supervariantName); + if (!supervariantIndex.IsValid()) { - // [GFX TODO][ATOM-15813] Change InstanceDatabase to support multiple instances with different supervariants. - // At this time we do not support multiple supervariants loaded for a shader asset simultaneously, so if this shader - // is referring to the wrong supervariant we need to change it to the correct one. - SupervariantIndex supervariantIndex = shaderAsset->GetSupervariantIndex(supervariantName); - if (supervariantIndex.IsValid() && shaderInstance->GetSupervariantIndex() != supervariantIndex) - { - shaderInstance->ChangeSupervariant(supervariantIndex); - } + AZ_Error("Shader", false, "Supervariant with name %s, was not found in shader %s", supervariantName.GetCStr(), shaderAsset->GetName().GetCStr()); + return nullptr; } + // create the InstanceId from the combined assetId and supervariantIndex + const Data::AssetId& assetId = shaderAsset.GetId(); + uint32_t shaderSupervariantIndex = supervariantIndex.GetIndex(); + + const uint32_t instanceIdDataSize = sizeof(assetId.m_guid) + sizeof(assetId.m_subId) + sizeof(shaderSupervariantIndex); + uint8_t instanceIdData[instanceIdDataSize]; + uint8_t* instanceIdDataPtr = instanceIdData; + + memcpy(instanceIdDataPtr, &assetId.m_guid, sizeof(assetId.m_guid)); + instanceIdDataPtr += sizeof(assetId.m_guid); + memcpy(instanceIdDataPtr, &assetId.m_subId, sizeof(assetId.m_subId)); + instanceIdDataPtr += sizeof(assetId.m_subId); + memcpy(instanceIdDataPtr, &shaderSupervariantIndex, sizeof(shaderSupervariantIndex)); + + Data::InstanceId instanceId = Data::InstanceId::CreateData(instanceIdData, instanceIdDataSize); + + // retrieve the shader instance from the Instance database + Data::Instance shaderInstance = Data::InstanceDatabase::Instance().FindOrCreate(instanceId, shaderAsset, &anySupervariantName); + return shaderInstance; } @@ -478,14 +491,5 @@ namespace AZ return m_drawListTag; } - void Shader::ChangeSupervariant(SupervariantIndex supervariantIndex) - { - if (supervariantIndex != m_supervariantIndex) - { - m_supervariantIndex = supervariantIndex; - Init(*m_asset); - } - } - } // namespace RPI } // namespace AZ From a43cd9531328d006f8487f449555318750712115 Mon Sep 17 00:00:00 2001 From: moraaar Date: Fri, 14 Jan 2022 10:01:38 +0000 Subject: [PATCH 180/272] Fixed physics periodic tests on linux platform (#6881) - Fixed path separators, now levels will be correctly opened in linux. - Fixed casing of physics paths. - Fixed casing of files inside levels Joints_HingeNoLimitsConstrained and RigidBody_KinematicModeWorks. - Resaved a level that still used old test ids in its name but the python tests didn't match. Linux: Start 21: AutomatedTesting::PhysicsTests_Periodic.periodic::TEST_RUN 8/11 Test #21: AutomatedTesting::PhysicsTests_Periodic.periodic::TEST_RUN .................. Passed 609.87 sec Windows: Start 21: AutomatedTesting::PhysicsTests_Periodic.periodic::TEST_RUN 8/13 Test #21: AutomatedTesting::PhysicsTests_Periodic.periodic::TEST_RUN ....................... Passed 810.59 sec Signed-off-by: moraaar --- ...ameCollisionGroupSameCustomLayerCollide.py | 2 +- ...tipleForcesInSameComponentCombineForces.py | 2 +- ...DefaultLibraryUpdatedAcrossLevels_after.py | 4 +- ...efaultLibraryUpdatedAcrossLevels_before.py | 2 +- .../Material_LibraryUpdatedAcrossLevels.py | 6 +- ...iptCanvas_SpawnEntityWithPhysComponents.py | 2 +- .../Joints_HingeNoLimitsConstrained.ly | 4 +- .../0/0.ly | 3 + .../0/filelist.xml | 6 + .../0/level.pak | 3 + .../tags.txt | 0 .../terraintexture.pak | 0 .../1/1.ly | 3 + .../1/filelist.xml | 6 + .../1/level.pak | 3 + .../tags.txt | 0 .../terraintexture.pak | 0 ...5_Material_LibraryUpdatedAcrossLevels_0.ly | 3 - .../filelist.xml | 6 - .../level.pak | 3 - .../leveldata/Environment.xml | 14 - .../leveldata/GameTokens.xml | 5 - .../leveldata/TerrainTexture.xml | 7 - .../leveldata/TimeOfDay.xml | 356 ------------------ .../leveldata/VegetationMap.dat | 3 - .../terrain/terrain.pxheightfield | 3 - ...5_Material_LibraryUpdatedAcrossLevels_1.ly | 3 - .../filelist.xml | 6 - .../level.pak | 3 - .../leveldata/Environment.xml | 14 - .../leveldata/GameTokens.xml | 5 - .../leveldata/TerrainTexture.xml | 7 - .../leveldata/TimeOfDay.xml | 356 ------------------ .../leveldata/VegetationMap.dat | 3 - .../terrain/terrain.pxheightfield | 3 - .../RigidBody_KinematicModeWorks.ly | 4 +- 36 files changed, 36 insertions(+), 814 deletions(-) create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/0.ly create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/filelist.xml create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/level.pak rename AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/{C15425935_Material_LibraryUpdatedAcrossLevels_0 => 0}/tags.txt (100%) rename AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/{C15425935_Material_LibraryUpdatedAcrossLevels_0 => 0}/terraintexture.pak (100%) create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/1.ly create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/filelist.xml create mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/level.pak rename AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/{C15425935_Material_LibraryUpdatedAcrossLevels_1 => 1}/tags.txt (100%) rename AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/{C15425935_Material_LibraryUpdatedAcrossLevels_1 => 1}/terraintexture.pak (100%) delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/C15425935_Material_LibraryUpdatedAcrossLevels_0.ly delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/filelist.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/level.pak delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Environment.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/GameTokens.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TerrainTexture.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TimeOfDay.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/VegetationMap.dat delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/terrain.pxheightfield delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/C15425935_Material_LibraryUpdatedAcrossLevels_1.ly delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/filelist.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/level.pak delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Environment.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/GameTokens.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TerrainTexture.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TimeOfDay.xml delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/VegetationMap.dat delete mode 100644 AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/terrain.pxheightfield diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py index 2e40c0b557..8e8fccd725 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py @@ -127,7 +127,7 @@ def Collider_SameCollisionGroupSameCustomLayerCollide(): # Main Script # 1) Load the level helper.init_idle() - helper.open_level("physics", "Collider_SameCollisionGroupSameCustomLayerCollide") + helper.open_level("Physics", "Collider_SameCollisionGroupSameCustomLayerCollide") # 2) Enter Game Mode helper.enter_game_mode(Tests.enter_game_mode) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py index 7307f3a2fb..e5f6e236cf 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py @@ -162,7 +162,7 @@ def ForceRegion_MultipleForcesInSameComponentCombineForces(): helper.init_idle() # 1) Load Level - helper.open_level("physics", "ForceRegion_MultipleForcesInSameComponentCombineForces") + helper.open_level("Physics", "ForceRegion_MultipleForcesInSameComponentCombineForces") # 2) Enter Game Mode helper.enter_game_mode(Tests.enter_game_mode) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_after.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_after.py index 1f8cfae498..41ccc8f2dd 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_after.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_after.py @@ -229,8 +229,8 @@ def Material_DefaultLibraryUpdatedAcrossLevels_after(): for test in test_list: # 1) Open the correct level is open helper.open_level( - "physics", - f"Material_DefaultLibraryUpdatedAcrossLevels\\{test.level}" + "Physics", + os.path.join("Material_DefaultLibraryUpdatedAcrossLevels", str(test.level)) ) # 2) Enter Game Mode diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_before.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_before.py index 15db5808e2..d86a016be1 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_before.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_DefaultLibraryUpdatedAcrossLevels_before.py @@ -189,7 +189,7 @@ def Material_DefaultLibraryUpdatedAcrossLevels_before(): # 1) Open the correct level is open helper.open_level( "Physics", - f"Material_DefaultLibraryUpdatedAcrossLevels\\{test.level}" + os.path.join("Material_DefaultLibraryUpdatedAcrossLevels", str(test.level)) ) # 2) Enter Game Mode diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_LibraryUpdatedAcrossLevels.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_LibraryUpdatedAcrossLevels.py index 0b647361f6..6eebfe60bc 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_LibraryUpdatedAcrossLevels.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/material/Material_LibraryUpdatedAcrossLevels.py @@ -252,10 +252,8 @@ def Material_LibraryUpdatedAcrossLevels(): for test in test_list: # 1) Open the correct level for the test helper.open_level( - "physics", - "Material_LibraryUpdatedAcrossLevels\\Material_LibraryUpdatedAcrossLevels_{}".format( - test.level_index - ), + "Physics", + os.path.join("Material_LibraryUpdatedAcrossLevels", str(test.level_index)) ) # 2) Open Game Mode diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/script_canvas/ScriptCanvas_SpawnEntityWithPhysComponents.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/script_canvas/ScriptCanvas_SpawnEntityWithPhysComponents.py index 5862b7586b..e6e29063d6 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/script_canvas/ScriptCanvas_SpawnEntityWithPhysComponents.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/script_canvas/ScriptCanvas_SpawnEntityWithPhysComponents.py @@ -106,7 +106,7 @@ def ScriptCanvas_SpawnEntityWithPhysComponents(): # Main Script helper.init_idle() # 1) Open Level - helper.open_level("physics", "ScriptCanvas_SpawnEntityWithPhysComponents") + helper.open_level("Physics", "ScriptCanvas_SpawnEntityWithPhysComponents") # 2) Enter Game Mode helper.enter_game_mode(Tests.enter_game_mode) diff --git a/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly b/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly index 9babf84ba4..18b503bab5 100644 --- a/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly +++ b/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60276c07b45a734e4f71d695278167ea61e884f8b513906168c9642078ad5954 -size 6045 +oid sha256:0d004c329a7c5044a8fe05b6dbbf9b19de29c60acec75f13fdbc344a55aab8c7 +size 6404 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/0.ly b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/0.ly new file mode 100644 index 0000000000..b908d29eab --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/0.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e89946c224d2e765931e8ba8e33133ac24651af321a404016d9a9ea8c323db6c +size 8563 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/filelist.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/filelist.xml new file mode 100644 index 0000000000..bb94b733b3 --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/level.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/level.pak new file mode 100644 index 0000000000..614e41c4b2 --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a46437ba86135567d87d43af0c4d499bf3cfe321721dbaf6e3cda8e49427ee1 +size 40212 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/tags.txt b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/tags.txt similarity index 100% rename from AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/tags.txt rename to AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/tags.txt diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terraintexture.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/terraintexture.pak similarity index 100% rename from AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terraintexture.pak rename to AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/0/terraintexture.pak diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/1.ly b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/1.ly new file mode 100644 index 0000000000..216426fc2a --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/1.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95996da3902d885060e700c573d13144bab246b930dfeedaed6066c13c879b11 +size 8737 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/filelist.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/filelist.xml new file mode 100644 index 0000000000..5f5b4928fc --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/level.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/level.pak new file mode 100644 index 0000000000..d920770374 --- /dev/null +++ b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:894dfd4ab92aa4d1d6003aebf82cf7ff854a8b3684e010234e073879f88b64e5 +size 40210 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/tags.txt b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/tags.txt similarity index 100% rename from AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/tags.txt rename to AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/tags.txt diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terraintexture.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/terraintexture.pak similarity index 100% rename from AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terraintexture.pak rename to AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/1/terraintexture.pak diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/C15425935_Material_LibraryUpdatedAcrossLevels_0.ly b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/C15425935_Material_LibraryUpdatedAcrossLevels_0.ly deleted file mode 100644 index a5953fc44b..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/C15425935_Material_LibraryUpdatedAcrossLevels_0.ly +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:969b77ee335d2a04524a27c765dd2f2bdee048661f3ff7be0766ba69d18d5842 -size 10409 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/filelist.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/filelist.xml deleted file mode 100644 index 9a78b1bfd5..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/filelist.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/level.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/level.pak deleted file mode 100644 index 8e6b3b29cb..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/level.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:547d7fdfcd959569b69d78eb6f63c7c19fc90840d69ca2d46eca8a3e82b8db75 -size 39337 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Environment.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Environment.xml deleted file mode 100644 index 4ba36f66ae..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Environment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/GameTokens.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/GameTokens.xml deleted file mode 100644 index 668a4583bd..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/GameTokens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TerrainTexture.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TerrainTexture.xml deleted file mode 100644 index f43df05b22..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TerrainTexture.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TimeOfDay.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TimeOfDay.xml deleted file mode 100644 index 456d609b8a..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/TimeOfDay.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/VegetationMap.dat b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/VegetationMap.dat deleted file mode 100644 index dce5631cd0..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/VegetationMap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9 -size 63 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/terrain.pxheightfield b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/terrain.pxheightfield deleted file mode 100644 index 011356e521..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/terrain.pxheightfield +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:19096597087688692a225c1955f73d22c46354995fca1df8dff107a90c2f17a2 -size 4202594 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/C15425935_Material_LibraryUpdatedAcrossLevels_1.ly b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/C15425935_Material_LibraryUpdatedAcrossLevels_1.ly deleted file mode 100644 index 9f48f08a1b..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/C15425935_Material_LibraryUpdatedAcrossLevels_1.ly +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:29f752c141514cb4b50aea07e6b63de5c8f43149ddac37722e9ddb8b5f4a667d -size 9495 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/filelist.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/filelist.xml deleted file mode 100644 index 9a78b1bfd5..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/filelist.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/level.pak b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/level.pak deleted file mode 100644 index 8e6b3b29cb..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/level.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:547d7fdfcd959569b69d78eb6f63c7c19fc90840d69ca2d46eca8a3e82b8db75 -size 39337 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Environment.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Environment.xml deleted file mode 100644 index 4ba36f66ae..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Environment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/GameTokens.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/GameTokens.xml deleted file mode 100644 index 668a4583bd..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/GameTokens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TerrainTexture.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TerrainTexture.xml deleted file mode 100644 index f43df05b22..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TerrainTexture.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TimeOfDay.xml b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TimeOfDay.xml deleted file mode 100644 index 456d609b8a..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/TimeOfDay.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/VegetationMap.dat b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/VegetationMap.dat deleted file mode 100644 index dce5631cd0..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/VegetationMap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9 -size 63 diff --git a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/terrain.pxheightfield b/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/terrain.pxheightfield deleted file mode 100644 index 011356e521..0000000000 --- a/AutomatedTesting/Levels/Physics/Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/terrain.pxheightfield +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:19096597087688692a225c1955f73d22c46354995fca1df8dff107a90c2f17a2 -size 4202594 diff --git a/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly b/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly index d6052ffa7c..a4b28a9e96 100644 --- a/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly +++ b/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb97ada674d123c67d7a32eb65e81fa66472cf51f748054c4a4297649f2a0f40 -size 5568 +oid sha256:0f645243fb623258ed4b063c5a18ea414560496f97d7234782ca97884e0ed8f0 +size 5961 From 5c52df721142fb23bb316ef6704cb3ef360116c9 Mon Sep 17 00:00:00 2001 From: windbagjacket Date: Fri, 14 Jan 2022 10:48:13 +0000 Subject: [PATCH 181/272] Change property refresh to ValuesOnly instead of EntireTree Signed-off-by: windbagjacket --- .../CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp index 423145f838..5c8d2d6116 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp @@ -81,7 +81,7 @@ namespace AZ ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MeshComponentConfig::m_isRayTracingEnabled, "Use ray tracing", "Includes this mesh in ray tracing calculations.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::EntireTree) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->DataElement(AZ::Edit::UIHandlers::ComboBox, &MeshComponentConfig::m_lodType, "Lod Type", "Lod Method.") ->EnumAttribute(RPI::Cullable::LodType::Default, "Default") ->EnumAttribute(RPI::Cullable::LodType::ScreenCoverage, "Screen Coverage") From e1572ce5c9615d8b4ecaa5ee8b8409f2fcb7944b Mon Sep 17 00:00:00 2001 From: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> Date: Fri, 14 Jan 2022 08:49:42 -0800 Subject: [PATCH 182/272] Updating assimp to the v12 packages (#6861) Signed-off-by: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> --- cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake | 2 +- cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake | 2 +- cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index f7bc2721ae..f1e8fdc950 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -8,7 +8,6 @@ # shared by other platforms: ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348) -ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev11-multiplatform TARGETS assimplib PACKAGE_HASH 1a9113788b893ef4a2ee63ac01eb71b981a92894a5a51175703fa225f5804dec) ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) @@ -21,6 +20,7 @@ ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform TARGETS xxhash PACKAGE_HASH e81f3e6c4065975833996dd1fcffe46c3cf0f9e3a4207ec5f4a1b564ba75861e) # platform-specific: +ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev12-linux TARGETS assimplib PACKAGE_HASH 49d32e11c594e58a9079972ad63570dd895ac61e6148e428b9c39a62feb676ee) ly_associate_package(PACKAGE_NAME AWSGameLiftServerSDK-3.4.1-rev1-linux TARGETS AWSGameLiftServerSDK PACKAGE_HASH a8149a95bd100384af6ade97e2b21a56173740d921e6c3da8188cd51554d39af) ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-linux TARGETS TIFF PACKAGE_HASH 2377f48b2ebc2d1628d9f65186c881544c92891312abe478a20d10b85877409a) ly_associate_package(PACKAGE_NAME freetype-2.10.4.16-linux TARGETS freetype PACKAGE_HASH 3f10c703d9001ecd2bb51a3bd003d3237c02d8f947ad0161c0252fdc54cbcf97) diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index ea324a5cb7..575a2dd70e 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -8,7 +8,6 @@ # shared by other platforms: ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348) -ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev11-multiplatform TARGETS assimplib PACKAGE_HASH 1a9113788b893ef4a2ee63ac01eb71b981a92894a5a51175703fa225f5804dec) ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) @@ -21,6 +20,7 @@ ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform TARGETS xxhash PACKAGE_HASH e81f3e6c4065975833996dd1fcffe46c3cf0f9e3a4207ec5f4a1b564ba75861e) # platform-specific: +ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev12-mac TARGETS assimplib PACKAGE_HASH 12db03817553f607bee0d65b690bcaae748014f3ed9266b70384f463bc98c9d1) ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-mac TARGETS DirectXShaderCompilerDxc PACKAGE_HASH 3f77367dbb0342136ec4ebbd44bc1fedf7198089a0f83c5631248530769b2be6) ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-mac TARGETS SPIRVCross PACKAGE_HASH 78c6376ed2fd195b9b1f5fb2b56e5267a32c3aa21fb399e905308de470eb4515) ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-mac TARGETS TIFF PACKAGE_HASH c2615ccdadcc0e1d6c5ed61e5965c4d3a82193d206591b79b805c3b3ff35a4bf) diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 5441bcd76f..7fd07927cc 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -8,7 +8,6 @@ # shared by other platforms: ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348) -ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev11-multiplatform TARGETS assimplib PACKAGE_HASH 1a9113788b893ef4a2ee63ac01eb71b981a92894a5a51175703fa225f5804dec) ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) @@ -21,6 +20,7 @@ ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform ly_associate_package(PACKAGE_NAME xxhash-0.7.4-rev1-multiplatform TARGETS xxhash PACKAGE_HASH e81f3e6c4065975833996dd1fcffe46c3cf0f9e3a4207ec5f4a1b564ba75861e) # platform-specific: +ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev12-windows TARGETS assimplib PACKAGE_HASH 5273b7661a7a247bb18e8bc928d25c9cd1bd8ce9dfcc56c50742bac8fa02f0f2) ly_associate_package(PACKAGE_NAME AWSGameLiftServerSDK-3.4.1-rev1-windows TARGETS AWSGameLiftServerSDK PACKAGE_HASH a0586b006e4def65cc25f388de17dc475e417dc1e6f9d96749777c88aa8271b0) ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-windows TARGETS DirectXShaderCompilerDxc PACKAGE_HASH 803e10b94006b834cbbdd30f562a8ddf04174c2cb6956c8399ec164ef8418d1f) ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-windows TARGETS SPIRVCross PACKAGE_HASH 7d601ea9d625b1d509d38bd132a1f433d7e895b16adab76bac6103567a7a6817) From 4392c8963c66786d9db2164fb3d7384dc2e7a6f9 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Fri, 14 Jan 2022 09:00:26 -0800 Subject: [PATCH 183/272] [Linux] Prefer higher versioned clang compilers to lower versions (#6824) If the user does not specify which compiler to use via cache variables in the CMake invocation, we perform a search for which version to use. Previously this was done using a glob search on some pre-defined paths, and then sorting the results using `list(SORT ... COMPARE NATURAL)`. Sorting in this manner results in lower versions being moved to the head of the list. The first result in the list was then used. Consequently, if the user has `clang-11` and `clang-12` installed, `clang-11` was chosen. This reverses the sort order so that the highest installed version is chosen. Signed-off-by: Chris Burel --- cmake/Platform/Linux/CompilerSettings_linux.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Linux/CompilerSettings_linux.cmake b/cmake/Platform/Linux/CompilerSettings_linux.cmake index 9bb629c53b..a1a632e957 100644 --- a/cmake/Platform/Linux/CompilerSettings_linux.cmake +++ b/cmake/Platform/Linux/CompilerSettings_linux.cmake @@ -19,7 +19,7 @@ if(NOT CMAKE_C_COMPILER AND NOT CMAKE_CXX_COMPILER AND NOT "$ENV{CC}" AND NOT "$ file(GLOB clang_versions ${path_search}) if(clang_versions) # Find and pick the highest installed version - list(SORT clang_versions COMPARE NATURAL) + list(SORT clang_versions COMPARE NATURAL ORDER DESCENDING) list(GET clang_versions 0 clang_higher_version_path) string(REGEX MATCH "clang-([0-9.]*)" clang_higher_version ${clang_higher_version_path}) if(CMAKE_MATCH_1) From 7474c5480e5ed3435d078efa75fb260f6f162296 Mon Sep 17 00:00:00 2001 From: windbagjacket Date: Fri, 14 Jan 2022 17:07:13 +0000 Subject: [PATCH 184/272] Adding ray tracing toggle to behavior context so it can be used with scripting. Signed-off-by: windbagjacket --- .../Atom/Feature/Mesh/MeshFeatureProcessor.h | 1 + .../Mesh/MeshFeatureProcessorInterface.h | 2 ++ .../Code/Mocks/MockMeshFeatureProcessor.h | 1 + .../Code/Source/Mesh/MeshFeatureProcessor.cpp | 13 +++++++++++ .../CommonFeatures/Mesh/MeshComponentBus.h | 3 +++ .../Source/Mesh/MeshComponentController.cpp | 22 +++++++++++++++++++ .../Source/Mesh/MeshComponentController.h | 3 +++ .../Code/Source/AtomActorInstance.cpp | 20 ++++++++++++++++- .../Code/Source/AtomActorInstance.h | 2 ++ Gems/Vegetation/Code/Tests/VegetationMocks.h | 9 ++++++++ 10 files changed, 75 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h index 23cd76ca20..92e9c1e88a 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h @@ -176,6 +176,7 @@ namespace AZ void SetExcludeFromReflectionCubeMaps(const MeshHandle& meshHandle, bool excludeFromReflectionCubeMaps) override; void SetRayTracingEnabled(const MeshHandle& meshHandle, bool rayTracingEnabled) override; + bool GetRayTracingEnabled(const MeshHandle& meshHandle) const override; void SetVisible(const MeshHandle& meshHandle, bool visible) override; void SetUseForwardPassIblSpecular(const MeshHandle& meshHandle, bool useForwardPassIblSpecular) override; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h index 356b1936ca..f616c06e92 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h @@ -105,6 +105,8 @@ namespace AZ virtual void SetExcludeFromReflectionCubeMaps(const MeshHandle& meshHandle, bool excludeFromReflectionCubeMaps) = 0; //! Sets the option to exclude this mesh from raytracing virtual void SetRayTracingEnabled(const MeshHandle& meshHandle, bool rayTracingEnabled) = 0; + //! Gets whether this mesh is excluded from raytracing + virtual bool GetRayTracingEnabled(const MeshHandle& meshHandle) const = 0; //! Sets the mesh as visible or hidden. When the mesh is hidden it will not be rendered by the feature processor. virtual void SetVisible(const MeshHandle& meshHandle, bool visible) = 0; //! Sets the mesh to render IBL specular in the forward pass. diff --git a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h index 2c818d3c9b..af1e23aa19 100644 --- a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h @@ -38,6 +38,7 @@ namespace UnitTest MOCK_METHOD2(AcquireMesh, MeshHandle (const AZ::Render::MeshHandleDescriptor&, const AZ::Render::MaterialAssignmentMap&)); MOCK_METHOD2(AcquireMesh, MeshHandle (const AZ::Render::MeshHandleDescriptor&, const AZ::Data::Instance&)); MOCK_METHOD2(SetRayTracingEnabled, void (const MeshHandle&, bool)); + MOCK_CONST_METHOD1(GetRayTracingEnabled, bool(const MeshHandle&)); MOCK_METHOD2(SetVisible, void (const MeshHandle&, bool)); MOCK_METHOD2(SetUseForwardPassIblSpecular, void (const MeshHandle&, bool)); }; diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp index dfb2b3fe6b..6b9a3fc698 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp @@ -435,6 +435,19 @@ namespace AZ } } + bool MeshFeatureProcessor::GetRayTracingEnabled(const MeshHandle& meshHandle) const + { + if (meshHandle.IsValid()) + { + return meshHandle->m_descriptor.m_isRayTracingEnabled; + } + else + { + AZ_Assert(false, "Invalid mesh handle"); + return false; + } + } + void MeshFeatureProcessor::SetVisible(const MeshHandle& meshHandle, bool visible) { if (meshHandle.IsValid()) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h index cc9c78d356..989cbcffb2 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h @@ -51,6 +51,9 @@ namespace AZ virtual void SetVisibility(bool visible) = 0; virtual bool GetVisibility() const = 0; + virtual void SetRayTracingEnabled(bool enabled) = 0; + virtual bool GetRayTracingEnabled() const = 0; + virtual AZ::Aabb GetWorldBounds() = 0; virtual AZ::Aabb GetLocalBounds() = 0; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index b08670113b..a68ad24adf 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -182,6 +182,8 @@ namespace AZ ->Event("GetMinimumScreenCoverage", &MeshComponentRequestBus::Events::GetMinimumScreenCoverage) ->Event("SetQualityDecayRate", &MeshComponentRequestBus::Events::SetQualityDecayRate) ->Event("GetQualityDecayRate", &MeshComponentRequestBus::Events::GetQualityDecayRate) + ->Event("SetRayTracingEnabled", &MeshComponentRequestBus::Events::SetRayTracingEnabled) + ->Event("GetRayTracingEnabled", &MeshComponentRequestBus::Events::GetRayTracingEnabled) ->VirtualProperty("ModelAssetId", "GetModelAssetId", "SetModelAssetId") ->VirtualProperty("ModelAssetPath", "GetModelAssetPath", "SetModelAssetPath") ->VirtualProperty("SortKey", "GetSortKey", "SetSortKey") @@ -189,6 +191,7 @@ namespace AZ ->VirtualProperty("LodOverride", "GetLodOverride", "SetLodOverride") ->VirtualProperty("MinimumScreenCoverage", "GetMinimumScreenCoverage", "SetMinimumScreenCoverage") ->VirtualProperty("QualityDecayRate", "GetQualityDecayRate", "SetQualityDecayRate") + ->VirtualProperty("RayTracingEnabled", "GetRayTracingEnabled", "SetRayTracingEnabled") ; behaviorContext->EBus("MeshComponentNotificationBus") @@ -561,6 +564,25 @@ namespace AZ return m_isVisible; } + void MeshComponentController::SetRayTracingEnabled(bool enabled) + { + if (m_meshHandle.IsValid() && m_meshFeatureProcessor) + { + m_meshFeatureProcessor->SetRayTracingEnabled(m_meshHandle, enabled); + m_configuration.m_isRayTracingEnabled = enabled; + } + } + + bool MeshComponentController::GetRayTracingEnabled() const + { + if (m_meshHandle.IsValid() && m_meshFeatureProcessor) + { + return m_meshFeatureProcessor->GetRayTracingEnabled(m_meshHandle); + } + + return false; + } + Aabb MeshComponentController::GetWorldBounds() { if (const AZ::Aabb localBounds = GetLocalBounds(); localBounds.IsValid()) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h index 4d09b0b7b6..76cf6a1b39 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h @@ -116,6 +116,9 @@ namespace AZ void SetVisibility(bool visible) override; bool GetVisibility() const override; + void SetRayTracingEnabled(bool enabled) override; + bool GetRayTracingEnabled() const override; + // BoundsRequestBus and MeshComponentRequestBus overrides ... AZ::Aabb GetWorldBounds() override; AZ::Aabb GetLocalBounds() override; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index 58b3d8b56e..bb467b2259 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -376,7 +376,25 @@ namespace AZ::Render bool AtomActorInstance::GetVisibility() const { - return IsVisible(); + return IsVisible(); + } + + void AtomActorInstance::SetRayTracingEnabled(bool enabled) + { + if (m_meshHandle->IsValid() && m_meshFeatureProcessor) + { + m_meshFeatureProcessor->SetRayTracingEnabled(*m_meshHandle, enabled); + } + } + + bool AtomActorInstance::GetRayTracingEnabled() const + { + if (m_meshHandle->IsValid() && m_meshFeatureProcessor) + { + return m_meshFeatureProcessor->GetRayTracingEnabled(*m_meshHandle); + } + + return false; } AZ::u32 AtomActorInstance::GetJointCount() diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h index 7f646466a5..73d428216c 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h @@ -152,6 +152,8 @@ namespace AZ float GetQualityDecayRate() const override; void SetVisibility(bool visible) override; bool GetVisibility() const override; + void SetRayTracingEnabled(bool enabled) override; + bool GetRayTracingEnabled() const override; // GetWorldBounds/GetLocalBounds already overridden by BoundsRequestBus::Handler ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Vegetation/Code/Tests/VegetationMocks.h b/Gems/Vegetation/Code/Tests/VegetationMocks.h index ece0833433..3361afa177 100644 --- a/Gems/Vegetation/Code/Tests/VegetationMocks.h +++ b/Gems/Vegetation/Code/Tests/VegetationMocks.h @@ -444,6 +444,15 @@ namespace UnitTest m_GetVisibilityOutput = visibility; } + void SetRayTracingEnabled([[maybe_unused]] bool enabled) override + { + } + + bool GetRayTracingEnabled() const override + { + return false; + } + AZ::Data::AssetId m_assetIdOutput; void SetModelAssetId(AZ::Data::AssetId modelAssetId) override { From b62d130475b81e9936f89c5123d1436b4c3dfb1a Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 14 Jan 2022 11:32:29 -0600 Subject: [PATCH 185/272] Updated AnimNode registration in LyShine and Maestro to register to a member variable map (#6786) * Updated the Maestro MovieSystem and LyShine AnimationSystem to register Anim Nodes and Anim Params into a member variable map Previously the registration was occuring in a global variable map inside of Movie.cpp and UiAnimationSystem.cpp Rolled back the changes to update the CUiAnimNode and CAnimParamType to use the stateless allocator in their m_name string member. This was only needed because those types were used in global memory. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the AZStd::hash specializations for basic_string and basic_fixed_string to be transparent. This allows hashing of types that aren't basic_string or basic_fixed_string using the hash specializations for those types without needing to create an instance of those types. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Adding call to disable saving of the UserSettings.xml in the DisplaySettingsPythonBindingsFixture to avoid race condition running the test in parallel Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../test_DisplaySettingsPythonBindings.cpp | 5 + .../AzCore/AzCore/std/string/fixed_string.inl | 3 +- .../AzCore/AzCore/std/string/string.h | 5 +- Code/Legacy/CryCommon/IMovieSystem.h | 5 +- .../Styling/SelectorImplementations.h | 2 +- Gems/LyShine/Code/Source/Animation/AnimNode.h | 3 +- .../Source/Animation/UiAnimationSystem.cpp | 133 ++++----- .../Code/Source/Animation/UiAnimationSystem.h | 22 +- Gems/LyShine/Code/Source/LyShine.cpp | 2 - .../Code/Source/Cinematics/AnimPostFXNode.cpp | 3 +- Gems/Maestro/Code/Source/Cinematics/Movie.cpp | 259 ++++++++---------- Gems/Maestro/Code/Source/Cinematics/Movie.h | 20 +- .../Code/Source/TextureAtlasImpl.h | 2 +- 13 files changed, 227 insertions(+), 237 deletions(-) diff --git a/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp b/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp index fd65634d4e..b73cb039ea 100644 --- a/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp +++ b/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp @@ -35,6 +35,11 @@ namespace DisplaySettingsPythonBindingsUnitTests m_app.Start(appDesc); m_app.RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsPythonFuncsHandler::CreateDescriptor()); + + // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is + // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash + // in the unit tests. + AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); } void TearDown() override diff --git a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl index 15d2acf7a1..a1c95b7ba2 100644 --- a/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl +++ b/Code/Framework/AzCore/AzCore/std/string/fixed_string.inl @@ -1760,7 +1760,8 @@ namespace AZStd template struct hash> { - inline constexpr size_t operator()(const basic_fixed_string& value) const + using is_transparent = void; + inline constexpr size_t operator()(const basic_string_view& value) const { return hash_string(value.begin(), value.length()); } diff --git a/Code/Framework/AzCore/AzCore/std/string/string.h b/Code/Framework/AzCore/AzCore/std/string/string.h index 7dd6dd7065..56afd16226 100644 --- a/Code/Framework/AzCore/AzCore/std/string/string.h +++ b/Code/Framework/AzCore/AzCore/std/string/string.h @@ -2071,9 +2071,8 @@ namespace AZStd template struct hash< basic_string< Element, Traits, Allocator> > { - typedef basic_string< Element, Traits, Allocator> argument_type; - typedef AZStd::size_t result_type; - inline result_type operator()(const argument_type& value) const + using is_transparent = void; + inline constexpr size_t operator()(const basic_string_view& value) const { return hash_string(value.begin(), value.length()); } diff --git a/Code/Legacy/CryCommon/IMovieSystem.h b/Code/Legacy/CryCommon/IMovieSystem.h index 79c000bfca..a55d764afa 100644 --- a/Code/Legacy/CryCommon/IMovieSystem.h +++ b/Code/Legacy/CryCommon/IMovieSystem.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -184,7 +183,7 @@ public: private: AnimParamType m_type; - AZStd::basic_string, AZStd::stateless_allocator> m_name; + AZStd::string m_name; }; namespace AZStd @@ -620,7 +619,7 @@ public: , valueType(_valueType) , flags(_flags) {}; - AZStd::basic_string, AZStd::stateless_allocator> name; // parameter name. + AZStd::string name; // parameter name. CAnimParamType paramType; // parameter id. AnimValueType valueType; // value type, defines type of track to use for animating this parameter. ESupportedParamFlags flags; // combination of flags from ESupportedParamFlags. diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Styling/SelectorImplementations.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Styling/SelectorImplementations.h index 1c65bf1915..eac9abdec8 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Styling/SelectorImplementations.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Styling/SelectorImplementations.h @@ -79,7 +79,7 @@ namespace GraphCanvas private: AZStd::string m_value; - AZStd::hash::result_type m_hash; + size_t m_hash; friend class BasicSelectorEventHandler; }; diff --git a/Gems/LyShine/Code/Source/Animation/AnimNode.h b/Gems/LyShine/Code/Source/Animation/AnimNode.h index 4d139e99ca..0076276204 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimNode.h +++ b/Gems/LyShine/Code/Source/Animation/AnimNode.h @@ -13,7 +13,6 @@ #include #include "UiAnimationSystem.h" -#include /*! @@ -40,7 +39,7 @@ public: , valueType(_valueType) , flags(_flags) {}; - AZStd::basic_string, AZStd::stateless_allocator> name; // parameter name. + AZStd::string name; // parameter name. CUiAnimParamType paramType; // parameter id. EUiAnimValue valueType; // value type, defines type of track to use for animating this parameter. ESupportedParamFlags flags; // combination of flags from ESupportedParamFlags. diff --git a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp index c8818836d6..06e7110fe2 100644 --- a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp +++ b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp @@ -14,77 +14,59 @@ #include "UiAnimSerialize.h" #include -#include #include #include -#include #include #include #include ////////////////////////////////////////////////////////////////////////// -namespace -{ - using UiAnimParamSystemString = AZStd::basic_string, AZStd::stateless_allocator>; - template > - using UiAnimSystemOrderedMap = AZStd::map; - template , typename EqualKey = AZStd::equal_to> - using UiAnimSystemUnorderedMap = AZStd::unordered_map; -} // Serialization for anim nodes & param types -#define REGISTER_NODE_TYPE(name) assert(!g_animNodeEnumToStringMap.contains(eUiAnimNodeType_ ## name)); \ - g_animNodeEnumToStringMap[eUiAnimNodeType_ ## name] = AZ_STRINGIZE(name); \ - g_animNodeStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimNodeType_ ## name; +#define REGISTER_NODE_TYPE(name) assert(!m_animNodeEnumToStringMap.contains(eUiAnimNodeType_ ## name)); \ + m_animNodeEnumToStringMap[eUiAnimNodeType_ ## name] = AZ_STRINGIZE(name); \ + m_animNodeStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimNodeType_ ## name; -#define REGISTER_PARAM_TYPE(name) assert(!g_animParamEnumToStringMap.contains(eUiAnimParamType_ ## name)); \ - g_animParamEnumToStringMap[eUiAnimParamType_ ## name] = AZ_STRINGIZE(name); \ - g_animParamStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimParamType_ ## name; +#define REGISTER_PARAM_TYPE(name) assert(!m_animParamEnumToStringMap.contains(eUiAnimParamType_ ## name)); \ + m_animParamEnumToStringMap[eUiAnimParamType_ ## name] = AZ_STRINGIZE(name); \ + m_animParamStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimParamType_ ## name; -namespace + +// If you get an assert in this function, it means two node types have the same enum value. +void UiAnimationSystem::RegisterNodeTypes() { - UiAnimSystemUnorderedMap g_animNodeEnumToStringMap; - UiAnimSystemOrderedMap> g_animNodeStringToEnumMap; + REGISTER_NODE_TYPE(Entity) + REGISTER_NODE_TYPE(Director) + REGISTER_NODE_TYPE(Camera) + REGISTER_NODE_TYPE(CVar) + REGISTER_NODE_TYPE(ScriptVar) + REGISTER_NODE_TYPE(Material) + REGISTER_NODE_TYPE(Event) + REGISTER_NODE_TYPE(Group) + REGISTER_NODE_TYPE(Layer) + REGISTER_NODE_TYPE(Comment) + REGISTER_NODE_TYPE(RadialBlur) + REGISTER_NODE_TYPE(ColorCorrection) + REGISTER_NODE_TYPE(DepthOfField) + REGISTER_NODE_TYPE(ScreenFader) + REGISTER_NODE_TYPE(Light) + REGISTER_NODE_TYPE(HDRSetup) + REGISTER_NODE_TYPE(ShadowSetup) + REGISTER_NODE_TYPE(Alembic) + REGISTER_NODE_TYPE(GeomCache) + REGISTER_NODE_TYPE(Environment) + REGISTER_NODE_TYPE(ScreenDropsSetup) + REGISTER_NODE_TYPE(AzEntity) +} - UiAnimSystemUnorderedMap g_animParamEnumToStringMap; - UiAnimSystemOrderedMap> g_animParamStringToEnumMap; - - // If you get an assert in this function, it means two node types have the same enum value. - void RegisterNodeTypes() - { - REGISTER_NODE_TYPE(Entity) - REGISTER_NODE_TYPE(Director) - REGISTER_NODE_TYPE(Camera) - REGISTER_NODE_TYPE(CVar) - REGISTER_NODE_TYPE(ScriptVar) - REGISTER_NODE_TYPE(Material) - REGISTER_NODE_TYPE(Event) - REGISTER_NODE_TYPE(Group) - REGISTER_NODE_TYPE(Layer) - REGISTER_NODE_TYPE(Comment) - REGISTER_NODE_TYPE(RadialBlur) - REGISTER_NODE_TYPE(ColorCorrection) - REGISTER_NODE_TYPE(DepthOfField) - REGISTER_NODE_TYPE(ScreenFader) - REGISTER_NODE_TYPE(Light) - REGISTER_NODE_TYPE(HDRSetup) - REGISTER_NODE_TYPE(ShadowSetup) - REGISTER_NODE_TYPE(Alembic) - REGISTER_NODE_TYPE(GeomCache) - REGISTER_NODE_TYPE(Environment) - REGISTER_NODE_TYPE(ScreenDropsSetup) - REGISTER_NODE_TYPE(AzEntity) - } - - // If you get an assert in this function, it means two param types have the same enum value. - void RegisterParamTypes() - { - REGISTER_PARAM_TYPE(Event) - REGISTER_PARAM_TYPE(Float) - REGISTER_PARAM_TYPE(TrackEvent) - REGISTER_PARAM_TYPE(AzComponentField) - } +// If you get an assert in this function, it means two param types have the same enum value. +void UiAnimationSystem::RegisterParamTypes() +{ + REGISTER_PARAM_TYPE(Event) + REGISTER_PARAM_TYPE(Float) + REGISTER_PARAM_TYPE(TrackEvent) + REGISTER_PARAM_TYPE(AzComponentField) } ////////////////////////////////////////////////////////////////////////// @@ -98,6 +80,10 @@ UiAnimationSystem::UiAnimationSystem() m_lastUpdateTime = AZ::Time::ZeroTimeUs; m_nextSequenceId = 1; + + DoNodeStaticInitialisation(); + RegisterNodeTypes(); + RegisterParamTypes(); } ////////////////////////////////////////////////////////////////////////// @@ -1173,16 +1159,16 @@ void UiAnimationSystem::SerializeNodeType(EUiAnimNodeType& animNodeType, XmlNode XmlString nodeTypeString; if (xmlNode->getAttr(kType, nodeTypeString)) { - assert(g_animNodeStringToEnumMap.find(nodeTypeString.c_str()) != g_animNodeStringToEnumMap.end()); - animNodeType = stl::find_in_map(g_animNodeStringToEnumMap, nodeTypeString.c_str(), eUiAnimNodeType_Invalid); + assert(m_animNodeStringToEnumMap.contains(nodeTypeString.c_str())); + animNodeType = stl::find_in_map(m_animNodeStringToEnumMap, nodeTypeString.c_str(), eUiAnimNodeType_Invalid); } } } else { const char* pTypeString = "Invalid"; - assert(g_animNodeEnumToStringMap.find(animNodeType) != g_animNodeEnumToStringMap.end()); - pTypeString = g_animNodeEnumToStringMap[animNodeType].c_str(); + assert(m_animNodeEnumToStringMap.find(animNodeType) != m_animNodeEnumToStringMap.end()); + pTypeString = m_animNodeEnumToStringMap[animNodeType].c_str(); xmlNode->setAttr(kType, pTypeString); } } @@ -1242,8 +1228,8 @@ void UiAnimationSystem::SerializeParamType(CUiAnimParamType& animParamType, XmlN } else { - assert(g_animParamStringToEnumMap.find(paramTypeString.c_str()) != g_animParamStringToEnumMap.end()); - animParamType.m_type = stl::find_in_map(g_animParamStringToEnumMap, paramTypeString.c_str(), eUiAnimParamType_Invalid); + assert(m_animParamStringToEnumMap.contains(paramTypeString.c_str())); + animParamType.m_type = stl::find_in_map(m_animParamStringToEnumMap, paramTypeString.c_str(), eUiAnimParamType_Invalid); } } } @@ -1265,8 +1251,8 @@ void UiAnimationSystem::SerializeParamType(CUiAnimParamType& animParamType, XmlN } else { - assert(g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()); - pTypeString = g_animParamEnumToStringMap[animParamType.m_type].c_str(); + assert(m_animParamEnumToStringMap.find(animParamType.m_type) != m_animParamEnumToStringMap.end()); + pTypeString = m_animParamEnumToStringMap[animParamType.m_type].c_str(); } xmlNode->setAttr(kParamType, pTypeString); @@ -1332,9 +1318,9 @@ const char* UiAnimationSystem::GetParamTypeName(const CUiAnimParamType& animPara } else { - if (g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()) + if (m_animParamEnumToStringMap.find(animParamType.m_type) != m_animParamEnumToStringMap.end()) { - return g_animParamEnumToStringMap[animParamType.m_type].c_str(); + return m_animParamEnumToStringMap[animParamType.m_type].c_str(); } } @@ -1346,15 +1332,6 @@ void UiAnimationSystem::OnCameraCut() { } -////////////////////////////////////////////////////////////////////////// -void UiAnimationSystem::StaticInitialize() -{ - DoNodeStaticInitialisation(); - - RegisterNodeTypes(); - RegisterParamTypes(); -} - ////////////////////////////////////////////////////////////////////////// void UiAnimationSystem::Reflect(AZ::SerializeContext* serializeContext) { @@ -1380,13 +1357,13 @@ void UiAnimationSystem::Reflect(AZ::SerializeContext* serializeContext) ////////////////////////////////////////////////////////////////////////// EUiAnimNodeType UiAnimationSystem::GetNodeTypeFromString(const char* pString) const { - return stl::find_in_map(g_animNodeStringToEnumMap, pString, eUiAnimNodeType_Invalid); + return stl::find_in_map(m_animNodeStringToEnumMap, pString, eUiAnimNodeType_Invalid); } ////////////////////////////////////////////////////////////////////////// CUiAnimParamType UiAnimationSystem::GetParamTypeFromString(const char* pString) const { - const EUiAnimParamType paramType = stl::find_in_map(g_animParamStringToEnumMap, pString, eUiAnimParamType_Invalid); + const EUiAnimParamType paramType = stl::find_in_map(m_animParamStringToEnumMap, pString, eUiAnimParamType_Invalid); if (paramType != eUiAnimParamType_Invalid) { diff --git a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.h b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.h index cd51cd51d0..6c710205fa 100644 --- a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.h +++ b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.h @@ -14,6 +14,8 @@ #include #include +#include + struct PlayingUIAnimSequence { //! Sequence playing @@ -134,12 +136,10 @@ public: void SerializeParamType(CUiAnimParamType& animParamType, XmlNodeRef& xmlNode, bool bLoading, const uint version) override; void SerializeParamData(UiAnimParamData& animParamData, XmlNodeRef& xmlNode, bool bLoading) override; - static const char* GetParamTypeName(const CUiAnimParamType& animParamType); + const char* GetParamTypeName(const CUiAnimParamType& animParamType); void OnCameraCut(); - static void StaticInitialize(); - static void Reflect(AZ::SerializeContext* serializeContext); void NotifyTrackEventListeners(const char* eventName, const char* valueName, IUiAnimSequence* pSequence) override; @@ -187,5 +187,21 @@ private: // A sequence which turned on the early animation update last time uint32 m_nextSequenceId; + + using UiAnimParamSystemString = AZStd::string; + template > + using UiAnimSystemOrderedMap = AZStd::map; + template , typename EqualKey = AZStd::equal_to<>> + using UiAnimSystemUnorderedMap = AZStd::unordered_map; + + UiAnimSystemUnorderedMap m_animNodeEnumToStringMap; + UiAnimSystemOrderedMap m_animNodeStringToEnumMap; + + UiAnimSystemUnorderedMap m_animParamEnumToStringMap; + UiAnimSystemOrderedMap m_animParamStringToEnumMap; + + void RegisterNodeTypes(); + void RegisterParamTypes(); + void ShowPlayedSequencesDebug(); }; diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index 5a704329ef..b362ed2106 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -156,8 +156,6 @@ CLyShine::CLyShine([[maybe_unused]] ISystem* system) UiElementComponent::Initialize(); UiCanvasComponent::Initialize(); - UiAnimationSystem::StaticInitialize(); - AzFramework::InputChannelEventListener::Connect(); AzFramework::InputTextEventListener::Connect(); UiCursorBus::Handler::BusConnect(); diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp index b535033351..7e32301b71 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp @@ -8,7 +8,6 @@ #include -#include #include "AnimPostFXNode.h" #include "AnimSplineTrack.h" #include "CompoundSplineTrack.h" @@ -39,7 +38,7 @@ public: virtual void GetDefault(bool& val) const = 0; virtual void GetDefault(Vec4& val) const = 0; - AZStd::basic_string, AZStd::stateless_allocator> m_name; + AZStd::string m_name; protected: virtual ~CControlParamBase(){} diff --git a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp index dc0782f982..51be8a4c24 100644 --- a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -28,7 +27,6 @@ #include "LayerNode.h" #include "ShadowsSetupNode.h" -#include #include #include @@ -74,136 +72,117 @@ static SMovieSequenceAutoComplete s_movieSequenceAutoComplete; #endif ////////////////////////////////////////////////////////////////////////// -namespace -{ - using AnimParamSystemString = AZStd::basic_string, AZStd::stateless_allocator>; +// Serialization for anim nodes & param types +#define REGISTER_NODE_TYPE(name) assert(!m_animNodeEnumToStringMap.contains(AnimNodeType::name)); \ + m_animNodeEnumToStringMap[AnimNodeType::name] = AZ_STRINGIZE(name); \ + m_animNodeStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimNodeType::name; - template > - using AnimSystemOrderedMap = AZStd::map; - template , typename EqualKey = AZStd::equal_to> - using AnimSystemUnorderedMap = AZStd::unordered_map; +#define REGISTER_PARAM_TYPE(name) assert(!m_animParamEnumToStringMap.contains(AnimParamType::name)); \ + m_animParamEnumToStringMap[AnimParamType::name] = AZ_STRINGIZE(name); \ + m_animParamStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimParamType::name; + +// If you get an assert in this function, it means two node types have the same enum value. +void CMovieSystem::RegisterNodeTypes() +{ + REGISTER_NODE_TYPE(Entity) + REGISTER_NODE_TYPE(Director) + REGISTER_NODE_TYPE(Camera) + REGISTER_NODE_TYPE(CVar) + REGISTER_NODE_TYPE(ScriptVar) + REGISTER_NODE_TYPE(Material) + REGISTER_NODE_TYPE(Event) + REGISTER_NODE_TYPE(Group) + REGISTER_NODE_TYPE(Layer) + REGISTER_NODE_TYPE(Comment) + REGISTER_NODE_TYPE(RadialBlur) + REGISTER_NODE_TYPE(ColorCorrection) + REGISTER_NODE_TYPE(DepthOfField) + REGISTER_NODE_TYPE(ScreenFader) + REGISTER_NODE_TYPE(Light) + REGISTER_NODE_TYPE(ShadowSetup) + REGISTER_NODE_TYPE(Alembic) + REGISTER_NODE_TYPE(GeomCache) + REGISTER_NODE_TYPE(Environment) + REGISTER_NODE_TYPE(AzEntity) + REGISTER_NODE_TYPE(Component) } -// Serialization for anim nodes & param types -#define REGISTER_NODE_TYPE(name) assert(!g_animNodeEnumToStringMap.contains(AnimNodeType::name)); \ - g_animNodeEnumToStringMap[AnimNodeType::name] = AZ_STRINGIZE(name); \ - g_animNodeStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimNodeType::name; - -#define REGISTER_PARAM_TYPE(name) assert(!g_animParamEnumToStringMap.contains(AnimParamType::name)); \ - g_animParamEnumToStringMap[AnimParamType::name] = AZ_STRINGIZE(name); \ - g_animParamStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimParamType::name; - -namespace +// If you get an assert in this function, it means two param types have the same enum value. +void CMovieSystem::RegisterParamTypes() { - AnimSystemUnorderedMap g_animNodeEnumToStringMap; - AnimSystemOrderedMap> g_animNodeStringToEnumMap; - - AnimSystemUnorderedMap g_animParamEnumToStringMap; - AnimSystemOrderedMap> g_animParamStringToEnumMap; - - // If you get an assert in this function, it means two node types have the same enum value. - void RegisterNodeTypes() - { - REGISTER_NODE_TYPE(Entity) - REGISTER_NODE_TYPE(Director) - REGISTER_NODE_TYPE(Camera) - REGISTER_NODE_TYPE(CVar) - REGISTER_NODE_TYPE(ScriptVar) - REGISTER_NODE_TYPE(Material) - REGISTER_NODE_TYPE(Event) - REGISTER_NODE_TYPE(Group) - REGISTER_NODE_TYPE(Layer) - REGISTER_NODE_TYPE(Comment) - REGISTER_NODE_TYPE(RadialBlur) - REGISTER_NODE_TYPE(ColorCorrection) - REGISTER_NODE_TYPE(DepthOfField) - REGISTER_NODE_TYPE(ScreenFader) - REGISTER_NODE_TYPE(Light) - REGISTER_NODE_TYPE(ShadowSetup) - REGISTER_NODE_TYPE(Alembic) - REGISTER_NODE_TYPE(GeomCache) - REGISTER_NODE_TYPE(Environment) - REGISTER_NODE_TYPE(AzEntity) - REGISTER_NODE_TYPE(Component) - } - - // If you get an assert in this function, it means two param types have the same enum value. - void RegisterParamTypes() - { - REGISTER_PARAM_TYPE(FOV) - REGISTER_PARAM_TYPE(Position) - REGISTER_PARAM_TYPE(Rotation) - REGISTER_PARAM_TYPE(Scale) - REGISTER_PARAM_TYPE(Event) - REGISTER_PARAM_TYPE(Visibility) - REGISTER_PARAM_TYPE(Camera) - REGISTER_PARAM_TYPE(Animation) - REGISTER_PARAM_TYPE(Sound) - REGISTER_PARAM_TYPE(Sequence) - REGISTER_PARAM_TYPE(Console) - REGISTER_PARAM_TYPE(Music) ///@deprecated in 1.11, left in for legacy serialization - REGISTER_PARAM_TYPE(Float) - REGISTER_PARAM_TYPE(LookAt) - REGISTER_PARAM_TYPE(TrackEvent) - REGISTER_PARAM_TYPE(ShakeAmplitudeA) - REGISTER_PARAM_TYPE(ShakeAmplitudeB) - REGISTER_PARAM_TYPE(ShakeFrequencyA) - REGISTER_PARAM_TYPE(ShakeFrequencyB) - REGISTER_PARAM_TYPE(ShakeMultiplier) - REGISTER_PARAM_TYPE(ShakeNoise) - REGISTER_PARAM_TYPE(ShakeWorking) - REGISTER_PARAM_TYPE(ShakeAmpAMult) - REGISTER_PARAM_TYPE(ShakeAmpBMult) - REGISTER_PARAM_TYPE(ShakeFreqAMult) - REGISTER_PARAM_TYPE(ShakeFreqBMult) - REGISTER_PARAM_TYPE(DepthOfField) - REGISTER_PARAM_TYPE(FocusDistance) - REGISTER_PARAM_TYPE(FocusRange) - REGISTER_PARAM_TYPE(BlurAmount) - REGISTER_PARAM_TYPE(Capture) - REGISTER_PARAM_TYPE(TransformNoise) - REGISTER_PARAM_TYPE(TimeWarp) - REGISTER_PARAM_TYPE(FixedTimeStep) - REGISTER_PARAM_TYPE(NearZ) - REGISTER_PARAM_TYPE(Goto) - REGISTER_PARAM_TYPE(PositionX) - REGISTER_PARAM_TYPE(PositionY) - REGISTER_PARAM_TYPE(PositionZ) - REGISTER_PARAM_TYPE(RotationX) - REGISTER_PARAM_TYPE(RotationY) - REGISTER_PARAM_TYPE(RotationZ) - REGISTER_PARAM_TYPE(ScaleX) - REGISTER_PARAM_TYPE(ScaleY) - REGISTER_PARAM_TYPE(ScaleZ) - REGISTER_PARAM_TYPE(ColorR) - REGISTER_PARAM_TYPE(ColorG) - REGISTER_PARAM_TYPE(ColorB) - REGISTER_PARAM_TYPE(CommentText) - REGISTER_PARAM_TYPE(ScreenFader) - REGISTER_PARAM_TYPE(LightDiffuse) - REGISTER_PARAM_TYPE(LightRadius) - REGISTER_PARAM_TYPE(LightDiffuseMult) - REGISTER_PARAM_TYPE(LightHDRDynamic) - REGISTER_PARAM_TYPE(LightSpecularMult) - REGISTER_PARAM_TYPE(LightSpecPercentage) - REGISTER_PARAM_TYPE(MaterialDiffuse) - REGISTER_PARAM_TYPE(MaterialSpecular) - REGISTER_PARAM_TYPE(MaterialEmissive) - REGISTER_PARAM_TYPE(MaterialEmissiveIntensity) - REGISTER_PARAM_TYPE(MaterialOpacity) - REGISTER_PARAM_TYPE(MaterialSmoothness) - REGISTER_PARAM_TYPE(TimeRanges) - REGISTER_PARAM_TYPE(Physics) - REGISTER_PARAM_TYPE(GSMCache) - REGISTER_PARAM_TYPE(ShutterSpeed) - REGISTER_PARAM_TYPE(Physicalize) - REGISTER_PARAM_TYPE(PhysicsDriven) - REGISTER_PARAM_TYPE(SunLongitude) - REGISTER_PARAM_TYPE(SunLatitude) - REGISTER_PARAM_TYPE(MoonLongitude) - REGISTER_PARAM_TYPE(MoonLatitude) - REGISTER_PARAM_TYPE(ProceduralEyes) - } + REGISTER_PARAM_TYPE(FOV) + REGISTER_PARAM_TYPE(Position) + REGISTER_PARAM_TYPE(Rotation) + REGISTER_PARAM_TYPE(Scale) + REGISTER_PARAM_TYPE(Event) + REGISTER_PARAM_TYPE(Visibility) + REGISTER_PARAM_TYPE(Camera) + REGISTER_PARAM_TYPE(Animation) + REGISTER_PARAM_TYPE(Sound) + REGISTER_PARAM_TYPE(Sequence) + REGISTER_PARAM_TYPE(Console) + REGISTER_PARAM_TYPE(Music) ///@deprecated in 1.11, left in for legacy serialization + REGISTER_PARAM_TYPE(Float) + REGISTER_PARAM_TYPE(LookAt) + REGISTER_PARAM_TYPE(TrackEvent) + REGISTER_PARAM_TYPE(ShakeAmplitudeA) + REGISTER_PARAM_TYPE(ShakeAmplitudeB) + REGISTER_PARAM_TYPE(ShakeFrequencyA) + REGISTER_PARAM_TYPE(ShakeFrequencyB) + REGISTER_PARAM_TYPE(ShakeMultiplier) + REGISTER_PARAM_TYPE(ShakeNoise) + REGISTER_PARAM_TYPE(ShakeWorking) + REGISTER_PARAM_TYPE(ShakeAmpAMult) + REGISTER_PARAM_TYPE(ShakeAmpBMult) + REGISTER_PARAM_TYPE(ShakeFreqAMult) + REGISTER_PARAM_TYPE(ShakeFreqBMult) + REGISTER_PARAM_TYPE(DepthOfField) + REGISTER_PARAM_TYPE(FocusDistance) + REGISTER_PARAM_TYPE(FocusRange) + REGISTER_PARAM_TYPE(BlurAmount) + REGISTER_PARAM_TYPE(Capture) + REGISTER_PARAM_TYPE(TransformNoise) + REGISTER_PARAM_TYPE(TimeWarp) + REGISTER_PARAM_TYPE(FixedTimeStep) + REGISTER_PARAM_TYPE(NearZ) + REGISTER_PARAM_TYPE(Goto) + REGISTER_PARAM_TYPE(PositionX) + REGISTER_PARAM_TYPE(PositionY) + REGISTER_PARAM_TYPE(PositionZ) + REGISTER_PARAM_TYPE(RotationX) + REGISTER_PARAM_TYPE(RotationY) + REGISTER_PARAM_TYPE(RotationZ) + REGISTER_PARAM_TYPE(ScaleX) + REGISTER_PARAM_TYPE(ScaleY) + REGISTER_PARAM_TYPE(ScaleZ) + REGISTER_PARAM_TYPE(ColorR) + REGISTER_PARAM_TYPE(ColorG) + REGISTER_PARAM_TYPE(ColorB) + REGISTER_PARAM_TYPE(CommentText) + REGISTER_PARAM_TYPE(ScreenFader) + REGISTER_PARAM_TYPE(LightDiffuse) + REGISTER_PARAM_TYPE(LightRadius) + REGISTER_PARAM_TYPE(LightDiffuseMult) + REGISTER_PARAM_TYPE(LightHDRDynamic) + REGISTER_PARAM_TYPE(LightSpecularMult) + REGISTER_PARAM_TYPE(LightSpecPercentage) + REGISTER_PARAM_TYPE(MaterialDiffuse) + REGISTER_PARAM_TYPE(MaterialSpecular) + REGISTER_PARAM_TYPE(MaterialEmissive) + REGISTER_PARAM_TYPE(MaterialEmissiveIntensity) + REGISTER_PARAM_TYPE(MaterialOpacity) + REGISTER_PARAM_TYPE(MaterialSmoothness) + REGISTER_PARAM_TYPE(TimeRanges) + REGISTER_PARAM_TYPE(Physics) + REGISTER_PARAM_TYPE(GSMCache) + REGISTER_PARAM_TYPE(ShutterSpeed) + REGISTER_PARAM_TYPE(Physicalize) + REGISTER_PARAM_TYPE(PhysicsDriven) + REGISTER_PARAM_TYPE(SunLongitude) + REGISTER_PARAM_TYPE(SunLatitude) + REGISTER_PARAM_TYPE(MoonLongitude) + REGISTER_PARAM_TYPE(MoonLatitude) + REGISTER_PARAM_TYPE(ProceduralEyes) } namespace Internal @@ -1666,16 +1645,16 @@ void CMovieSystem::SerializeNodeType(AnimNodeType& animNodeType, XmlNodeRef& xml XmlString nodeTypeString; if (xmlNode->getAttr(kType, nodeTypeString)) { - assert(g_animNodeStringToEnumMap.find(nodeTypeString.c_str()) != g_animNodeStringToEnumMap.end()); - animNodeType = stl::find_in_map(g_animNodeStringToEnumMap, nodeTypeString.c_str(), AnimNodeType::Invalid); + assert(m_animNodeStringToEnumMap.find(nodeTypeString.c_str()) != m_animNodeStringToEnumMap.end()); + animNodeType = stl::find_in_map(m_animNodeStringToEnumMap, nodeTypeString.c_str(), AnimNodeType::Invalid); } } } else { const char* pTypeString = "Invalid"; - assert(g_animNodeEnumToStringMap.find(animNodeType) != g_animNodeEnumToStringMap.end()); - pTypeString = g_animNodeEnumToStringMap[animNodeType].c_str(); + assert(m_animNodeEnumToStringMap.find(animNodeType) != m_animNodeEnumToStringMap.end()); + pTypeString = m_animNodeEnumToStringMap[animNodeType].c_str(); xmlNode->setAttr(kType, pTypeString); } } @@ -1744,8 +1723,8 @@ void CMovieSystem::LoadParamTypeFromXml(CAnimParamType& animParamType, const Xml animParamType.m_name = virtualPropertyValue; } - assert(g_animParamStringToEnumMap.find(paramTypeString.c_str()) != g_animParamStringToEnumMap.end()); - animParamType.m_type = stl::find_in_map(g_animParamStringToEnumMap, paramTypeString.c_str(), AnimParamType::Invalid); + assert(m_animParamStringToEnumMap.find(paramTypeString.c_str()) != m_animParamStringToEnumMap.end()); + animParamType.m_type = stl::find_in_map(m_animParamStringToEnumMap, paramTypeString.c_str(), AnimParamType::Invalid); } } } @@ -1775,8 +1754,8 @@ void CMovieSystem::SaveParamTypeToXml(const CAnimParamType& animParamType, XmlNo xmlNode->setAttr(CAnimParamTypeXmlNames::kVirtualPropertyName, animParamType.m_name.c_str()); } - assert(g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()); - pTypeString = g_animParamEnumToStringMap[animParamType.m_type].c_str(); + assert(m_animParamEnumToStringMap.find(animParamType.m_type) != m_animParamEnumToStringMap.end()); + pTypeString = m_animParamEnumToStringMap[animParamType.m_type].c_str(); } xmlNode->setAttr(kParamType, pTypeString); @@ -1809,9 +1788,9 @@ const char* CMovieSystem::GetParamTypeName(const CAnimParamType& animParamType) } else { - if (g_animParamEnumToStringMap.find(animParamType.m_type) != g_animParamEnumToStringMap.end()) + if (m_animParamEnumToStringMap.contains(animParamType.m_type)) { - return g_animParamEnumToStringMap[animParamType.m_type].c_str(); + return m_animParamEnumToStringMap[animParamType.m_type].c_str(); } } @@ -1973,13 +1952,13 @@ void CLightAnimWrapper::RemoveCachedLightAnim(const char* name) ////////////////////////////////////////////////////////////////////////// AnimNodeType CMovieSystem::GetNodeTypeFromString(const char* pString) const { - return stl::find_in_map(g_animNodeStringToEnumMap, pString, AnimNodeType::Invalid); + return stl::find_in_map(m_animNodeStringToEnumMap, pString, AnimNodeType::Invalid); } ////////////////////////////////////////////////////////////////////////// CAnimParamType CMovieSystem::GetParamTypeFromString(const char* pString) const { - const AnimParamType paramType = stl::find_in_map(g_animParamStringToEnumMap, pString, AnimParamType::Invalid); + const AnimParamType paramType = stl::find_in_map(m_animParamStringToEnumMap, pString, AnimParamType::Invalid); if (paramType != AnimParamType::Invalid) { diff --git a/Gems/Maestro/Code/Source/Cinematics/Movie.h b/Gems/Maestro/Code/Source/Cinematics/Movie.h index ab2c2e649b..4af2b55ced 100644 --- a/Gems/Maestro/Code/Source/Cinematics/Movie.h +++ b/Gems/Maestro/Code/Source/Cinematics/Movie.h @@ -18,6 +18,7 @@ #include #include +#include #include "IMovieSystem.h" #include "IShader.h" @@ -192,7 +193,7 @@ public: void SaveParamTypeToXml(const CAnimParamType& animParamType, XmlNodeRef& xmlNode) override; void SerializeParamType(CAnimParamType& animParamType, XmlNodeRef& xmlNode, bool bLoading, const uint version) override; - static const char* GetParamTypeName(const CAnimParamType& animParamType); + const char* GetParamTypeName(const CAnimParamType& animParamType); void OnCameraCut(); @@ -290,6 +291,23 @@ private: void ShowPlayedSequencesDebug(); + + using AnimParamSystemString = AZStd::string; + + template > + using AnimSystemOrderedMap = AZStd::map; + template , typename EqualKey = AZStd::equal_to<>> + using AnimSystemUnorderedMap = AZStd::unordered_map; + + AnimSystemUnorderedMap m_animNodeEnumToStringMap; + AnimSystemOrderedMap m_animNodeStringToEnumMap; + + AnimSystemUnorderedMap m_animParamEnumToStringMap; + AnimSystemOrderedMap m_animParamStringToEnumMap; + + void RegisterNodeTypes(); + void RegisterParamTypes(); + public: static float m_mov_cameraPrecacheTime; #if !defined(_RELEASE) diff --git a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h index ce2f4826da..bb0ed650e5 100644 --- a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h +++ b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h @@ -33,7 +33,7 @@ namespace TextureAtlasNamespace struct hash_case_insensitive : public AZStd::hash { AZ_TYPE_INFO(hash_case_insensitive, "{FE0F4349-D80D-4286-8874-733966A32B29}"); - inline result_type operator()(const AZStd::string& value) const + inline size_t operator()(const AZStd::string& value) const { AZStd::string lowerStr = value; AZStd::to_lower(lowerStr.begin(), lowerStr.end()); From f87e1f6906d1ccdb4485d6e6e1237101128b68fd Mon Sep 17 00:00:00 2001 From: LesaelR <89800757+LesaelR@users.noreply.github.com> Date: Fri, 14 Jan 2022 09:48:46 -0800 Subject: [PATCH 186/272] Disabling BundleMode, AssetBundler, and MissingDependency tests on Linux. (#6888) Signed-off-by: Rosario Cox --- .../asset_processor_tests/CMakeLists.txt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index e37a5ed99b..5839093473 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -93,15 +93,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_pytest( - NAME AssetPipelineTests.AssetBundler - PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py + NAME AssetPipelineTests.AssetBuilder + PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessor - AZ::AssetBundlerBatch ) + + set(SUPPORTED_PLATFORMS "Windows" "Mac") + if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS) + return() + endif() ly_add_pytest( NAME AssetPipelineTests.BundleMode @@ -117,16 +121,16 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_pytest( - NAME AssetPipelineTests.AssetBuilder - PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py + NAME AssetPipelineTests.AssetBundler + PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessor + AZ::AssetBundlerBatch ) - ly_add_pytest( NAME AssetPipelineTests.MissingDependency PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py @@ -136,5 +140,5 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) RUNTIME_DEPENDENCIES AZ::AssetProcessorBatch ) - + endif() From 02ce4659c4312c11c6210f5745b2a592650012c0 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Fri, 14 Jan 2022 09:58:54 -0800 Subject: [PATCH 187/272] remove comment Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 0e158d3e08..92045b505f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -674,7 +674,6 @@ namespace ScriptCanvasEditor if (variable) { - // functions 2.0 set variable scope to function if (variable->GetScope() != ScriptCanvas::VariableFlags::Scope::Function) { variable->SetScope(ScriptCanvas::VariableFlags::Scope::Function); From 641e76eca9f2c0b7f4d5bf1f83d6b8b884d9ecc5 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 14 Jan 2022 10:09:14 -0800 Subject: [PATCH 188/272] Convert the loops using the Get* functions in Terrain physics and debugger components to use the new ProcessRegion* functions. Signed-off-by: amzn-sj --- .../TerrainPhysicsColliderComponent.cpp | 80 ++++++++----------- .../TerrainWorldDebuggerComponent.cpp | 37 +++------ 2 files changed, 45 insertions(+), 72 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index c51728a5c3..4a8b4680b3 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -284,21 +284,14 @@ namespace Terrain heights.clear(); heights.reserve(gridWidth * gridHeight); - for (int32_t row = 0; row < gridHeight; row++) + auto perPositionHeightCallback = [&heights, worldCenterZ] + ([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { - const float y = row * gridResolution.GetY() + worldSize.GetMin().GetY(); - for (int32_t col = 0; col < gridWidth; col++) - { - const float x = col * gridResolution.GetX() + worldSize.GetMin().GetX(); - float height = 0.0f; + heights.emplace_back(surfacePoint.m_position.GetZ() - worldCenterZ); + }; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, nullptr); - - heights.emplace_back(height - worldCenterZ); - } - } + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, + worldSize, gridResolution, perPositionHeightCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT); } uint8_t TerrainPhysicsColliderComponent::GetMaterialIdIndex(const Physics::MaterialId& materialId, const AZStd::vector& materialList) const @@ -350,42 +343,37 @@ namespace Terrain AZStd::vector materialList = GetMaterialList(); - for (int32_t row = 0; row < gridHeight; row++) + auto perPositionCallback = [&heightMaterials, &materialList, this, worldCenterZ, worldHeightBoundsMin, worldHeightBoundsMax] + (size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists) { - const float y = row * gridResolution.GetY() + worldSize.GetMin().GetY(); - for (int32_t col = 0; col < gridWidth; col++) + float height = surfacePoint.m_position.GetZ(); + + // Any heights that fall outside the range of our bounding box will get turned into holes. + if ((height < worldHeightBoundsMin) || (height > worldHeightBoundsMax)) { - const float x = col * gridResolution.GetX() + worldSize.GetMin().GetX(); - float height = 0.0f; - - bool terrainExists = true; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, &terrainExists); - - // Any heights that fall outside the range of our bounding box will get turned into holes. - if ((height < worldHeightBoundsMin) || (height > worldHeightBoundsMax)) - { - height = worldHeightBoundsMin; - terrainExists = false; - } - - // Find the best surface tag at this point. - AzFramework::SurfaceData::SurfaceTagWeight surfaceWeight; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - surfaceWeight, &AzFramework::Terrain::TerrainDataRequests::GetMaxSurfaceWeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, nullptr); - - Physics::HeightMaterialPoint point; - point.m_height = height - worldCenterZ; - point.m_quadMeshType = terrainExists ? Physics::QuadMeshType::SubdivideUpperLeftToBottomRight : Physics::QuadMeshType::Hole; - - Physics::MaterialId materialId = FindMaterialIdForSurfaceTag(surfaceWeight.m_surfaceType); - point.m_materialIndex = GetMaterialIdIndex(materialId, materialList); - - heightMaterials.emplace_back(point); + height = worldHeightBoundsMin; + terrainExists = false; } - } + + // Find the best surface tag at this point. + // We want the MaxSurfaceWeight. The ProcessSurfacePoints callback has surface weights sorted. + // So, we pick the value at the front of the list. + AzFramework::SurfaceData::SurfaceTagWeight surfaceWeight; + if (!surfacePoint.m_surfaceTags.empty()) + { + surfaceWeight = *surfacePoint.m_surfaceTags.begin(); + } + + Physics::HeightMaterialPoint point; + point.m_height = height - worldCenterZ; + point.m_quadMeshType = terrainExists ? Physics::QuadMeshType::SubdivideUpperLeftToBottomRight : Physics::QuadMeshType::Hole; + Physics::MaterialId materialId = FindMaterialIdForSurfaceTag(surfaceWeight.m_surfaceType); + point.m_materialIndex = GetMaterialIdIndex(materialId, materialList); + heightMaterials.emplace_back(point); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromRegion, + worldSize, gridResolution, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT); } AZ::Vector2 TerrainPhysicsColliderComponent::GetHeightfieldGridSpacing() const diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp index f3e0d59537..46be621307 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -354,44 +354,29 @@ namespace Terrain // For each terrain height value in the region, create the _| grid lines for that point and cache off the height value // for use with subsequent grid line calculations. auto ProcessHeightValue = [gridResolution, &previousHeight, &rowHeights, §or] - (uint32_t xIndex, uint32_t yIndex, const AZ::Vector3& position, [[maybe_unused]] bool terrainExists) + (uint32_t xIndex, uint32_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { // Don't add any vertices for the first column or first row. These grid lines will be handled by an adjacent sector, if // there is one. if ((xIndex > 0) && (yIndex > 0)) { - float x = position.GetX() - gridResolution.GetX(); - float y = position.GetY() - gridResolution.GetY(); + float x = surfacePoint.m_position.GetX() - gridResolution.GetX(); + float y = surfacePoint.m_position.GetY() - gridResolution.GetY(); - sector.m_lineVertices.emplace_back(AZ::Vector3(x, position.GetY(), previousHeight)); - sector.m_lineVertices.emplace_back(position); + sector.m_lineVertices.emplace_back(AZ::Vector3(x, surfacePoint.m_position.GetY(), previousHeight)); + sector.m_lineVertices.emplace_back(surfacePoint.m_position); - sector.m_lineVertices.emplace_back(AZ::Vector3(position.GetX(), y, rowHeights[xIndex])); - sector.m_lineVertices.emplace_back(position); + sector.m_lineVertices.emplace_back(AZ::Vector3(surfacePoint.m_position.GetX(), y, rowHeights[xIndex])); + sector.m_lineVertices.emplace_back(surfacePoint.m_position); } // Save off the heights so that we can use them to draw subsequent columns and rows. - previousHeight = position.GetZ(); - rowHeights[xIndex] = position.GetZ(); + previousHeight = surfacePoint.m_position.GetZ(); + rowHeights[xIndex] = surfacePoint.m_position.GetZ(); }; - // This set of nested loops will get replaced with a call to ProcessHeightsFromRegion once the API exists. - for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) - { - float y = region.GetMin().GetY() + (gridResolution.GetY() * yIndex); - for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) - { - float x = region.GetMin().GetX() + (gridResolution.GetX() * xIndex); - - float height = worldMinZ; - bool terrainExists = false; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, &terrainExists); - ProcessHeightValue( - aznumeric_cast(xIndex), aznumeric_cast(yIndex), AZ::Vector3(x, y, height), terrainExists); - } - } + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, + region, gridResolution, ProcessHeightValue, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); } void TerrainWorldDebuggerComponent::OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) From c778606c89e795ff885f5a732eaecd3b8946ba98 Mon Sep 17 00:00:00 2001 From: AMZN-byrcolin <68035668+byrcolin@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:27:20 -0800 Subject: [PATCH 189/272] Templates restricted (#6498) * Templates/Restricted upgrade/fixes: Fixed template storage format: templates now only store true relative paths and no longer save "origin" paths and "optional" has been removed, it was never used. Upgraded all templates to new standard Template system now correctly handles child objects: Child objects no longer have to specify restricted they inherit from parent Restricted now operates at the object level and makes no assumptions about parent Restricted templates can now be combined and seperated on creation ly_get_list_relative_filename has been deprecated for o3de_pal_dir All Gems/Projects/Templates updated to use new code Signed-off-by: byrcolin --- AutomatedTesting/CMakeLists.txt | 1 - AutomatedTesting/Gem/CMakeLists.txt | 7 +- AutomatedTesting/Gem/Code/CMakeLists.txt | 2 +- .../Gem/PythonCoverage/CMakeLists.txt | 4 + .../Gem/PythonCoverage/Code/CMakeLists.txt | 2 +- AutomatedTesting/Gem/PythonCoverage/gem.json | 6 +- .../Gem/PythonTests/Blast/CMakeLists.txt | 2 +- .../Gem/PythonTests/CMakeLists.txt | 2 +- .../Gem/PythonTests/WhiteBox/CMakeLists.txt | 2 +- AutomatedTesting/Gem/Sponza/gem.json | 11 +- AutomatedTesting/Gem/gem.json | 14 +- AutomatedTesting/project.json | 9 +- CMakeLists.txt | 73 +- Code/Editor/CMakeLists.txt | 2 +- Code/Framework/AzCore/CMakeLists.txt | 10 +- Code/Framework/AzFramework/CMakeLists.txt | 12 +- Code/Framework/AzNetworking/CMakeLists.txt | 4 +- Code/Framework/AzQtComponents/CMakeLists.txt | 2 +- Code/Framework/AzTest/CMakeLists.txt | 8 +- Code/Framework/GridMate/CMakeLists.txt | 6 +- Code/LauncherUnified/CMakeLists.txt | 2 +- Code/LauncherUnified/launcher_generator.cmake | 2 +- Code/Legacy/CryCommon/CMakeLists.txt | 2 +- Code/Legacy/CrySystem/CMakeLists.txt | 2 +- Code/Tools/AWSNativeSDKInit/CMakeLists.txt | 4 +- .../AssetBuilderSDK/CMakeLists.txt | 2 +- Code/Tools/AzTestRunner/CMakeLists.txt | 2 +- Code/Tools/CrashHandler/CMakeLists.txt | 2 +- Code/Tools/LuaIDE/CMakeLists.txt | 4 +- .../ProjectManager/Source/PythonBindings.cpp | 2 +- Code/Tools/RemoteConsole/CMakeLists.txt | 2 +- Code/Tools/SceneAPI/SceneData/CMakeLists.txt | 2 +- Code/Tools/TestImpactFramework/CMakeLists.txt | 4 +- .../Runtime/Code/CMakeLists.txt | 4 +- Gems/AWSClientAuth/CMakeLists.txt | 4 + Gems/AWSClientAuth/Code/CMakeLists.txt | 2 +- Gems/AWSClientAuth/gem.json | 4 +- Gems/AWSCore/CMakeLists.txt | 4 + Gems/AWSCore/Code/CMakeLists.txt | 4 +- Gems/AWSCore/gem.json | 8 +- Gems/AWSGameLift/gem.json | 5 +- Gems/AWSMetrics/gem.json | 4 +- Gems/Achievements/CMakeLists.txt | 4 + Gems/Achievements/Code/CMakeLists.txt | 6 +- Gems/Achievements/gem.json | 1 + Gems/AssetValidation/gem.json | 1 + Gems/Atom/Asset/CMakeLists.txt | 10 - .../Asset/ImageProcessingAtom/CMakeLists.txt | 4 + .../ImageProcessingAtom/Code/CMakeLists.txt | 6 +- Gems/Atom/Asset/ImageProcessingAtom/gem.json | 2 + Gems/Atom/Asset/Shader/CMakeLists.txt | 4 + Gems/Atom/Asset/Shader/Code/CMakeLists.txt | 6 +- Gems/Atom/Asset/Shader/gem.json | 8 +- Gems/Atom/Bootstrap/CMakeLists.txt | 4 + Gems/Atom/Bootstrap/Code/CMakeLists.txt | 2 +- Gems/Atom/Bootstrap/gem.json | 2 + Gems/Atom/CMakeLists.txt | 10 +- Gems/Atom/Component/CMakeLists.txt | 9 - .../Atom/Component/DebugCamera/CMakeLists.txt | 4 + Gems/Atom/Component/DebugCamera/gem.json | 2 + Gems/Atom/Feature/CMakeLists.txt | 9 - Gems/Atom/Feature/Common/CMakeLists.txt | 4 + Gems/Atom/Feature/Common/Code/CMakeLists.txt | 4 +- Gems/Atom/Feature/Common/gem.json | 2 + Gems/Atom/RHI/CMakeLists.txt | 8 +- Gems/Atom/RHI/Code/CMakeLists.txt | 4 +- Gems/Atom/RHI/DX12/CMakeLists.txt | 4 + Gems/Atom/RHI/DX12/Code/CMakeLists.txt | 6 +- Gems/Atom/RHI/DX12/gem.json | 2 + Gems/Atom/RHI/Metal/CMakeLists.txt | 4 + Gems/Atom/RHI/Metal/Code/CMakeLists.txt | 4 +- Gems/Atom/RHI/Metal/gem.json | 2 + Gems/Atom/RHI/Null/CMakeLists.txt | 4 + Gems/Atom/RHI/Null/Code/CMakeLists.txt | 4 +- Gems/Atom/RHI/Null/gem.json | 2 + Gems/Atom/RHI/Vulkan/CMakeLists.txt | 4 + Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt | 4 +- Gems/Atom/RHI/Vulkan/gem.json | 2 + Gems/Atom/RHI/gem.json | 7 + Gems/Atom/RPI/CMakeLists.txt | 4 + Gems/Atom/RPI/Code/CMakeLists.txt | 6 +- Gems/Atom/RPI/gem.json | 4 +- .../Tools/AtomToolsFramework/CMakeLists.txt | 4 + .../AtomToolsFramework/Code/CMakeLists.txt | 2 +- Gems/Atom/Tools/AtomToolsFramework/gem.json | 2 + Gems/Atom/Tools/CMakeLists.txt | 2 - Gems/Atom/Tools/MaterialEditor/CMakeLists.txt | 4 + .../Tools/MaterialEditor/Code/CMakeLists.txt | 2 +- Gems/Atom/Tools/MaterialEditor/gem.json | 2 + .../Code/CMakeLists.txt | 2 +- Gems/Atom/Utils/Code/CMakeLists.txt | 5 +- Gems/Atom/gem.json | 12 + Gems/AtomContent/CMakeLists.txt | 2 - Gems/AtomContent/ReferenceMaterials/gem.json | 10 +- Gems/AtomContent/Sponza/gem.json | 5 +- Gems/AtomContent/gem.json | 9 +- .../AtomBridge/CMakeLists.txt | 4 + .../AtomBridge/Code/CMakeLists.txt | 2 +- Gems/AtomLyIntegration/AtomBridge/gem.json | 2 + .../AtomLyIntegration/AtomFont/CMakeLists.txt | 4 + .../AtomFont/Code/CMakeLists.txt | 2 +- Gems/AtomLyIntegration/AtomFont/gem.json | 2 + .../AtomLyIntegration/AtomImGuiTools/gem.json | 2 + .../AtomViewportDisplayIcons/gem.json | 2 + .../AtomViewportDisplayInfo/gem.json | 2 + Gems/AtomLyIntegration/CMakeLists.txt | 9 - .../CommonFeatures/CMakeLists.txt | 4 + .../CommonFeatures/Code/CMakeLists.txt | 4 +- .../AtomLyIntegration/CommonFeatures/gem.json | 2 + Gems/AtomLyIntegration/EMotionFXAtom/gem.json | 2 + Gems/AtomLyIntegration/ImguiAtom/gem.json | 2 + .../TechnicalArt/CMakeLists.txt | 9 - .../DccScriptingInterface/CMakeLists.txt | 1 - .../DccScriptingInterface/gem.json | 4 +- Gems/AtomLyIntegration/gem.json | 12 + Gems/AtomTressFX/gem.json | 5 +- Gems/AudioEngineWwise/CMakeLists.txt | 4 + Gems/AudioEngineWwise/Code/CMakeLists.txt | 4 +- Gems/AudioEngineWwise/gem.json | 1 + Gems/AudioSystem/CMakeLists.txt | 4 + Gems/AudioSystem/Code/CMakeLists.txt | 4 +- Gems/AudioSystem/gem.json | 1 + Gems/BarrierInput/gem.json | 2 + Gems/Blast/CMakeLists.txt | 4 + Gems/Blast/Code/CMakeLists.txt | 2 +- Gems/Blast/gem.json | 1 + Gems/Camera/gem.json | 1 + Gems/CameraFramework/gem.json | 1 + Gems/CertificateManager/gem.json | 1 + Gems/CrashReporting/CMakeLists.txt | 4 + Gems/CrashReporting/Code/CMakeLists.txt | 2 +- Gems/CrashReporting/gem.json | 1 + Gems/CustomAssetExample/gem.json | 1 + Gems/DebugDraw/gem.json | 1 + Gems/DevTextures/gem.json | 1 + Gems/EMotionFX/CMakeLists.txt | 4 + Gems/EMotionFX/Code/CMakeLists.txt | 7 +- Gems/EMotionFX/gem.json | 1 + Gems/EditorPythonBindings/gem.json | 1 + Gems/ExpressionEvaluation/gem.json | 1 + Gems/FastNoise/gem.json | 1 + Gems/GameState/gem.json | 1 + Gems/GameStateSamples/CMakeLists.txt | 4 + Gems/GameStateSamples/Code/CMakeLists.txt | 2 +- Gems/GameStateSamples/gem.json | 1 + Gems/Gestures/gem.json | 1 + Gems/GradientSignal/gem.json | 1 + Gems/GraphCanvas/gem.json | 1 + Gems/GraphModel/gem.json | 1 + Gems/HttpRequestor/CMakeLists.txt | 4 + Gems/HttpRequestor/Code/CMakeLists.txt | 2 +- Gems/HttpRequestor/gem.json | 1 + Gems/ImGui/CMakeLists.txt | 4 + Gems/ImGui/Code/CMakeLists.txt | 2 +- Gems/ImGui/gem.json | 1 + Gems/InAppPurchases/CMakeLists.txt | 4 + Gems/InAppPurchases/Code/CMakeLists.txt | 2 +- Gems/InAppPurchases/gem.json | 1 + Gems/LandscapeCanvas/gem.json | 1 + Gems/LmbrCentral/CMakeLists.txt | 4 + Gems/LmbrCentral/Code/CMakeLists.txt | 4 +- Gems/LmbrCentral/gem.json | 1 + Gems/LocalUser/CMakeLists.txt | 4 + Gems/LocalUser/Code/CMakeLists.txt | 2 +- Gems/LocalUser/gem.json | 1 + Gems/LyShine/CMakeLists.txt | 4 + Gems/LyShine/Code/CMakeLists.txt | 4 +- Gems/LyShine/gem.json | 1 + Gems/LyShineExamples/gem.json | 1 + Gems/Maestro/gem.json | 1 + Gems/MessagePopup/gem.json | 1 + Gems/Metastream/CMakeLists.txt | 4 + Gems/Metastream/Code/CMakeLists.txt | 4 +- Gems/Metastream/gem.json | 1 + Gems/Microphone/CMakeLists.txt | 4 + Gems/Microphone/Code/CMakeLists.txt | 2 +- Gems/Microphone/gem.json | 1 + Gems/Multiplayer/CMakeLists.txt | 4 + Gems/Multiplayer/Code/CMakeLists.txt | 2 + Gems/Multiplayer/gem.json | 2 + Gems/MultiplayerCompression/gem.json | 1 + Gems/NvCloth/CMakeLists.txt | 4 + Gems/NvCloth/Code/CMakeLists.txt | 2 +- Gems/NvCloth/gem.json | 3 +- Gems/PhysX/CMakeLists.txt | 4 + Gems/PhysX/Code/CMakeLists.txt | 2 +- Gems/PhysXDebug/CMakeLists.txt | 4 + Gems/PhysXDebug/Code/CMakeLists.txt | 6 +- Gems/PhysXDebug/gem.json | 1 + Gems/Prefab/PrefabBuilder/gem.json | 1 + Gems/Presence/CMakeLists.txt | 4 + Gems/Presence/Code/CMakeLists.txt | 2 +- Gems/Presence/gem.json | 1 + Gems/PrimitiveAssets/gem.json | 1 + Gems/Profiler/gem.json | 1 + Gems/PythonAssetBuilder/gem.json | 1 + Gems/QtForPython/Code/CMakeLists.txt | 2 +- Gems/QtForPython/gem.json | 1 + Gems/SaveData/CMakeLists.txt | 4 + Gems/SaveData/Code/CMakeLists.txt | 2 +- Gems/SaveData/gem.json | 1 + Gems/SceneLoggingExample/gem.json | 1 + Gems/SceneProcessing/gem.json | 1 + Gems/ScriptCanvas/gem.json | 1 + Gems/ScriptCanvasDeveloper/gem.json | 1 + Gems/ScriptCanvasPhysics/gem.json | 1 + Gems/ScriptCanvasTesting/gem.json | 1 + Gems/ScriptEvents/gem.json | 1 + Gems/ScriptedEntityTweener/gem.json | 1 + Gems/SliceFavorites/gem.json | 5 + Gems/StartingPointCamera/gem.json | 1 + Gems/StartingPointInput/gem.json | 1 + Gems/StartingPointMovement/gem.json | 1 + Gems/SurfaceData/gem.json | 1 + Gems/Terrain/gem.json | 1 + Gems/TestAssetBuilder/gem.json | 1 + Gems/TextureAtlas/gem.json | 1 + Gems/TickBusOrderViewer/gem.json | 1 + Gems/Twitch/CMakeLists.txt | 4 + Gems/Twitch/Code/CMakeLists.txt | 4 +- Gems/Twitch/gem.json | 4 +- Gems/UiBasics/gem.json | 1 + Gems/Vegetation/gem.json | 1 + Gems/VideoPlaybackFramework/gem.json | 1 + Gems/VirtualGamepad/gem.json | 1 + Gems/WhiteBox/CMakeLists.txt | 4 + Gems/WhiteBox/Code/CMakeLists.txt | 4 +- Gems/WhiteBox/gem.json | 1 + Templates/AssetGem/Template/gem.json | 15 +- Templates/AssetGem/template.json | 32 +- Templates/CppToolGem/Template/gem.json | 15 +- Templates/CppToolGem/template.json | 262 ++---- Templates/DefaultGem/Template/CMakeLists.txt | 9 +- .../DefaultGem/Template/Code/CMakeLists.txt | 4 +- Templates/DefaultGem/Template/gem.json | 14 +- Templates/DefaultGem/template.json | 250 ++---- .../DefaultProject/Template/CMakeLists.txt | 1 - .../{Code => Gem}/${NameLower}_files.cmake | 0 .../${NameLower}_shared_files.cmake | 0 .../Template/Gem}/CMakeLists.txt | 11 +- .../Include/${Name}/${Name}Bus.h | 2 +- .../Android/${NameLower}_android_files.cmake | 0 .../${NameLower}_shared_android_files.cmake | 0 .../Platform/Android/PAL_android.cmake | 0 .../Linux/${NameLower}_linux_files.cmake | 0 .../${NameLower}_shared_linux_files.cmake | 0 .../Platform/Linux/PAL_linux.cmake | 0 .../Platform/Mac/${NameLower}_mac_files.cmake | 0 .../Mac/${NameLower}_shared_mac_files.cmake | 0 .../{Code => Gem}/Platform/Mac/PAL_mac.cmake | 0 .../${NameLower}_shared_windows_files.cmake | 0 .../Windows/${NameLower}_windows_files.cmake | 0 .../Platform/Windows/PAL_windows.cmake | 0 .../Platform/iOS/${NameLower}_ios_files.cmake | 0 .../iOS/${NameLower}_shared_ios_files.cmake | 0 .../{Code => Gem}/Platform/iOS/PAL_ios.cmake | 0 .../{Code => Gem}/Source/${Name}Module.cpp | 0 .../Source/${Name}SystemComponent.cpp | 2 +- .../Source/${Name}SystemComponent.h | 0 .../Template/{Code => Gem}/enabled_gems.cmake | 0 .../DefaultProject/Template/Gem/gem.json | 21 + .../DefaultProject/Template/project.json | 7 +- Templates/DefaultProject/template.json | 646 +++++--------- Templates/GemRepo/Template/gem.json | 22 +- Templates/GemRepo/template.json | 18 +- .../MinimalProject/Template/CMakeLists.txt | 1 - .../{Code => Gem}/${NameLower}_files.cmake | 0 .../${NameLower}_shared_files.cmake | 0 .../Template/Gem}/CMakeLists.txt | 11 +- .../Include/${Name}/${Name}Bus.h | 0 .../Android/${NameLower}_android_files.cmake | 0 .../${NameLower}_shared_android_files.cmake | 0 .../Platform/Android/PAL_android.cmake | 0 .../Linux/${NameLower}_linux_files.cmake | 0 .../${NameLower}_shared_linux_files.cmake | 0 .../Platform/Linux/PAL_linux.cmake | 0 .../Platform/Mac/${NameLower}_mac_files.cmake | 0 .../Mac/${NameLower}_shared_mac_files.cmake | 0 .../{Code => Gem}/Platform/Mac/PAL_mac.cmake | 0 .../${NameLower}_shared_windows_files.cmake | 0 .../Windows/${NameLower}_windows_files.cmake | 0 .../Platform/Windows/PAL_windows.cmake | 0 .../Platform/iOS/${NameLower}_ios_files.cmake | 0 .../iOS/${NameLower}_shared_ios_files.cmake | 0 .../{Code => Gem}/Platform/iOS/PAL_ios.cmake | 0 .../{Code => Gem}/Source/${Name}Module.cpp | 0 .../Source/${Name}SystemComponent.cpp | 0 .../Source/${Name}SystemComponent.h | 0 .../Template/{Code => Gem}/enabled_gems.cmake | 0 .../MinimalProject/Template/Gem/gem.json | 21 + .../Template/cmake/CompilerSettings.cmake | 4 +- .../Linux/CompilerSettings_linux.cmake | 4 +- .../MinimalProject/Template/project.json | 6 +- Templates/MinimalProject/template.json | 617 +++++-------- Templates/PythonToolGem/Template/gem.json | 6 +- Templates/PythonToolGem/template.json | 162 ++-- cmake/3rdParty.cmake | 6 +- cmake/3rdParty/BuiltInPackages.cmake | 4 +- cmake/3rdPartyPackages.cmake | 3 +- cmake/Configurations.cmake | 2 +- cmake/FileUtil.cmake | 21 +- cmake/Install.cmake | 4 +- cmake/LYTestWrappers.cmake | 2 +- cmake/LYWrappers.cmake | 2 +- cmake/PAL.cmake | 335 +++++-- cmake/PALTools.cmake | 4 +- cmake/Packaging.cmake | 2 +- cmake/Projects.cmake | 22 +- cmake/RuntimeDependencies.cmake | 2 +- engine.json | 2 +- scripts/o3de/CMakeLists.txt | 2 +- scripts/o3de/o3de/disable_gem.py | 6 - scripts/o3de/o3de/download.py | 5 - scripts/o3de/o3de/enable_gem.py | 6 - scripts/o3de/o3de/engine_template.py | 835 ++++++++++-------- scripts/o3de/o3de/get_registration.py | 6 - scripts/o3de/o3de/manifest.py | 481 +++++----- scripts/o3de/o3de/print_registration.py | 135 +-- scripts/o3de/o3de/register.py | 7 +- scripts/o3de/tests/unit_test_enable_gem.py | 11 +- .../o3de/tests/unit_test_engine_template.py | 56 +- .../o3de/tests/unit_test_gem_properties.py | 9 +- scripts/o3de/tests/unit_test_manifest.py | 64 +- .../tests/unit_test_print_registration.py | 19 +- 324 files changed, 2471 insertions(+), 2548 deletions(-) delete mode 100644 Gems/Atom/Asset/CMakeLists.txt delete mode 100644 Gems/Atom/Component/CMakeLists.txt delete mode 100644 Gems/Atom/Feature/CMakeLists.txt delete mode 100644 Gems/AtomLyIntegration/TechnicalArt/CMakeLists.txt rename Templates/DefaultProject/Template/{Code => Gem}/${NameLower}_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/${NameLower}_shared_files.cmake (100%) rename Templates/{MinimalProject/Template/Code => DefaultProject/Template/Gem}/CMakeLists.txt (87%) rename Templates/DefaultProject/Template/{Code => Gem}/Include/${Name}/${Name}Bus.h (99%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Android/${NameLower}_android_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Android/${NameLower}_shared_android_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Android/PAL_android.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Linux/${NameLower}_linux_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Linux/${NameLower}_shared_linux_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Linux/PAL_linux.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Mac/${NameLower}_mac_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Mac/${NameLower}_shared_mac_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Mac/PAL_mac.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Windows/${NameLower}_shared_windows_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Windows/${NameLower}_windows_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/Windows/PAL_windows.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/iOS/${NameLower}_ios_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/iOS/${NameLower}_shared_ios_files.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Platform/iOS/PAL_ios.cmake (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Source/${Name}Module.cpp (100%) rename Templates/DefaultProject/Template/{Code => Gem}/Source/${Name}SystemComponent.cpp (99%) rename Templates/DefaultProject/Template/{Code => Gem}/Source/${Name}SystemComponent.h (100%) rename Templates/DefaultProject/Template/{Code => Gem}/enabled_gems.cmake (100%) create mode 100644 Templates/DefaultProject/Template/Gem/gem.json rename Templates/MinimalProject/Template/{Code => Gem}/${NameLower}_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/${NameLower}_shared_files.cmake (100%) rename Templates/{DefaultProject/Template/Code => MinimalProject/Template/Gem}/CMakeLists.txt (87%) rename Templates/MinimalProject/Template/{Code => Gem}/Include/${Name}/${Name}Bus.h (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Android/${NameLower}_android_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Android/${NameLower}_shared_android_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Android/PAL_android.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Linux/${NameLower}_linux_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Linux/${NameLower}_shared_linux_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Linux/PAL_linux.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Mac/${NameLower}_mac_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Mac/${NameLower}_shared_mac_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Mac/PAL_mac.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Windows/${NameLower}_shared_windows_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Windows/${NameLower}_windows_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/Windows/PAL_windows.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/iOS/${NameLower}_ios_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/iOS/${NameLower}_shared_ios_files.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Platform/iOS/PAL_ios.cmake (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Source/${Name}Module.cpp (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Source/${Name}SystemComponent.cpp (100%) rename Templates/MinimalProject/Template/{Code => Gem}/Source/${Name}SystemComponent.h (100%) rename Templates/MinimalProject/Template/{Code => Gem}/enabled_gems.cmake (100%) create mode 100644 Templates/MinimalProject/Template/Gem/gem.json diff --git a/AutomatedTesting/CMakeLists.txt b/AutomatedTesting/CMakeLists.txt index 1c5382ba4b..9621c0accb 100644 --- a/AutomatedTesting/CMakeLists.txt +++ b/AutomatedTesting/CMakeLists.txt @@ -27,5 +27,4 @@ else() set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${project_target_name}) - add_subdirectory(Gem) endif() \ No newline at end of file diff --git a/AutomatedTesting/Gem/CMakeLists.txt b/AutomatedTesting/Gem/CMakeLists.txt index 7a411544ec..e3d8a4087a 100644 --- a/AutomatedTesting/Gem/CMakeLists.txt +++ b/AutomatedTesting/Gem/CMakeLists.txt @@ -6,6 +6,9 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) -add_subdirectory(PythonTests) -add_subdirectory(PythonCoverage) +add_subdirectory(PythonTests) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/CMakeLists.txt b/AutomatedTesting/Gem/Code/CMakeLists.txt index 8808507765..1a88d6e69a 100644 --- a/AutomatedTesting/Gem/Code/CMakeLists.txt +++ b/AutomatedTesting/Gem/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AutomatedTesting ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} diff --git a/AutomatedTesting/Gem/PythonCoverage/CMakeLists.txt b/AutomatedTesting/Gem/PythonCoverage/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/AutomatedTesting/Gem/PythonCoverage/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonCoverage/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/AutomatedTesting/Gem/PythonCoverage/Code/CMakeLists.txt b/AutomatedTesting/Gem/PythonCoverage/Code/CMakeLists.txt index a865ccc49f..ea6db88c1c 100644 --- a/AutomatedTesting/Gem/PythonCoverage/Code/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonCoverage/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) if(PAL_TRAIT_PYTHONCOVERAGE_SUPPORTED) diff --git a/AutomatedTesting/Gem/PythonCoverage/gem.json b/AutomatedTesting/Gem/PythonCoverage/gem.json index b99ce0daad..681696d78e 100644 --- a/AutomatedTesting/Gem/PythonCoverage/gem.json +++ b/AutomatedTesting/Gem/PythonCoverage/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "A tool for generating gem coverage for Python tests.", "canonical_tags": [ @@ -13,5 +14,8 @@ "PythonCoverage" ], "icon_path": "preview.png", - "requirements": "" + "requirements": "", + "documentation_url": "", + "dependencies": [ + ] } diff --git a/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt index aea2562e0b..64effb5b4c 100644 --- a/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_BLAST Traits diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 800f347359..26c03e78c2 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -10,7 +10,7 @@ # Automated Tests ################################################################################ -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt index 733e8edf29..d4554ee84b 100644 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_WHITEBOX Traits diff --git a/AutomatedTesting/Gem/Sponza/gem.json b/AutomatedTesting/Gem/Sponza/gem.json index 68749cd5f4..f36b22a805 100644 --- a/AutomatedTesting/Gem/Sponza/gem.json +++ b/AutomatedTesting/Gem/Sponza/gem.json @@ -4,14 +4,19 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "A standard test scene for Global Illumination (forked from crytek sponza scene)", "canonical_tags": [ - "Gem" + "Gem", + "Asset" ], "user_tags": [ - "Assets" + "Sponza" ], + "icon_path": "preview.png", "requirements": "", - "dependencies": [] + "documentation_url": "", + "dependencies": [ + ] } diff --git a/AutomatedTesting/Gem/gem.json b/AutomatedTesting/Gem/gem.json index df197df09d..90a0c8cb01 100644 --- a/AutomatedTesting/Gem/gem.json +++ b/AutomatedTesting/Gem/gem.json @@ -3,13 +3,21 @@ "display_name": "AutomatedTesting", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", - "origin": "Amazon Web Services, Inc.", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "Project Gem for customizing the AutomatedTesting project functionality.", "canonical_tags": [ "Gem" ], - "user_tags": [], + "user_tags": [ + "AutomatedTesting" + ], "icon_path": "preview.png", - "requirements": "" + "requirements": "", + "documentation_url": "", + "dependencies": [], + "external_subdirectories": [ + "PythonCoverage" + ] } diff --git a/AutomatedTesting/project.json b/AutomatedTesting/project.json index fc14645d2b..5a4b303570 100644 --- a/AutomatedTesting/project.json +++ b/AutomatedTesting/project.json @@ -5,12 +5,15 @@ "modules": [], "project_id": "{D816AFAE-4BB7-4FEF-88F4-E2B786DCF29D}", "android_settings": { - "package_name": "com.lumberyard.yourgame", + "package_name": "org.o3de.automatedtesting", "version_number": 1, "version_name": "1.0.0", "orientation": "landscape" }, "engine": "o3de", "display_name": "AutomatedTesting", - "icon_path": "preview.png" -} + "icon_path": "preview.png", + "external_subdirectories": [ + "Gem" + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f61a9561e8..c81581fe0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,21 +49,56 @@ include(cmake/O3DEJson.cmake) # Subdirectory processing ################################################################################ -function(add_engine_json_external_subdirectories) - read_json_external_subdirs(external_subdis ${LY_ROOT_FOLDER}/engine.json) - foreach(external_subdir ${external_subdis}) - file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER}) - list(APPEND engine_external_subdirs ${real_external_subdir}) - endforeach() +# this function is building up the LY_EXTERNAL_SUBDIRS global property +function(add_engine_gem_json_external_subdirectories gem_path) + set(gem_json_path ${gem_path}/gem.json) + if(EXISTS ${gem_json_path}) + read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json) + foreach(gem_external_subdir ${gem_external_subdirs}) + file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path}) + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) + add_engine_gem_json_external_subdirectories(${real_external_subdir}) + endforeach() + endif() +endfunction() - set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${engine_external_subdirs}) +function(add_engine_json_external_subdirectories) + read_json_external_subdirs(engine_external_subdirs ${LY_ROOT_FOLDER}/engine.json) + foreach(engine_external_subdir ${engine_external_subdirs}) + file(REAL_PATH ${engine_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER}) + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) + add_engine_gem_json_external_subdirectories(${real_external_subdir}) + endforeach() +endfunction() + +function(add_subdirectory_on_externalsubdirs) + get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS) + list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs}) + # Loop over the additional external subdirectories and invoke add_subdirectory on them + foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) + # Hash the external_directory name and append it to the Binary Directory section of add_subdirectory + # This is to deal with potential situations where multiple external directories has the same last directory name + # For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory + file(REAL_PATH ${external_directory} full_directory_path) + string(SHA256 full_directory_hash ${full_directory_path}) + # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit + # when the external subdirectory contains relative paths of significant length + string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash) + # Use the last directory as the suffix path to use for the Binary Directory + get_filename_component(directory_name ${external_directory} NAME) + add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash}) + endforeach() endfunction() # Add the projects first so the Launcher can find them include(cmake/Projects.cmake) if(NOT INSTALLED_ENGINE) - + # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra + # external subdirectories. This should go before adding the rest of the targets so the targets are availbe to the launcher. + add_engine_json_external_subdirectories() + add_subdirectory_on_externalsubdirs() + # Add the rest of the targets add_subdirectory(Assets) add_subdirectory(Code) @@ -73,31 +108,11 @@ if(NOT INSTALLED_ENGINE) add_subdirectory(Templates) add_subdirectory(Tools) - # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra - # external subdirectories - add_engine_json_external_subdirectories() else() ly_find_o3de_packages() + add_subdirectory_on_externalsubdirs() endif() -get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS) -list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs}) - -# Loop over the additional external subdirectories and invoke add_subdirectory on them -foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) - # Hash the extenal_directory name and append it to the Binary Directory section of add_subdirectory - # This is to deal with potential situations where multiple external directories has the same last directory name - # For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory - file(REAL_PATH ${external_directory} full_directory_path) - string(SHA256 full_directory_hash ${full_directory_path}) - # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit - # when the external subdirectory contains relative paths of significant length - string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash) - # Use the last directory as the suffix path to use for the Binary Directory - get_filename_component(directory_name ${external_directory} NAME) - add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash}) -endforeach() - ################################################################################ # Post-processing ################################################################################ diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt index 3358b49dce..9d74f8e3a2 100644 --- a/Code/Editor/CMakeLists.txt +++ b/Code/Editor/CMakeLists.txt @@ -63,7 +63,7 @@ ly_add_target( set(pal_cmake_files "") foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_cmake_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${enabled_platform}) + o3de_pal_dir(pal_cmake_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${enabled_platform} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) list(APPEND pal_cmake_files ${pal_cmake_dir}/editor_lib_${enabled_platform_lowercase}_files.cmake) endforeach() diff --git a/Code/Framework/AzCore/CMakeLists.txt b/Code/Framework/AzCore/CMakeLists.txt index 838142f0df..01f4086a18 100644 --- a/Code/Framework/AzCore/CMakeLists.txt +++ b/Code/Framework/AzCore/CMakeLists.txt @@ -9,8 +9,8 @@ # TODO: would like to be able to build from this path, however, the whole setup is done at the workspace's root # we also dont want to drop cmake output files everywhere. -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) if(PAL_TRAIT_PROF_PIX_SUPPORTED) set(LY_PIX_ENABLED OFF CACHE BOOL "Enables PIX profiler integration.") @@ -110,15 +110,15 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTest ) - ly_get_list_relative_pal_filename(pal_test_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(pal_tests_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME AzCore.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE AZ FILES_CMAKE Tests/azcoretests_files.cmake - ${pal_test_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${pal_tests_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake PLATFORM_INCLUDE_FILES - ${pal_test_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake + ${pal_tests_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PRIVATE Tests diff --git a/Code/Framework/AzFramework/CMakeLists.txt b/Code/Framework/AzFramework/CMakeLists.txt index 9f30d23a19..bd7af2724e 100644 --- a/Code/Framework/AzFramework/CMakeLists.txt +++ b/Code/Framework/AzFramework/CMakeLists.txt @@ -8,8 +8,8 @@ include(AzFramework/feature_options.cmake) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) ly_add_target( NAME AzFramework STATIC @@ -44,7 +44,7 @@ ly_add_source_properties( if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(test_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME AzFrameworkTestShared STATIC @@ -86,11 +86,11 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) NAMESPACE AZ FILES_CMAKE Tests/frameworktests_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${test_pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PRIVATE Tests - ${pal_dir} + ${test_pal_dir} BUILD_DEPENDENCIES PRIVATE AZ::AzFramework @@ -104,7 +104,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) NAME AZ::AzFramework.Tests ) - include(${pal_dir}/platform_specific_test_targets.cmake) + include(${test_pal_dir}/platform_specific_test_targets.cmake) endif() diff --git a/Code/Framework/AzNetworking/CMakeLists.txt b/Code/Framework/AzNetworking/CMakeLists.txt index a0a3871201..ba2eecd023 100644 --- a/Code/Framework/AzNetworking/CMakeLists.txt +++ b/Code/Framework/AzNetworking/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) ly_add_target( NAME AzNetworking STATIC diff --git a/Code/Framework/AzQtComponents/CMakeLists.txt b/Code/Framework/AzQtComponents/CMakeLists.txt index a24b68bcd7..76850e196b 100644 --- a/Code/Framework/AzQtComponents/CMakeLists.txt +++ b/Code/Framework/AzQtComponents/CMakeLists.txt @@ -10,7 +10,7 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME AzQtComponents SHARED diff --git a/Code/Framework/AzTest/CMakeLists.txt b/Code/Framework/AzTest/CMakeLists.txt index 95e444a1e9..2edc80f893 100644 --- a/Code/Framework/AzTest/CMakeLists.txt +++ b/Code/Framework/AzTest/CMakeLists.txt @@ -7,18 +7,18 @@ # if(NOT LY_MONOLITHIC_GAME) - ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/AzTest/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(pal_aztest_dir ${CMAKE_CURRENT_LIST_DIR}/AzTest/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME AzTest STATIC NAMESPACE AZ FILES_CMAKE AzTest/aztest_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${pal_aztest_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC . - ${pal_dir} + ${pal_aztest_dir} BUILD_DEPENDENCIES PUBLIC 3rdParty::googletest::GMock @@ -26,6 +26,6 @@ if(NOT LY_MONOLITHIC_GAME) 3rdParty::GoogleBenchmark AZ::AzCore PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake + ${pal_aztest_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake ) endif() diff --git a/Code/Framework/GridMate/CMakeLists.txt b/Code/Framework/GridMate/CMakeLists.txt index 0da878081d..07c2f8b4a8 100644 --- a/Code/Framework/GridMate/CMakeLists.txt +++ b/Code/Framework/GridMate/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) ly_add_target( NAME GridMate STATIC @@ -41,7 +41,7 @@ ly_add_source_properties( ################################################################################ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_get_list_relative_pal_filename(pal_test_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(pal_test_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME GridMate.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE AZ diff --git a/Code/LauncherUnified/CMakeLists.txt b/Code/LauncherUnified/CMakeLists.txt index 845c2cd6c7..8097570462 100644 --- a/Code/LauncherUnified/CMakeLists.txt +++ b/Code/LauncherUnified/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/LauncherUnified_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index 550a67bc49..70bcf776af 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -201,7 +201,7 @@ function(ly_delayed_generate_static_modules_inl) foreach(game_gem_dependency ${all_game_gem_dependencies}) # Sometimes, a gem's Client variant may be an interface library - # which dependes on multiple gem targets. The interface libraries + # which depends on multiple gem targets. The interface libraries # should be skipped; the real dependencies of the interface will be processed if(TARGET ${game_gem_dependency}) get_target_property(target_type ${game_gem_dependency} TYPE) diff --git a/Code/Legacy/CryCommon/CMakeLists.txt b/Code/Legacy/CryCommon/CMakeLists.txt index 1556c6a099..629f26d217 100644 --- a/Code/Legacy/CryCommon/CMakeLists.txt +++ b/Code/Legacy/CryCommon/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME CryCommon STATIC diff --git a/Code/Legacy/CrySystem/CMakeLists.txt b/Code/Legacy/CrySystem/CMakeLists.txt index ebfc866f4a..3153205b69 100644 --- a/Code/Legacy/CrySystem/CMakeLists.txt +++ b/Code/Legacy/CrySystem/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) add_subdirectory(XML) diff --git a/Code/Tools/AWSNativeSDKInit/CMakeLists.txt b/Code/Tools/AWSNativeSDKInit/CMakeLists.txt index 57ee31d30d..04f61eb924 100644 --- a/Code/Tools/AWSNativeSDKInit/CMakeLists.txt +++ b/Code/Tools/AWSNativeSDKInit/CMakeLists.txt @@ -6,14 +6,14 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/source/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME AWSNativeSDKInit STATIC NAMESPACE AZ FILES_CMAKE aws_native_sdk_init_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC include diff --git a/Code/Tools/AssetProcessor/AssetBuilderSDK/CMakeLists.txt b/Code/Tools/AssetProcessor/AssetBuilderSDK/CMakeLists.txt index bfbcc35663..f32d55844e 100644 --- a/Code/Tools/AssetProcessor/AssetBuilderSDK/CMakeLists.txt +++ b/Code/Tools/AssetProcessor/AssetBuilderSDK/CMakeLists.txt @@ -11,7 +11,7 @@ ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/AssetBuilderSDK/Pla set(pal_files "") foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/AssetBuilderSDK/Platform/${enabled_platform}) + o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/AssetBuilderSDK/Platform/${enabled_platform} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) list(APPEND pal_files ${pal_dir}/assetbuildersdk_${enabled_platform_lowercase}_files.cmake) endforeach() diff --git a/Code/Tools/AzTestRunner/CMakeLists.txt b/Code/Tools/AzTestRunner/CMakeLists.txt index 5f3bb829a8..2bd74fa1a1 100644 --- a/Code/Tools/AzTestRunner/CMakeLists.txt +++ b/Code/Tools/AzTestRunner/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/platform_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Code/Tools/CrashHandler/CMakeLists.txt b/Code/Tools/CrashHandler/CMakeLists.txt index 259a7d2891..db50741326 100644 --- a/Code/Tools/CrashHandler/CMakeLists.txt +++ b/Code/Tools/CrashHandler/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Code/Tools/LuaIDE/CMakeLists.txt b/Code/Tools/LuaIDE/CMakeLists.txt index 98c8d7f04b..58e0fe505a 100644 --- a/Code/Tools/LuaIDE/CMakeLists.txt +++ b/Code/Tools/LuaIDE/CMakeLists.txt @@ -10,6 +10,8 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) + ly_add_target( NAME LuaIDE APPLICATION NAMESPACE AZ @@ -18,7 +20,7 @@ ly_add_target( AUTORCC FILES_CMAKE lua_ide_files.cmake - Platform/${PAL_PLATFORM_NAME}/lua_ide_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${pal_dir}/lua_ide_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PRIVATE . diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 35bdfe0031..7c436a3a70 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -1221,7 +1221,7 @@ namespace O3DE::ProjectManager auto result = ExecuteWithLockErrorHandling( [&] { - for (auto repoUri : m_manifest.attr("get_repos")()) + for (auto repoUri : m_manifest.attr("get_manifest_repos")()) { gemRepos.push_back(GetGemRepoInfo(repoUri)); } diff --git a/Code/Tools/RemoteConsole/CMakeLists.txt b/Code/Tools/RemoteConsole/CMakeLists.txt index d2685b2aea..b9a08650b6 100644 --- a/Code/Tools/RemoteConsole/CMakeLists.txt +++ b/Code/Tools/RemoteConsole/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME RemoteConsoleCore STATIC diff --git a/Code/Tools/SceneAPI/SceneData/CMakeLists.txt b/Code/Tools/SceneAPI/SceneData/CMakeLists.txt index 5507ada2b9..0d4ef4a5df 100644 --- a/Code/Tools/SceneAPI/SceneData/CMakeLists.txt +++ b/Code/Tools/SceneAPI/SceneData/CMakeLists.txt @@ -10,7 +10,7 @@ if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_add_target( NAME SceneData SHARED diff --git a/Code/Tools/TestImpactFramework/CMakeLists.txt b/Code/Tools/TestImpactFramework/CMakeLists.txt index 1cdf02d101..15d93b1a70 100644 --- a/Code/Tools/TestImpactFramework/CMakeLists.txt +++ b/Code/Tools/TestImpactFramework/CMakeLists.txt @@ -6,9 +6,9 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) -include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) +include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) if(PAL_TRAIT_TEST_IMPACT_FRAMEWORK_SUPPORTED) add_subdirectory(Runtime) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/CMakeLists.txt b/Code/Tools/TestImpactFramework/Runtime/Code/CMakeLists.txt index 0b8432642a..f3262a26af 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/CMakeLists.txt +++ b/Code/Tools/TestImpactFramework/Runtime/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME TestImpact.Runtime.Static STATIC diff --git a/Gems/AWSClientAuth/CMakeLists.txt b/Gems/AWSClientAuth/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AWSClientAuth/CMakeLists.txt +++ b/Gems/AWSClientAuth/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AWSClientAuth/Code/CMakeLists.txt b/Gems/AWSClientAuth/Code/CMakeLists.txt index 1f0c119f5a..ac9d221f07 100644 --- a/Gems/AWSClientAuth/Code/CMakeLists.txt +++ b/Gems/AWSClientAuth/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AWSClientAuth.Static STATIC diff --git a/Gems/AWSClientAuth/gem.json b/Gems/AWSClientAuth/gem.json index 9c7188f103..d6729cee99 100644 --- a/Gems/AWSClientAuth/gem.json +++ b/Gems/AWSClientAuth/gem.json @@ -3,7 +3,8 @@ "display_name": "AWS Client Authorization", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", - "origin": "Amazon Web Services, Inc.", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "AWS Client Auth provides client authentication and AWS authorization solution.", "canonical_tags": [ @@ -15,6 +16,7 @@ "SDK" ], "icon_path": "preview.png", + "requirements": "", "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/aws/aws-client-auth/", "dependencies": [ "AWSCore", diff --git a/Gems/AWSCore/CMakeLists.txt b/Gems/AWSCore/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AWSCore/CMakeLists.txt +++ b/Gems/AWSCore/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 877696e26c..3911aefce6 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AWSCore.Static STATIC @@ -61,7 +61,7 @@ ly_create_alias( if (PAL_TRAIT_BUILD_HOST_TOOLS) - include(${CMAKE_CURRENT_SOURCE_DIR}/Platform/${PAL_PLATFORM_NAME}/PAL_traits_editor_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + include(${pal_dir}/PAL_traits_editor_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) ly_add_target( NAME AWSCore.Editor.Static STATIC diff --git a/Gems/AWSCore/gem.json b/Gems/AWSCore/gem.json index 3bced07e8d..3bc8e6f77c 100644 --- a/Gems/AWSCore/gem.json +++ b/Gems/AWSCore/gem.json @@ -3,7 +3,8 @@ "display_name": "AWS Core", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", - "origin": "Amazon Web Services, Inc.", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The AWS Core Gem provides basic shared AWS functionality such as AWS SDK initialization and client configuration, and is automatically added when selecting any AWS feature Gem.", "canonical_tags": [ @@ -15,5 +16,8 @@ "SDK" ], "icon_path": "preview.png", - "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/aws/aws-core/" + "requirements": "", + "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/aws/aws-core/", + "dependencies": [ + ] } diff --git a/Gems/AWSGameLift/gem.json b/Gems/AWSGameLift/gem.json index 1ac65c4526..e1b80cb9fe 100644 --- a/Gems/AWSGameLift/gem.json +++ b/Gems/AWSGameLift/gem.json @@ -3,7 +3,8 @@ "display_name": "AWS GameLift", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", - "origin": "Amazon Web Services, Inc.", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The AWS GameLift Gem provides a framework to extend O3DE networking layer to work with GameLift resources via GameLift server and client SDK.", "canonical_tags": [ @@ -12,7 +13,7 @@ "user_tags": [ "AWS", "Framework", - "Network", + "Network", "SDK" ], "icon_path": "preview.png", diff --git a/Gems/AWSMetrics/gem.json b/Gems/AWSMetrics/gem.json index 054c3624c4..bd462edec3 100644 --- a/Gems/AWSMetrics/gem.json +++ b/Gems/AWSMetrics/gem.json @@ -3,7 +3,8 @@ "display_name": "AWS Metrics", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", - "origin": "Amazon Web Services, Inc.", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The AWS Metrics Gem provides a solution for AWS metrics submission and analytics.", "canonical_tags": [ @@ -15,6 +16,7 @@ "SDK" ], "icon_path": "preview.png", + "requirements": "", "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/aws/aws-metrics/", "dependencies": [ "AWSCore" diff --git a/Gems/Achievements/CMakeLists.txt b/Gems/Achievements/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Achievements/CMakeLists.txt +++ b/Gems/Achievements/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Achievements/Code/CMakeLists.txt b/Gems/Achievements/Code/CMakeLists.txt index 2d00ac2fb2..5ac43e9736 100644 --- a/Gems/Achievements/Code/CMakeLists.txt +++ b/Gems/Achievements/Code/CMakeLists.txt @@ -6,16 +6,16 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME Achievements.Static STATIC NAMESPACE Gem PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake + ${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake FILES_CMAKE achievements_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + ${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC Include diff --git a/Gems/Achievements/gem.json b/Gems/Achievements/gem.json index 8180584500..5fc83aefe2 100644 --- a/Gems/Achievements/gem.json +++ b/Gems/Achievements/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Achievements Gem provides a target platform agnostic interface for retrieving achievement details and unlocking achievements.", "canonical_tags": [ diff --git a/Gems/AssetValidation/gem.json b/Gems/AssetValidation/gem.json index 55cdffb9f3..de1d36ffb4 100644 --- a/Gems/AssetValidation/gem.json +++ b/Gems/AssetValidation/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Asset Validation Gem provides seed-related commands to ensure assets have valid seeds for asset bundling.", "canonical_tags": [ diff --git a/Gems/Atom/Asset/CMakeLists.txt b/Gems/Atom/Asset/CMakeLists.txt deleted file mode 100644 index 3ed20148a2..0000000000 --- a/Gems/Atom/Asset/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(ImageProcessingAtom) -add_subdirectory(Shader) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/CMakeLists.txt b/Gems/Atom/Asset/ImageProcessingAtom/CMakeLists.txt index 54543a000a..92079d35be 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/CMakeLists.txt +++ b/Gems/Atom/Asset/ImageProcessingAtom/CMakeLists.txt @@ -7,4 +7,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/CMakeLists.txt b/Gems/Atom/Asset/ImageProcessingAtom/Code/CMakeLists.txt index 982ec43715..74876994f6 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/CMakeLists.txt +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/CMakeLists.txt @@ -26,15 +26,15 @@ set(pal_tools_include_dirs) foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_tools_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform}) + o3de_pal_dir(pal_tools_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) list(APPEND pal_tools_include_dirs ${pal_tools_source_dir}) list(APPEND platform_tools_files ${pal_tools_source_dir}/pal_tools_${enabled_platform_lowercase}.cmake) list(APPEND pal_tools_include_files ${pal_tools_source_dir}/pal_tools_${enabled_platform_lowercase}_files.cmake) endforeach() -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME ImageProcessingAtom.Editor.Static STATIC diff --git a/Gems/Atom/Asset/ImageProcessingAtom/gem.json b/Gems/Atom/Asset/ImageProcessingAtom/gem.json index 4fd437d298..c2af4b7e7e 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/gem.json +++ b/Gems/Atom/Asset/ImageProcessingAtom/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI", "Atom_RHI", diff --git a/Gems/Atom/Asset/Shader/CMakeLists.txt b/Gems/Atom/Asset/Shader/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Asset/Shader/CMakeLists.txt +++ b/Gems/Atom/Asset/Shader/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Asset/Shader/Code/CMakeLists.txt b/Gems/Atom/Asset/Shader/Code/CMakeLists.txt index ed5aa45bbf..9ebd5e6d2d 100644 --- a/Gems/Atom/Asset/Shader/Code/CMakeLists.txt +++ b/Gems/Atom/Asset/Shader/Code/CMakeLists.txt @@ -10,8 +10,8 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) #for PAL_TRAIT_BUILD_ATOM_ASSET_SHADER_SUPPORTED @@ -71,7 +71,7 @@ ly_add_target( set(builder_tools_include_files) foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(builder_tools_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform}) + o3de_pal_dir(builder_tools_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) list(APPEND builder_tools_include_files ${builder_tools_source_dir}/platform_builders_${enabled_platform_lowercase}.cmake) endforeach() diff --git a/Gems/Atom/Asset/Shader/gem.json b/Gems/Atom/Asset/Shader/gem.json index 9f59c65f78..8b4ba4fb0d 100644 --- a/Gems/Atom/Asset/Shader/gem.json +++ b/Gems/Atom/Asset/Shader/gem.json @@ -4,13 +4,17 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Atom Shader Builder", "canonical_tags": [ "Gem" ], - "user_tags": [], + "user_tags": [ + "AtomShader" + ], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI", "Atom_RPI" diff --git a/Gems/Atom/Bootstrap/CMakeLists.txt b/Gems/Atom/Bootstrap/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Bootstrap/CMakeLists.txt +++ b/Gems/Atom/Bootstrap/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Bootstrap/Code/CMakeLists.txt b/Gems/Atom/Bootstrap/Code/CMakeLists.txt index fd9df96124..0ba8d17865 100644 --- a/Gems/Atom/Bootstrap/Code/CMakeLists.txt +++ b/Gems/Atom/Bootstrap/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME Atom_Bootstrap.Headers HEADERONLY diff --git a/Gems/Atom/Bootstrap/gem.json b/Gems/Atom/Bootstrap/gem.json index df615366da..543efe0f34 100644 --- a/Gems/Atom/Bootstrap/gem.json +++ b/Gems/Atom/Bootstrap/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI" ] diff --git a/Gems/Atom/CMakeLists.txt b/Gems/Atom/CMakeLists.txt index a71afa64e0..b5dd311e5a 100644 --- a/Gems/Atom/CMakeLists.txt +++ b/Gems/Atom/CMakeLists.txt @@ -6,12 +6,10 @@ # # -add_subdirectory(Asset) -add_subdirectory(Bootstrap) -add_subdirectory(Component) -add_subdirectory(Feature) -add_subdirectory(RHI) -add_subdirectory(RPI) +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Tools) add_subdirectory(Utils) diff --git a/Gems/Atom/Component/CMakeLists.txt b/Gems/Atom/Component/CMakeLists.txt deleted file mode 100644 index 8b867b8c67..0000000000 --- a/Gems/Atom/Component/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(DebugCamera) diff --git a/Gems/Atom/Component/DebugCamera/CMakeLists.txt b/Gems/Atom/Component/DebugCamera/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Component/DebugCamera/CMakeLists.txt +++ b/Gems/Atom/Component/DebugCamera/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Component/DebugCamera/gem.json b/Gems/Atom/Component/DebugCamera/gem.json index 8eab74f41d..74d88a21b6 100644 --- a/Gems/Atom/Component/DebugCamera/gem.json +++ b/Gems/Atom/Component/DebugCamera/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI" ] diff --git a/Gems/Atom/Feature/CMakeLists.txt b/Gems/Atom/Feature/CMakeLists.txt deleted file mode 100644 index 32d654d5c4..0000000000 --- a/Gems/Atom/Feature/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(Common) diff --git a/Gems/Atom/Feature/Common/CMakeLists.txt b/Gems/Atom/Feature/Common/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Feature/Common/CMakeLists.txt +++ b/Gems/Atom/Feature/Common/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Feature/Common/Code/CMakeLists.txt b/Gems/Atom/Feature/Common/Code/CMakeLists.txt index db9ac8560f..a832c46539 100644 --- a/Gems/Atom/Feature/Common/Code/CMakeLists.txt +++ b/Gems/Atom/Feature/Common/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME Atom_Feature_Common.Static STATIC diff --git a/Gems/Atom/Feature/Common/gem.json b/Gems/Atom/Feature/Common/gem.json index 84ab07a9f9..f4c936dc4a 100644 --- a/Gems/Atom/Feature/Common/gem.json +++ b/Gems/Atom/Feature/Common/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI", "Atom", diff --git a/Gems/Atom/RHI/CMakeLists.txt b/Gems/Atom/RHI/CMakeLists.txt index 074f6acfd7..5812828c1a 100644 --- a/Gems/Atom/RHI/CMakeLists.txt +++ b/Gems/Atom/RHI/CMakeLists.txt @@ -6,10 +6,10 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + ly_add_external_target_path(${CMAKE_CURRENT_LIST_DIR}/3rdParty) add_subdirectory(Code) -add_subdirectory(DX12) -add_subdirectory(Metal) -add_subdirectory(Vulkan) -add_subdirectory(Null) diff --git a/Gems/Atom/RHI/Code/CMakeLists.txt b/Gems/Atom/RHI/Code/CMakeLists.txt index 5238985feb..fe9db107a8 100644 --- a/Gems/Atom/RHI/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/AtomRHITests_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Gems/Atom/RHI/DX12/CMakeLists.txt b/Gems/Atom/RHI/DX12/CMakeLists.txt index 51912a5ff0..5812828c1a 100644 --- a/Gems/Atom/RHI/DX12/CMakeLists.txt +++ b/Gems/Atom/RHI/DX12/CMakeLists.txt @@ -6,6 +6,10 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + ly_add_external_target_path(${CMAKE_CURRENT_LIST_DIR}/3rdParty) add_subdirectory(Code) diff --git a/Gems/Atom/RHI/DX12/Code/CMakeLists.txt b/Gems/Atom/RHI/DX12/Code/CMakeLists.txt index 975b838ffa..95118c60a7 100644 --- a/Gems/Atom/RHI/DX12/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/DX12/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # PAL_TRAIT_ATOM_RHI_DX12_SUPPORTED @@ -23,7 +23,7 @@ set(pal_builder_tools_files) set(pal_builder_tools_includes) foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_builder_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform}) + o3de_pal_dir(pal_builder_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) list(APPEND pal_builder_tools_includes ${pal_builder_source_dir}) list(APPEND pal_builder_tools_files ${pal_builder_source_dir}/platform_builders_${enabled_platform_lowercase}_tools_files.cmake) endforeach() diff --git a/Gems/Atom/RHI/DX12/gem.json b/Gems/Atom/RHI/DX12/gem.json index 868acd43db..803ae4f4d0 100644 --- a/Gems/Atom/RHI/DX12/gem.json +++ b/Gems/Atom/RHI/DX12/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI" ] diff --git a/Gems/Atom/RHI/Metal/CMakeLists.txt b/Gems/Atom/RHI/Metal/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/RHI/Metal/CMakeLists.txt +++ b/Gems/Atom/RHI/Metal/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/RHI/Metal/Code/CMakeLists.txt b/Gems/Atom/RHI/Metal/Code/CMakeLists.txt index 11876e0a30..3df00a30e0 100644 --- a/Gems/Atom/RHI/Metal/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Metal/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL2_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Gems/Atom/RHI/Metal/gem.json b/Gems/Atom/RHI/Metal/gem.json index 6e983ba505..0257048bd3 100644 --- a/Gems/Atom/RHI/Metal/gem.json +++ b/Gems/Atom/RHI/Metal/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI" ] diff --git a/Gems/Atom/RHI/Null/CMakeLists.txt b/Gems/Atom/RHI/Null/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/RHI/Null/CMakeLists.txt +++ b/Gems/Atom/RHI/Null/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/RHI/Null/Code/CMakeLists.txt b/Gems/Atom/RHI/Null/Code/CMakeLists.txt index 71df9f696f..081edd4c44 100644 --- a/Gems/Atom/RHI/Null/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Null/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( diff --git a/Gems/Atom/RHI/Null/gem.json b/Gems/Atom/RHI/Null/gem.json index e9f22c5fcb..1ea2eb4cb0 100644 --- a/Gems/Atom/RHI/Null/gem.json +++ b/Gems/Atom/RHI/Null/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI" ] diff --git a/Gems/Atom/RHI/Vulkan/CMakeLists.txt b/Gems/Atom/RHI/Vulkan/CMakeLists.txt index 51912a5ff0..5812828c1a 100644 --- a/Gems/Atom/RHI/Vulkan/CMakeLists.txt +++ b/Gems/Atom/RHI/Vulkan/CMakeLists.txt @@ -6,6 +6,10 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + ly_add_external_target_path(${CMAKE_CURRENT_LIST_DIR}/3rdParty) add_subdirectory(Code) diff --git a/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt b/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt index fb13d1fddb..674e5aff9e 100644 --- a/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # PAL_TRAIT_ATOM_RHI_VULKAN_SUPPORTED / PAL_TRAIT_ATOM_RHI_VULKAN_TARGETS_ALREADY_DEFINED diff --git a/Gems/Atom/RHI/Vulkan/gem.json b/Gems/Atom/RHI/Vulkan/gem.json index 1dfeb9eafa..508ad85c75 100644 --- a/Gems/Atom/RHI/Vulkan/gem.json +++ b/Gems/Atom/RHI/Vulkan/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI" ] diff --git a/Gems/Atom/RHI/gem.json b/Gems/Atom/RHI/gem.json index de46c312ad..858a64fc17 100644 --- a/Gems/Atom/RHI/gem.json +++ b/Gems/Atom/RHI/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,12 @@ ], "user_tags": [], "requirements": "", + "external_subdirectories": [ + "DX12", + "Metal", + "Null", + "Vulkan" + ], "dependencies": [ "Atom_RHI_DX12", "Atom_RHI_Metal", diff --git a/Gems/Atom/RPI/CMakeLists.txt b/Gems/Atom/RPI/CMakeLists.txt index 6d148328ec..2c2cee5804 100644 --- a/Gems/Atom/RPI/CMakeLists.txt +++ b/Gems/Atom/RPI/CMakeLists.txt @@ -6,6 +6,10 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) add_subdirectory(Tools) diff --git a/Gems/Atom/RPI/Code/CMakeLists.txt b/Gems/Atom/RPI/Code/CMakeLists.txt index f0459a23c2..dcdad13c10 100644 --- a/Gems/Atom/RPI/Code/CMakeLists.txt +++ b/Gems/Atom/RPI/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) #for PAL_TRAIT_BUILD_ATOM_RPI_ASSETS_SUPPORTED and PAL_TRAIT_BUILD_ATOM_RPI_MASKED_OCCLUSION_CULLING_SUPPORTED include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) @@ -176,8 +176,8 @@ endif() if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) - ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) + o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) + set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) if(NOT PAL_TRAIT_BUILD_ATOM_RPI_ASSETS_SUPPORTED) diff --git a/Gems/Atom/RPI/gem.json b/Gems/Atom/RPI/gem.json index 885f150508..0acef5179b 100644 --- a/Gems/Atom/RPI/gem.json +++ b/Gems/Atom/RPI/gem.json @@ -1,16 +1,18 @@ { "gem_name": "Atom_RPI", "display_name": "Atom API", - "summary": "", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", + "summary": "", "canonical_tags": [ "Gem" ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI" ] diff --git a/Gems/Atom/Tools/AtomToolsFramework/CMakeLists.txt b/Gems/Atom/Tools/AtomToolsFramework/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/CMakeLists.txt +++ b/Gems/Atom/Tools/AtomToolsFramework/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/CMakeLists.txt b/Gems/Atom/Tools/AtomToolsFramework/Code/CMakeLists.txt index e7e8208722..0fc896e88a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/CMakeLists.txt +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/CMakeLists.txt @@ -10,7 +10,7 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AtomToolsFramework.Static STATIC diff --git a/Gems/Atom/Tools/AtomToolsFramework/gem.json b/Gems/Atom/Tools/AtomToolsFramework/gem.json index de2a9e06f2..6e5a7b311a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/gem.json +++ b/Gems/Atom/Tools/AtomToolsFramework/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI", "Atom_RHI", diff --git a/Gems/Atom/Tools/CMakeLists.txt b/Gems/Atom/Tools/CMakeLists.txt index 653babd0b3..82a803bdef 100644 --- a/Gems/Atom/Tools/CMakeLists.txt +++ b/Gems/Atom/Tools/CMakeLists.txt @@ -6,6 +6,4 @@ # # -add_subdirectory(AtomToolsFramework) -add_subdirectory(MaterialEditor) add_subdirectory(ShaderManagementConsole) diff --git a/Gems/Atom/Tools/MaterialEditor/CMakeLists.txt b/Gems/Atom/Tools/MaterialEditor/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Atom/Tools/MaterialEditor/CMakeLists.txt +++ b/Gems/Atom/Tools/MaterialEditor/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt b/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt index 99beb721d6..1d9295f9b3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt +++ b/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt @@ -10,7 +10,7 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # PAL_TRAIT_ATOM_MATERIAL_EDITOR_APPLICATION_SUPPORTED diff --git a/Gems/Atom/Tools/MaterialEditor/gem.json b/Gems/Atom/Tools/MaterialEditor/gem.json index 807e3fa65f..463553c27d 100644 --- a/Gems/Atom/Tools/MaterialEditor/gem.json +++ b/Gems/Atom/Tools/MaterialEditor/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "Editor for creating, modifying, and previewing materials", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "AtomToolsFramework", "Atom_RPI", diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt b/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt index d384378b09..3f7788418a 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt @@ -10,7 +10,7 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # PAL_TRAIT_ATOM_SHADER_MANAGEMENT_CONSOLE_APPLICATION_SUPPORTED diff --git a/Gems/Atom/Utils/Code/CMakeLists.txt b/Gems/Atom/Utils/Code/CMakeLists.txt index 90d7ce501b..a657262f2d 100644 --- a/Gems/Atom/Utils/Code/CMakeLists.txt +++ b/Gems/Atom/Utils/Code/CMakeLists.txt @@ -6,8 +6,6 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - ly_add_target( NAME Atom_Utils.Static STATIC NAMESPACE Gem @@ -52,6 +50,9 @@ endif() # Tests ################################################################################ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + + o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) + ly_add_target( NAME Atom_Utils.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE Gem diff --git a/Gems/Atom/gem.json b/Gems/Atom/gem.json index 0f409ad993..ee6a617ee7 100644 --- a/Gems/Atom/gem.json +++ b/Gems/Atom/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Atom Renderer Gem provides Atom Renderer and its associated tools (such as Material Editor), utilites, libraries, and interfaces.", "canonical_tags": [ @@ -15,6 +16,17 @@ ], "requirements": "", "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/rendering/atom/atom/", + "external_subdirectories": [ + "Asset/ImageProcessingAtom", + "Asset/Shader", + "Bootstrap", + "Component/DebugCamera", + "Feature/Common", + "RHI", + "RPI", + "Tools/AtomToolsFramework", + "Tools/MaterialEditor" + ], "dependencies": [ "Atom_Feature_Common", "AtomShader", diff --git a/Gems/AtomContent/CMakeLists.txt b/Gems/AtomContent/CMakeLists.txt index ee06f07bc3..29477608b9 100644 --- a/Gems/AtomContent/CMakeLists.txt +++ b/Gems/AtomContent/CMakeLists.txt @@ -5,8 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT # # -add_subdirectory(ReferenceMaterials) -add_subdirectory(Sponza) if(PAL_TRAIT_BUILD_HOST_TOOLS) ly_create_alias(NAME AtomContent.Builders NAMESPACE Gem TARGETS Gem::AtomContent_ReferenceMaterials.Builders Gem::AtomContent_Sponza.Builders) diff --git a/Gems/AtomContent/ReferenceMaterials/gem.json b/Gems/AtomContent/ReferenceMaterials/gem.json index b75b01e1ae..49a488b9d3 100644 --- a/Gems/AtomContent/ReferenceMaterials/gem.json +++ b/Gems/AtomContent/ReferenceMaterials/gem.json @@ -2,7 +2,9 @@ "gem_name": "ReferenceMaterials", "display_name": "PBR Reference Materials", "license": "Code, text, data files: Apache-2.0 Or MIT, assets/content/images: CC BY 4.0", - "origin": "https://github.com/aws-lumberyard-dev/o3de.git", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "Atom Asset Gem with a library of reference materials for StandardPBR (and others in the future)", "canonical_tags": [ @@ -14,6 +16,8 @@ "Materials" ], "icon_path": "preview.png", - "dependencies": [], - "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt" + "requirements": "", + "documentation_url": "", + "dependencies": [ + ] } diff --git a/Gems/AtomContent/Sponza/gem.json b/Gems/AtomContent/Sponza/gem.json index 68749cd5f4..f15d57a4d1 100644 --- a/Gems/AtomContent/Sponza/gem.json +++ b/Gems/AtomContent/Sponza/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "A standard test scene for Global Illumination (forked from crytek sponza scene)", "canonical_tags": [ @@ -13,5 +14,7 @@ "Assets" ], "requirements": "", - "dependencies": [] + "documentation_url": "", + "dependencies": [ + ] } diff --git a/Gems/AtomContent/gem.json b/Gems/AtomContent/gem.json index 400e897a3b..9be15f7da8 100644 --- a/Gems/AtomContent/gem.json +++ b/Gems/AtomContent/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The Atom Content Gem provides assets for Atom Renderer and a modified version of the Pixar Look Development Studio.", "canonical_tags": [ @@ -17,7 +18,11 @@ "requirements": "", "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/rendering/atom/atom-content/", "dependencies": [ - "ReferenceMaterials", - "Sponza" + "Sponza", + "ReferenceMaterials" + ], + "external_subdirectories": [ + "Sponza", + "ReferenceMaterials" ] } diff --git a/Gems/AtomLyIntegration/AtomBridge/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AtomLyIntegration/AtomBridge/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index 67f28767e0..fa3669d7c2 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME Atom_AtomBridge.Static STATIC diff --git a/Gems/AtomLyIntegration/AtomBridge/gem.json b/Gems/AtomLyIntegration/AtomBridge/gem.json index e8ca413023..5a8512c90d 100644 --- a/Gems/AtomLyIntegration/AtomBridge/gem.json +++ b/Gems/AtomLyIntegration/AtomBridge/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI", "Atom_Bootstrap", diff --git a/Gems/AtomLyIntegration/AtomFont/CMakeLists.txt b/Gems/AtomLyIntegration/AtomFont/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AtomLyIntegration/AtomFont/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomFont/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt index 6567736f02..79d97e797d 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomFont/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AtomFont ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} diff --git a/Gems/AtomLyIntegration/AtomFont/gem.json b/Gems/AtomLyIntegration/AtomFont/gem.json index 8907ec0979..d979509059 100644 --- a/Gems/AtomLyIntegration/AtomFont/gem.json +++ b/Gems/AtomLyIntegration/AtomFont/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI", "Atom_RPI", diff --git a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json index e188ba0cb8..205120f6f0 100644 --- a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json +++ b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "", "canonical_tags": [ @@ -14,6 +15,7 @@ "Rendering" ], "requirements": "", + "documentation_url": "", "dependencies": [ "ImguiAtom", "Atom" diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json index 5a0763e0da..cff957c1f1 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json +++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI", "Atom_RPI", diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json index 639d93d301..a2bc92c76d 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RHI", "Atom_RPI" diff --git a/Gems/AtomLyIntegration/CMakeLists.txt b/Gems/AtomLyIntegration/CMakeLists.txt index 4ab976d68f..25d7356b01 100644 --- a/Gems/AtomLyIntegration/CMakeLists.txt +++ b/Gems/AtomLyIntegration/CMakeLists.txt @@ -6,13 +6,4 @@ # # -add_subdirectory(CommonFeatures) -add_subdirectory(ImguiAtom) -add_subdirectory(AtomImGuiTools) -add_subdirectory(EMotionFXAtom) -add_subdirectory(AtomFont) -add_subdirectory(TechnicalArt) -add_subdirectory(AtomBridge) -add_subdirectory(AtomViewportDisplayInfo) -add_subdirectory(AtomViewportDisplayIcons) diff --git a/Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt b/Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt +++ b/Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt b/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt index 7b685ece13..3234db2292 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME AtomLyIntegration_CommonFeatures.Public HEADERONLY diff --git a/Gems/AtomLyIntegration/CommonFeatures/gem.json b/Gems/AtomLyIntegration/CommonFeatures/gem.json index 6fa8938332..a06f607fab 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/gem.json +++ b/Gems/AtomLyIntegration/CommonFeatures/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_Feature_Common", "LmbrCentral", diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json index 3514d4c1b9..8bea93da91 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json +++ b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "EMotionFX", "Atom", diff --git a/Gems/AtomLyIntegration/ImguiAtom/gem.json b/Gems/AtomLyIntegration/ImguiAtom/gem.json index fa611d8224..4c65d80e33 100644 --- a/Gems/AtomLyIntegration/ImguiAtom/gem.json +++ b/Gems/AtomLyIntegration/ImguiAtom/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "", "canonical_tags": [ @@ -11,6 +12,7 @@ ], "user_tags": [], "requirements": "", + "documentation_url": "", "dependencies": [ "ImGui", "Atom_Feature_Common" diff --git a/Gems/AtomLyIntegration/TechnicalArt/CMakeLists.txt b/Gems/AtomLyIntegration/TechnicalArt/CMakeLists.txt deleted file mode 100644 index 4fc1e5241d..0000000000 --- a/Gems/AtomLyIntegration/TechnicalArt/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(DccScriptingInterface) diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/CMakeLists.txt b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/CMakeLists.txt index 5780172755..f26d18b90e 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/CMakeLists.txt +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/CMakeLists.txt @@ -6,5 +6,4 @@ # # -add_subdirectory(Code) update_pip_requirements(${CMAKE_CURRENT_LIST_DIR}/requirements.txt DccScriptingInterface) diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json index 4cc6fff169..7786a8adf4 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json @@ -1,11 +1,12 @@ { "gem_name": "DccScriptingInterface", "display_name": "Atom DccScriptingInterface (DCCsi)", - "summary": "A python framework for working with various DCC tools and workflows.", "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", + "summary": "A python framework for working with various DCC tools and workflows.", "canonical_tags": [ "Gem" ], @@ -16,5 +17,6 @@ "Creation" ], "requirements": "", + "documentation_url": "", "dependencies": [] } diff --git a/Gems/AtomLyIntegration/gem.json b/Gems/AtomLyIntegration/gem.json index d9e526aee0..c491126269 100644 --- a/Gems/AtomLyIntegration/gem.json +++ b/Gems/AtomLyIntegration/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Atom O3DE Integration Gem provides components, libraries, and functionality to support and integrate Atom Renderer in Open 3D Engine.", "canonical_tags": [ @@ -25,5 +26,16 @@ "CommonFeaturesAtom", "EMotionFX_Atom", "ImguiAtom" + ], + "external_subdirectories": [ + "AtomBridge", + "AtomFont", + "AtomImGuiTools", + "AtomViewportDisplayIcons", + "AtomViewportDisplayInfo", + "CommonFeatures", + "EMotionFXAtom", + "ImguiAtom", + "TechnicalArt/DccScriptingInterface" ] } diff --git a/Gems/AtomTressFX/gem.json b/Gems/AtomTressFX/gem.json index b7588ea374..1bd619a418 100644 --- a/Gems/AtomTressFX/gem.json +++ b/Gems/AtomTressFX/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "Atom TressFX Gem provides a cutting edge hair and fur simulation and rendering in Atom enhancing the AMD TressFX 4.1. The open source TressFX can be found here: https://github.com/GPUOpen-Effects/TressFX", "canonical_tags": [ @@ -15,5 +16,7 @@ "Animation" ], "requirements": "", - "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/rendering/amd/atom-tressfx/" + "documentation_url": "https://o3de.org/docs/user-guide/gems/reference/rendering/amd/atom-tressfx/", + "dependencies": [ + ] } diff --git a/Gems/AudioEngineWwise/CMakeLists.txt b/Gems/AudioEngineWwise/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AudioEngineWwise/CMakeLists.txt +++ b/Gems/AudioEngineWwise/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AudioEngineWwise/Code/CMakeLists.txt b/Gems/AudioEngineWwise/Code/CMakeLists.txt index 33c80bc31c..02d4f1e6c8 100644 --- a/Gems/AudioEngineWwise/Code/CMakeLists.txt +++ b/Gems/AudioEngineWwise/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) #for PAL_TRAIT_AUDIO_ENGINE_WWISE Traits diff --git a/Gems/AudioEngineWwise/gem.json b/Gems/AudioEngineWwise/gem.json index 2b0af30d40..f0d8c73be2 100644 --- a/Gems/AudioEngineWwise/gem.json +++ b/Gems/AudioEngineWwise/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Wwise Audio Engine Gem provides support for Audiokinetic Wave Works Interactive Sound Engine (Wwise).", "canonical_tags": [ diff --git a/Gems/AudioSystem/CMakeLists.txt b/Gems/AudioSystem/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/AudioSystem/CMakeLists.txt +++ b/Gems/AudioSystem/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/AudioSystem/Code/CMakeLists.txt b/Gems/AudioSystem/Code/CMakeLists.txt index 17dbd91878..e5778e9152 100644 --- a/Gems/AudioSystem/Code/CMakeLists.txt +++ b/Gems/AudioSystem/Code/CMakeLists.txt @@ -10,7 +10,7 @@ set(AUDIOSYSTEM_COMPILEDEFINITIONS $,AUDIO_RELEASE,ENABLE_AUDIO_LOGGING> ) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME AudioSystem.Static STATIC @@ -65,7 +65,7 @@ ly_create_alias(NAME AudioSystem.Clients NAMESPACE Gem TARGETS Gem::AudioSystem # Tests ################################################################################ if (PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) + set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) ly_add_target( NAME AudioSystem.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE Gem diff --git a/Gems/AudioSystem/gem.json b/Gems/AudioSystem/gem.json index ed028068a1..be618ee44e 100644 --- a/Gems/AudioSystem/gem.json +++ b/Gems/AudioSystem/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Audio System Gem provides the Audio Translation Layer (ATL) and Audio Controls Editor, which add support for audio in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/BarrierInput/gem.json b/Gems/BarrierInput/gem.json index 72d6398550..e8dcf0d93c 100644 --- a/Gems/BarrierInput/gem.json +++ b/Gems/BarrierInput/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Barrier Input Gem allows the Open 3D Engine to function as a Barrier client so that it can receive input from a remote Barrier server.", "canonical_tags": [ @@ -16,6 +17,7 @@ ], "icon_path": "preview.png", "requirements": "", + "documentation_url": "", "dependencies": [ "Atom_RPI" ] diff --git a/Gems/Blast/CMakeLists.txt b/Gems/Blast/CMakeLists.txt index 7c478ef2b2..e2fe57d8cc 100644 --- a/Gems/Blast/CMakeLists.txt +++ b/Gems/Blast/CMakeLists.txt @@ -6,5 +6,9 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Blast/Code/CMakeLists.txt b/Gems/Blast/Code/CMakeLists.txt index d3555b2855..7f478054b8 100644 --- a/Gems/Blast/Code/CMakeLists.txt +++ b/Gems/Blast/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_BLAST Traits diff --git a/Gems/Blast/gem.json b/Gems/Blast/gem.json index 761eb04761..dc90c587d7 100644 --- a/Gems/Blast/gem.json +++ b/Gems/Blast/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The NVIDIA Blast Gem provides tools to author fractured mesh assets in Houdini, and functionality to create realistic destruction simulations in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/Camera/gem.json b/Gems/Camera/gem.json index 4cf0747c7b..c6367d4663 100644 --- a/Gems/Camera/gem.json +++ b/Gems/Camera/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Camera Gem provides a basic camera component that defines a frustum for runtime rendering.", "canonical_tags": [ diff --git a/Gems/CameraFramework/gem.json b/Gems/CameraFramework/gem.json index d24014be61..0803fd7522 100644 --- a/Gems/CameraFramework/gem.json +++ b/Gems/CameraFramework/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Camera Framework Gem provides a base for implementing more complex camera systems.", "canonical_tags": [ diff --git a/Gems/CertificateManager/gem.json b/Gems/CertificateManager/gem.json index 11ea14ea5e..c582e932be 100644 --- a/Gems/CertificateManager/gem.json +++ b/Gems/CertificateManager/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Certificate Manager Gem provides access to authentication files for secure game connections from Amazon S3, files on disk, and other 3rd party sources.", "canonical_tags": [ diff --git a/Gems/CrashReporting/CMakeLists.txt b/Gems/CrashReporting/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/CrashReporting/CMakeLists.txt +++ b/Gems/CrashReporting/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/CrashReporting/Code/CMakeLists.txt b/Gems/CrashReporting/Code/CMakeLists.txt index 8bcb143d1c..7d7b2c76da 100644 --- a/Gems/CrashReporting/Code/CMakeLists.txt +++ b/Gems/CrashReporting/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Gems/CrashReporting/gem.json b/Gems/CrashReporting/gem.json index b8c75548a4..1651bad7b8 100644 --- a/Gems/CrashReporting/gem.json +++ b/Gems/CrashReporting/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Crash Reporting Gem provides support for external crash reporting for Open 3D Engine projects.", "canonical_tags": [ diff --git a/Gems/CustomAssetExample/gem.json b/Gems/CustomAssetExample/gem.json index 89492ee6ea..ba1030b280 100644 --- a/Gems/CustomAssetExample/gem.json +++ b/Gems/CustomAssetExample/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Custom Asset Example Gem provides example code for creating a custom asset for Open 3D Engine's asset pipeline.", "canonical_tags": [ diff --git a/Gems/DebugDraw/gem.json b/Gems/DebugDraw/gem.json index 58eff5f87a..e140d642b8 100644 --- a/Gems/DebugDraw/gem.json +++ b/Gems/DebugDraw/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Debug Draw Gem provides Editor and runtime debug visualization features for Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/DevTextures/gem.json b/Gems/DevTextures/gem.json index 00cafbd6fb..f8c436887d 100644 --- a/Gems/DevTextures/gem.json +++ b/Gems/DevTextures/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The Dev Textures Gem provides a collection of general purpose texture assets useful for prototypes and preproduction.", "canonical_tags": [ diff --git a/Gems/EMotionFX/CMakeLists.txt b/Gems/EMotionFX/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/EMotionFX/CMakeLists.txt +++ b/Gems/EMotionFX/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/EMotionFX/Code/CMakeLists.txt b/Gems/EMotionFX/Code/CMakeLists.txt index 67d0ba6d85..bd90e589c9 100644 --- a/Gems/EMotionFX/Code/CMakeLists.txt +++ b/Gems/EMotionFX/Code/CMakeLists.txt @@ -6,10 +6,9 @@ # # -ly_get_list_relative_pal_filename(core_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - -ly_get_list_relative_pal_filename(editor_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Editor/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(editor_common_dir ${CMAKE_CURRENT_LIST_DIR}/Editor/Platform/Common) +o3de_pal_dir(core_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +o3de_pal_dir(editor_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Editor/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(editor_common_dir ${CMAKE_CURRENT_LIST_DIR}/Editor/Platform/Common) ly_add_target( NAME EMotionFXStaticLib STATIC diff --git a/Gems/EMotionFX/gem.json b/Gems/EMotionFX/gem.json index ed80517af1..c07c8368c2 100644 --- a/Gems/EMotionFX/gem.json +++ b/Gems/EMotionFX/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The EMotion FX Animation Gem provides Open 3D Engine's animation system for rigged actors and includes Animation Editor, a tool for creating animated behaviors, simulated objects, and colliders for rigged actors.", "canonical_tags": [ diff --git a/Gems/EditorPythonBindings/gem.json b/Gems/EditorPythonBindings/gem.json index 475483f13b..a5ee9f5631 100644 --- a/Gems/EditorPythonBindings/gem.json +++ b/Gems/EditorPythonBindings/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Editor Python Bindings Gem provides Python commands for Open 3D Engine Editor functions.", "canonical_tags": [ diff --git a/Gems/ExpressionEvaluation/gem.json b/Gems/ExpressionEvaluation/gem.json index cd712f4da9..667eebbcb5 100644 --- a/Gems/ExpressionEvaluation/gem.json +++ b/Gems/ExpressionEvaluation/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Expression Evaluation Gem provides a method for parsing and executing string expressions in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/FastNoise/gem.json b/Gems/FastNoise/gem.json index d8dfb878b4..a9c0f1f42d 100644 --- a/Gems/FastNoise/gem.json +++ b/Gems/FastNoise/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The FastNoise Gradient Gem uses the third-party, open source FastNoise library to provide a variety of high-performance noise generation algorithms.", "canonical_tags": [ diff --git a/Gems/GameState/gem.json b/Gems/GameState/gem.json index fe3a338997..d3e2d76c5a 100644 --- a/Gems/GameState/gem.json +++ b/Gems/GameState/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Game State Gem provides a generic framework to determine and manage game states and game state transitions in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/GameStateSamples/CMakeLists.txt b/Gems/GameStateSamples/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/GameStateSamples/CMakeLists.txt +++ b/Gems/GameStateSamples/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/GameStateSamples/Code/CMakeLists.txt b/Gems/GameStateSamples/Code/CMakeLists.txt index a07bef6a06..939b2ce1bd 100644 --- a/Gems/GameStateSamples/Code/CMakeLists.txt +++ b/Gems/GameStateSamples/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(include_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(include_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME GameStateSamples.Headers HEADERONLY diff --git a/Gems/GameStateSamples/gem.json b/Gems/GameStateSamples/gem.json index 80018ff1a8..94556ee677 100644 --- a/Gems/GameStateSamples/gem.json +++ b/Gems/GameStateSamples/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Game State Samples Gem provides a set of sample game states (built on top of the Game State Gem), including primary user selection, main menu, level loading, level running, and level paused.", "canonical_tags": [ diff --git a/Gems/Gestures/gem.json b/Gems/Gestures/gem.json index 8efd389d53..c0609c8d54 100644 --- a/Gems/Gestures/gem.json +++ b/Gems/Gestures/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Gestures Gem provides detection for common gesture-based input actions on iOS and Android devices.", "canonical_tags": [ diff --git a/Gems/GradientSignal/gem.json b/Gems/GradientSignal/gem.json index aac4c652c5..f0136ef104 100644 --- a/Gems/GradientSignal/gem.json +++ b/Gems/GradientSignal/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Gradient Signal Gem provides a number of components for generating, modifying, and mixing gradient signals.", "canonical_tags": [ diff --git a/Gems/GraphCanvas/gem.json b/Gems/GraphCanvas/gem.json index 4762cfef35..c2038f4645 100644 --- a/Gems/GraphCanvas/gem.json +++ b/Gems/GraphCanvas/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Graph Canvas Gem provides a C++ framework for creating custom graphical node based editors for Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/GraphModel/gem.json b/Gems/GraphModel/gem.json index ad6b592430..ece520278b 100644 --- a/Gems/GraphModel/gem.json +++ b/Gems/GraphModel/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Graph Model Gem provides a generic node graph data model framework for Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/HttpRequestor/CMakeLists.txt b/Gems/HttpRequestor/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/HttpRequestor/CMakeLists.txt +++ b/Gems/HttpRequestor/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/HttpRequestor/Code/CMakeLists.txt b/Gems/HttpRequestor/Code/CMakeLists.txt index 831eb52231..4ebca5518c 100644 --- a/Gems/HttpRequestor/Code/CMakeLists.txt +++ b/Gems/HttpRequestor/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(source_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(source_pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME HttpRequestor.Static STATIC diff --git a/Gems/HttpRequestor/gem.json b/Gems/HttpRequestor/gem.json index 582bfa0071..a8e111ac63 100644 --- a/Gems/HttpRequestor/gem.json +++ b/Gems/HttpRequestor/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The HTTP Requestor Gem provides functionality to make asynchronous HTTP/HTTPS requests and return data through a user-provided call back function.", "canonical_tags": [ diff --git a/Gems/ImGui/CMakeLists.txt b/Gems/ImGui/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/ImGui/CMakeLists.txt +++ b/Gems/ImGui/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/ImGui/Code/CMakeLists.txt b/Gems/ImGui/Code/CMakeLists.txt index e345e3d546..c293065636 100644 --- a/Gems/ImGui/Code/CMakeLists.txt +++ b/Gems/ImGui/Code/CMakeLists.txt @@ -8,7 +8,7 @@ set(config_base_defines $,IMGUI_DISABLED,IMGUI_ENABLED>) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) # This library is the 3rdParty imgui that is in the Gem's External ly_add_target( diff --git a/Gems/ImGui/gem.json b/Gems/ImGui/gem.json index dfc12f64b4..0ed889f693 100644 --- a/Gems/ImGui/gem.json +++ b/Gems/ImGui/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Immediate Mode GUI Gem provides the 3rdParty library IMGUI which can be used to create run time immediate mode overlays for debugging and profiling information in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/InAppPurchases/CMakeLists.txt b/Gems/InAppPurchases/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/InAppPurchases/CMakeLists.txt +++ b/Gems/InAppPurchases/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/InAppPurchases/Code/CMakeLists.txt b/Gems/InAppPurchases/Code/CMakeLists.txt index 99fc937919..e7b34296d1 100644 --- a/Gems/InAppPurchases/Code/CMakeLists.txt +++ b/Gems/InAppPurchases/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME InAppPurchases.Static STATIC diff --git a/Gems/InAppPurchases/gem.json b/Gems/InAppPurchases/gem.json index 21febbfeca..0b3d2e65e4 100644 --- a/Gems/InAppPurchases/gem.json +++ b/Gems/InAppPurchases/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The In-App Purchases Gem provides functionality for in app purchases for iOS and Android.", "canonical_tags": [ diff --git a/Gems/LandscapeCanvas/gem.json b/Gems/LandscapeCanvas/gem.json index 8653da40e1..f1e326efce 100644 --- a/Gems/LandscapeCanvas/gem.json +++ b/Gems/LandscapeCanvas/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Landscape Canvas Gem provides the Landscape Canvas editor, a node-based graph tool for authoring workflows to populate landscape with dynamic vegetation.", "canonical_tags": [ diff --git a/Gems/LmbrCentral/CMakeLists.txt b/Gems/LmbrCentral/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/LmbrCentral/CMakeLists.txt +++ b/Gems/LmbrCentral/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/LmbrCentral/Code/CMakeLists.txt b/Gems/LmbrCentral/Code/CMakeLists.txt index 4401d3b752..a4c94a7b40 100644 --- a/Gems/LmbrCentral/Code/CMakeLists.txt +++ b/Gems/LmbrCentral/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) ly_add_target( NAME LmbrCentral.Static STATIC diff --git a/Gems/LmbrCentral/gem.json b/Gems/LmbrCentral/gem.json index a0a6ea813f..4eea28d26e 100644 --- a/Gems/LmbrCentral/gem.json +++ b/Gems/LmbrCentral/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The O3DE Core (LmbrCentral) Gem provides required code and assets for running Open 3D Engine Editor.", "canonical_tags": [ diff --git a/Gems/LocalUser/CMakeLists.txt b/Gems/LocalUser/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/LocalUser/CMakeLists.txt +++ b/Gems/LocalUser/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/LocalUser/Code/CMakeLists.txt b/Gems/LocalUser/Code/CMakeLists.txt index 055cfe6c7c..ce937e9dc5 100644 --- a/Gems/LocalUser/Code/CMakeLists.txt +++ b/Gems/LocalUser/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME LocalUser.Static STATIC diff --git a/Gems/LocalUser/gem.json b/Gems/LocalUser/gem.json index 5199b4f777..04f2145956 100644 --- a/Gems/LocalUser/gem.json +++ b/Gems/LocalUser/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Local User Gem provides functionality for mapping local user ids to local player slots and managing local user profiles.", "canonical_tags": [ diff --git a/Gems/LyShine/CMakeLists.txt b/Gems/LyShine/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/LyShine/CMakeLists.txt +++ b/Gems/LyShine/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 2b550b0e36..76d7742ddf 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME LyShine.Static STATIC diff --git a/Gems/LyShine/gem.json b/Gems/LyShine/gem.json index 8dcac6404a..7ebb733b0f 100644 --- a/Gems/LyShine/gem.json +++ b/Gems/LyShine/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The LyShine Gem provides the runtime UI system and creation tools for Open 3D Engine projects.", "canonical_tags": [ diff --git a/Gems/LyShineExamples/gem.json b/Gems/LyShineExamples/gem.json index 74d2b6fe51..c91e9b819e 100644 --- a/Gems/LyShineExamples/gem.json +++ b/Gems/LyShineExamples/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The LyShine Examples Gem provides example code and assets for LyShine, the runtime UI system and editor for Open 3D Engine projects.", "canonical_tags": [ diff --git a/Gems/Maestro/gem.json b/Gems/Maestro/gem.json index d8f884e271..95aa43c179 100644 --- a/Gems/Maestro/gem.json +++ b/Gems/Maestro/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Maestro Cinematics Gem provides Track View, Open 3D Engine's animated sequence and cinematics editor.", "canonical_tags": [ diff --git a/Gems/MessagePopup/gem.json b/Gems/MessagePopup/gem.json index fb44dd93a5..5e1b4843b0 100644 --- a/Gems/MessagePopup/gem.json +++ b/Gems/MessagePopup/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Message Popup Gem provides an example implementation of popup messages using LyShine in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/Metastream/CMakeLists.txt b/Gems/Metastream/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Metastream/CMakeLists.txt +++ b/Gems/Metastream/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Metastream/Code/CMakeLists.txt b/Gems/Metastream/Code/CMakeLists.txt index a032fc34ff..f1652058ac 100644 --- a/Gems/Metastream/Code/CMakeLists.txt +++ b/Gems/Metastream/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME Metastream.Static STATIC diff --git a/Gems/Metastream/gem.json b/Gems/Metastream/gem.json index 309f16b221..9a37a0a8ee 100644 --- a/Gems/Metastream/gem.json +++ b/Gems/Metastream/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Metastream Gem provides functionality for an HTTP server that allows broadcasters to customize game streams with overlays of statistics and event data from a game session.", "canonical_tags": [ diff --git a/Gems/Microphone/CMakeLists.txt b/Gems/Microphone/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Microphone/CMakeLists.txt +++ b/Gems/Microphone/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Microphone/Code/CMakeLists.txt b/Gems/Microphone/Code/CMakeLists.txt index 5b40521f6a..873d05e98d 100644 --- a/Gems/Microphone/Code/CMakeLists.txt +++ b/Gems/Microphone/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME Microphone.Static STATIC diff --git a/Gems/Microphone/gem.json b/Gems/Microphone/gem.json index 6e57bec854..6a5b415a22 100644 --- a/Gems/Microphone/gem.json +++ b/Gems/Microphone/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Microphone Gem provides support for audio input through microphones.", "canonical_tags": [ diff --git a/Gems/Multiplayer/CMakeLists.txt b/Gems/Multiplayer/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Multiplayer/CMakeLists.txt +++ b/Gems/Multiplayer/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Multiplayer/Code/CMakeLists.txt b/Gems/Multiplayer/Code/CMakeLists.txt index afe40408ab..66085476e5 100644 --- a/Gems/Multiplayer/Code/CMakeLists.txt +++ b/Gems/Multiplayer/Code/CMakeLists.txt @@ -6,6 +6,8 @@ # # +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) + ly_add_target( NAME Multiplayer.Static STATIC NAMESPACE Gem diff --git a/Gems/Multiplayer/gem.json b/Gems/Multiplayer/gem.json index f895c78c5d..2b412084af 100644 --- a/Gems/Multiplayer/gem.json +++ b/Gems/Multiplayer/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Multiplayer Gem provides a public API for multiplayer functionality such as connecting and hosting.", "canonical_tags": [ @@ -16,6 +17,7 @@ ], "icon_path": "preview.png", "requirements": "", + "documentation_url": "", "dependencies": [ "CertificateManager", "Atom_Feature_Common", diff --git a/Gems/MultiplayerCompression/gem.json b/Gems/MultiplayerCompression/gem.json index 98156cc404..a9cf3fa460 100644 --- a/Gems/MultiplayerCompression/gem.json +++ b/Gems/MultiplayerCompression/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Multiplayer Compression Gem provides an open source Compressor for use with AzNetworking's transport layer.", "canonical_tags": [ diff --git a/Gems/NvCloth/CMakeLists.txt b/Gems/NvCloth/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/NvCloth/CMakeLists.txt +++ b/Gems/NvCloth/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/NvCloth/Code/CMakeLists.txt b/Gems/NvCloth/Code/CMakeLists.txt index 5b5bba9d8b..76f5bcfeb8 100644 --- a/Gems/NvCloth/Code/CMakeLists.txt +++ b/Gems/NvCloth/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) #for PAL_TRAIT_NVCLOTH Traits diff --git a/Gems/NvCloth/gem.json b/Gems/NvCloth/gem.json index 86a70b9373..9494d65e82 100644 --- a/Gems/NvCloth/gem.json +++ b/Gems/NvCloth/gem.json @@ -2,8 +2,9 @@ "gem_name": "NvCloth", "display_name": "NVIDIA Cloth (NvCloth)", "license": "Apache-2.0 Or MIT", - "origin": "Open 3D Engine - o3de.org", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The NVIDIA Cloth Gem provides functionality to create fast, realistic cloth simulation with the NVIDIA Cloth library.", "canonical_tags": [ diff --git a/Gems/PhysX/CMakeLists.txt b/Gems/PhysX/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/PhysX/CMakeLists.txt +++ b/Gems/PhysX/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/PhysX/Code/CMakeLists.txt b/Gems/PhysX/Code/CMakeLists.txt index f045d6b00d..1cad877542 100644 --- a/Gems/PhysX/Code/CMakeLists.txt +++ b/Gems/PhysX/Code/CMakeLists.txt @@ -8,7 +8,7 @@ add_subdirectory(NumericalMethods) -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_PHYSX_SUPPORTED set(LY_PHYSX_ENABLE_RUNNING_BENCHMARKS OFF CACHE BOOL "Adds a target to allow running of the physx benchmarks.") diff --git a/Gems/PhysXDebug/CMakeLists.txt b/Gems/PhysXDebug/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/PhysXDebug/CMakeLists.txt +++ b/Gems/PhysXDebug/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/PhysXDebug/Code/CMakeLists.txt b/Gems/PhysXDebug/Code/CMakeLists.txt index 3ddec9d105..0886f2bf34 100644 --- a/Gems/PhysXDebug/Code/CMakeLists.txt +++ b/Gems/PhysXDebug/Code/CMakeLists.txt @@ -6,7 +6,11 @@ # # -ly_get_list_relative_pal_filename(physx_pal_source_dir ${LY_ROOT_FOLDER}/Gems/PhysX/Code/Source/Platform/${PAL_PLATFORM_NAME}) +# This gem relies on the PhysX gem +o3de_find_gem("PhysX" physx_gem_path) +set(physx_gem_json ${physx_gem_path}/gem.json) +o3de_restricted_path(${physx_gem_json} physx_gem_restricted_path physx_gem_parent_relative_path) +o3de_pal_dir(physx_pal_source_dir ${physx_gem_path}/Code/Source/Platform/${PAL_PLATFORM_NAME} ${physx_gem_restricted_path} ${physx_gem_path} ${physx_gem_parent_relative_path}) include(${physx_pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_PHYSX_SUPPORTED diff --git a/Gems/PhysXDebug/gem.json b/Gems/PhysXDebug/gem.json index 2d9f4dc24d..1087eefad4 100644 --- a/Gems/PhysXDebug/gem.json +++ b/Gems/PhysXDebug/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The PhysX Debug Gem provides debugging functionality and visualizations for NVIDIA PhysX in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/Prefab/PrefabBuilder/gem.json b/Gems/Prefab/PrefabBuilder/gem.json index 2233a7235e..1c0dcd9a72 100644 --- a/Gems/Prefab/PrefabBuilder/gem.json +++ b/Gems/Prefab/PrefabBuilder/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Prefab Builder Gem provides an Asset Processor module for prefabs, which are complex assets built by combining smaller entities.", "canonical_tags": [ diff --git a/Gems/Presence/CMakeLists.txt b/Gems/Presence/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Presence/CMakeLists.txt +++ b/Gems/Presence/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Presence/Code/CMakeLists.txt b/Gems/Presence/Code/CMakeLists.txt index c1c807d432..cc84771201 100644 --- a/Gems/Presence/Code/CMakeLists.txt +++ b/Gems/Presence/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME Presence.Headers HEADERONLY diff --git a/Gems/Presence/gem.json b/Gems/Presence/gem.json index 624af2e62d..48d9dd5ef0 100644 --- a/Gems/Presence/gem.json +++ b/Gems/Presence/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Presence Gem provides a target platform agnostic interface for Presence services.", "canonical_tags": [ diff --git a/Gems/PrimitiveAssets/gem.json b/Gems/PrimitiveAssets/gem.json index 0e4c4689dc..7669477220 100644 --- a/Gems/PrimitiveAssets/gem.json +++ b/Gems/PrimitiveAssets/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The Primitive Assets Gem provides primitive shape mesh assets with physics enabled.", "canonical_tags": [ diff --git a/Gems/Profiler/gem.json b/Gems/Profiler/gem.json index b160bc4b3c..40478deae1 100644 --- a/Gems/Profiler/gem.json +++ b/Gems/Profiler/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "A collection of utilities for capturing performance data", "canonical_tags": [ diff --git a/Gems/PythonAssetBuilder/gem.json b/Gems/PythonAssetBuilder/gem.json index 8046104f03..54fbb949f9 100644 --- a/Gems/PythonAssetBuilder/gem.json +++ b/Gems/PythonAssetBuilder/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Python Asset Builder Gem provides functionality to implement custom asset builders in Python for Asset Processor.", "canonical_tags": [ diff --git a/Gems/QtForPython/Code/CMakeLists.txt b/Gems/QtForPython/Code/CMakeLists.txt index da763978a6..d63c71492d 100644 --- a/Gems/QtForPython/Code/CMakeLists.txt +++ b/Gems/QtForPython/Code/CMakeLists.txt @@ -9,7 +9,7 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) include(${CMAKE_CURRENT_SOURCE_DIR}/Source/Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Gems/QtForPython/gem.json b/Gems/QtForPython/gem.json index 17d3a26f21..63805a5bc7 100644 --- a/Gems/QtForPython/gem.json +++ b/Gems/QtForPython/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Qt for Python Gem provides the PySide2 Python libraries to manage Qt widgets.", "canonical_tags": [ diff --git a/Gems/SaveData/CMakeLists.txt b/Gems/SaveData/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/SaveData/CMakeLists.txt +++ b/Gems/SaveData/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/SaveData/Code/CMakeLists.txt b/Gems/SaveData/Code/CMakeLists.txt index 38d145f8e5..5d4eb361cc 100644 --- a/Gems/SaveData/Code/CMakeLists.txt +++ b/Gems/SaveData/Code/CMakeLists.txt @@ -6,7 +6,7 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) ly_add_target( NAME SaveData.Static STATIC diff --git a/Gems/SaveData/gem.json b/Gems/SaveData/gem.json index 1ee5a54cec..3a686242d7 100644 --- a/Gems/SaveData/gem.json +++ b/Gems/SaveData/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Save Data Gem provides a platform independent API to save and load persistent user data in Open 3D Engine projects.", "canonical_tags": [ diff --git a/Gems/SceneLoggingExample/gem.json b/Gems/SceneLoggingExample/gem.json index ad950f3992..dc6b5179b6 100644 --- a/Gems/SceneLoggingExample/gem.json +++ b/Gems/SceneLoggingExample/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The Scene Logging Example Gem demonstrates the basics of extending the Open 3D Engine Scene API by adding additional logging to the pipeline.", "canonical_tags": [ diff --git a/Gems/SceneProcessing/gem.json b/Gems/SceneProcessing/gem.json index 576460d0a9..3689c2500a 100644 --- a/Gems/SceneProcessing/gem.json +++ b/Gems/SceneProcessing/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Scene Processing Gem provides Scene Settings, a tool you can use to specify the default settings for processing asset files for actors, meshes, motions, and PhysX.", "canonical_tags": [ diff --git a/Gems/ScriptCanvas/gem.json b/Gems/ScriptCanvas/gem.json index fc8a504917..ace6bca50c 100644 --- a/Gems/ScriptCanvas/gem.json +++ b/Gems/ScriptCanvas/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Script Canvas Gem provides Open 3D Engine's visual scripting environment, Script Canvas.", "canonical_tags": [ diff --git a/Gems/ScriptCanvasDeveloper/gem.json b/Gems/ScriptCanvasDeveloper/gem.json index fe1fdea0fc..c7e23dab9a 100644 --- a/Gems/ScriptCanvasDeveloper/gem.json +++ b/Gems/ScriptCanvasDeveloper/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Script Canvas Developer Gem provides a suite of utility features for the development and debugging of Script Canvas systems.", "canonical_tags": [ diff --git a/Gems/ScriptCanvasPhysics/gem.json b/Gems/ScriptCanvasPhysics/gem.json index 2e35e85c46..fdf83fe479 100644 --- a/Gems/ScriptCanvasPhysics/gem.json +++ b/Gems/ScriptCanvasPhysics/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Script Canvas Physics Gem provides Script Canvas nodes for physics scene queries such as raycasts.", "canonical_tags": [ diff --git a/Gems/ScriptCanvasTesting/gem.json b/Gems/ScriptCanvasTesting/gem.json index 5cb718e674..f62ec46fd4 100644 --- a/Gems/ScriptCanvasTesting/gem.json +++ b/Gems/ScriptCanvasTesting/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Script Canvas Testing Gem provides a framework for testing for and with Script Canvas.", "canonical_tags": [ diff --git a/Gems/ScriptEvents/gem.json b/Gems/ScriptEvents/gem.json index 5640e08489..c9391da996 100644 --- a/Gems/ScriptEvents/gem.json +++ b/Gems/ScriptEvents/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Script Events Gem provides a framework for creating event assets usable from any scripting solution in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/ScriptedEntityTweener/gem.json b/Gems/ScriptedEntityTweener/gem.json index 477345093c..bf7eec470f 100644 --- a/Gems/ScriptedEntityTweener/gem.json +++ b/Gems/ScriptedEntityTweener/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Scripted Entity Tweener Gem provides a script driven animation system for Open 3D Engine projects.", "canonical_tags": [ diff --git a/Gems/SliceFavorites/gem.json b/Gems/SliceFavorites/gem.json index c4536dc042..bbb873b20b 100644 --- a/Gems/SliceFavorites/gem.json +++ b/Gems/SliceFavorites/gem.json @@ -4,13 +4,18 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "Add the ability to favorite a slice to allow easy access and instantiation", + "canonical_tags": [ + "Gem" + ], "user_tags": [ "Editor", "Slices" ], "icon_path": "preview.png", "requirements": "", + "documentation_url": "", "dependencies": [] } diff --git a/Gems/StartingPointCamera/gem.json b/Gems/StartingPointCamera/gem.json index 1033770022..1a736d6e74 100644 --- a/Gems/StartingPointCamera/gem.json +++ b/Gems/StartingPointCamera/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Starting Point Camera Gem provides the behaviors used with the Camera Framework Gem to define a camera rig.", "canonical_tags": [ diff --git a/Gems/StartingPointInput/gem.json b/Gems/StartingPointInput/gem.json index ee1655b794..77a683658d 100644 --- a/Gems/StartingPointInput/gem.json +++ b/Gems/StartingPointInput/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Starting Point Input Gem provides functionality to map low-level input events to high-level actions.", "canonical_tags": [ diff --git a/Gems/StartingPointMovement/gem.json b/Gems/StartingPointMovement/gem.json index 188d8483bc..a9941098fa 100644 --- a/Gems/StartingPointMovement/gem.json +++ b/Gems/StartingPointMovement/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Starting Point Movement Gem provides a series of Lua scripts that listen and respond to input events and trigger transform operations such as translation and rotation.", "canonical_tags": [ diff --git a/Gems/SurfaceData/gem.json b/Gems/SurfaceData/gem.json index d16254040f..10100e3b90 100644 --- a/Gems/SurfaceData/gem.json +++ b/Gems/SurfaceData/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Surface Data Gem provides functionality to emit signals or tags from surfaces such as meshes and terrain.", "canonical_tags": [ diff --git a/Gems/Terrain/gem.json b/Gems/Terrain/gem.json index 0ca470c4d3..f038eb4d90 100644 --- a/Gems/Terrain/gem.json +++ b/Gems/Terrain/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "summary": "The Terrain Gem is an experimental terrain system. The terrain system maps height, color, and surface data to regions of the world, provides gradient-based and shape-based authoring tools and workflows, includes specialized rendering for efficient display, and integrates with physics for physical simulation.", "canonical_tags": [ "Gem" diff --git a/Gems/TestAssetBuilder/gem.json b/Gems/TestAssetBuilder/gem.json index 68ed706499..96c3bb4ffb 100644 --- a/Gems/TestAssetBuilder/gem.json +++ b/Gems/TestAssetBuilder/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Test Asset Builder Gem is used to feature test Asset Processor.", "canonical_tags": [ diff --git a/Gems/TextureAtlas/gem.json b/Gems/TextureAtlas/gem.json index 142f0fb082..970982fb48 100644 --- a/Gems/TextureAtlas/gem.json +++ b/Gems/TextureAtlas/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Texture Atlas Gem provides the formatting for texture atlases from 2D textures for LyShine.", "canonical_tags": [ diff --git a/Gems/TickBusOrderViewer/gem.json b/Gems/TickBusOrderViewer/gem.json index a6a6fd23ac..78b4d96c5c 100644 --- a/Gems/TickBusOrderViewer/gem.json +++ b/Gems/TickBusOrderViewer/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The Tick Bus Order Viewer Gem provides a console variable that displays the order of runtime tick events.", "canonical_tags": [ diff --git a/Gems/Twitch/CMakeLists.txt b/Gems/Twitch/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/Twitch/CMakeLists.txt +++ b/Gems/Twitch/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/Twitch/Code/CMakeLists.txt b/Gems/Twitch/Code/CMakeLists.txt index 80c74e5bd4..75b18627cf 100644 --- a/Gems/Twitch/Code/CMakeLists.txt +++ b/Gems/Twitch/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common) ly_add_target( NAME Twitch.Static STATIC diff --git a/Gems/Twitch/gem.json b/Gems/Twitch/gem.json index 42ec1b971e..70386e057f 100644 --- a/Gems/Twitch/gem.json +++ b/Gems/Twitch/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Twitch Gem provides access to the Twitch API v5 SDK including social functions, channels, and other APIs.", "canonical_tags": [ @@ -12,7 +13,8 @@ "user_tags": [ "Network", "SDK", - "Multiplayer" + "Multiplayer", + "Twitch" ], "icon_path": "preview.png", "requirements": "", diff --git a/Gems/UiBasics/gem.json b/Gems/UiBasics/gem.json index bb2416c235..4734aef779 100644 --- a/Gems/UiBasics/gem.json +++ b/Gems/UiBasics/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Asset", "summary": "The UI Basics Gem provides a collection of basic UI prefabs such as image, text, and button, that can be used with LyShine, the Open 3D Engine runtime User Interface system and editor.", "canonical_tags": [ diff --git a/Gems/Vegetation/gem.json b/Gems/Vegetation/gem.json index 75416933f0..8dfd3b3a59 100644 --- a/Gems/Vegetation/gem.json +++ b/Gems/Vegetation/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Vegetation Gem provides tools to place natural-looking vegetation in Open 3D Engine.", "canonical_tags": [ diff --git a/Gems/VideoPlaybackFramework/gem.json b/Gems/VideoPlaybackFramework/gem.json index 381738ab4b..9115148c50 100644 --- a/Gems/VideoPlaybackFramework/gem.json +++ b/Gems/VideoPlaybackFramework/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Video Playback Framework Gem provides the interface to play back video.", "canonical_tags": [ diff --git a/Gems/VirtualGamepad/gem.json b/Gems/VirtualGamepad/gem.json index 637776ac85..a2a669bb11 100644 --- a/Gems/VirtualGamepad/gem.json +++ b/Gems/VirtualGamepad/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "The Virtual Gamepad Gem provides controls that emulate a gamepad on touch screen devices.", "canonical_tags": [ diff --git a/Gems/WhiteBox/CMakeLists.txt b/Gems/WhiteBox/CMakeLists.txt index 2bb380fae3..50f9e78c74 100644 --- a/Gems/WhiteBox/CMakeLists.txt +++ b/Gems/WhiteBox/CMakeLists.txt @@ -6,4 +6,8 @@ # # +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + add_subdirectory(Code) diff --git a/Gems/WhiteBox/Code/CMakeLists.txt b/Gems/WhiteBox/Code/CMakeLists.txt index bfc4eb724a..91536503ac 100644 --- a/Gems/WhiteBox/Code/CMakeLists.txt +++ b/Gems/WhiteBox/Code/CMakeLists.txt @@ -6,8 +6,8 @@ # # -ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) +o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) +set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/Gems/WhiteBox/gem.json b/Gems/WhiteBox/gem.json index 2d173e9a6b..18a3022b74 100644 --- a/Gems/WhiteBox/gem.json +++ b/Gems/WhiteBox/gem.json @@ -4,6 +4,7 @@ "license": "Apache-2.0 Or MIT", "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Tool", "summary": "The White Box Gem provides White Box rapid design components for Open 3D Engine.", "canonical_tags": [ diff --git a/Templates/AssetGem/Template/gem.json b/Templates/AssetGem/Template/gem.json index 2a02362256..b04ecf9dd8 100644 --- a/Templates/AssetGem/Template/gem.json +++ b/Templates/AssetGem/Template/gem.json @@ -1,18 +1,21 @@ { "gem_name": "${Name}", "display_name": "${Name}", - "license": "What license ${Name} uses goes here: i.e. Apache-2.0 Or MIT", - "license_url": "", - "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", "type": "Asset", - "summary": "A short description of ${Name}.", + "summary": "A short description of ${Name} goes here.", "canonical_tags": [ "Gem" ], "user_tags": [ - "Assets", "${Name}" ], "icon_path": "preview.png", - "requirements": "" + "requirements": "Notice of any requirements ${Name} has goes here. i.e. This requires X other gem", + "documentation_url": "Link to any documentation of ${Name} goes here: i.e. https://o3de.org/docs/user-guide/gems/reference/design/white-box/", + "dependencies": [ + ] } diff --git a/Templates/AssetGem/template.json b/Templates/AssetGem/template.json index e858dc526d..2f390f2077 100644 --- a/Templates/AssetGem/template.json +++ b/Templates/AssetGem/template.json @@ -1,10 +1,17 @@ { "template_name": "AssetGem", - "origin": "The primary repo for AssetGem goes here: i.e. http://www.mydomain.com", - "license": "What license AssetGem uses goes here: i.e. https://opensource.org/licenses/MIT", - "display_name": "AssetGem", - "summary": "A short description of AssetGem template.", - "canonical_tags": [], + "template_restricted_platform_relative_path": "Templates/AssetGem", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "display_name": "Asset Gem Template", + "summary": "Use this gem template to create the minimal gem needed for adding asset(s).", + "canonical_tags": [ + "Template", + "Gem", + "Asset" + ], "user_tags": [ "AssetGem" ], @@ -12,27 +19,20 @@ "copyFiles": [ { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" } ] } diff --git a/Templates/CppToolGem/Template/gem.json b/Templates/CppToolGem/Template/gem.json index 079b7152ff..05be122226 100644 --- a/Templates/CppToolGem/Template/gem.json +++ b/Templates/CppToolGem/Template/gem.json @@ -1,11 +1,12 @@ { "gem_name": "${Name}", "display_name": "${Name}", - "license": "What license ${Name} uses goes here: i.e. Apache-2.0 Or MIT", - "license_url": "", - "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", "type": "Code", - "summary": "A short description of ${Name}.", + "summary": "A short description of ${Name} goes here.", "canonical_tags": [ "Gem" ], @@ -13,6 +14,8 @@ "${Name}" ], "icon_path": "preview.png", - "requirements": "", - "restricted_name": "gems" + "requirements": "Notice of any requirements ${Name} has goes here. i.e. This requires X other gem", + "documentation_url": "Link to any documentation of ${Name} goes here: i.e. https://o3de.org/docs/user-guide/gems/reference/design/white-box/", + "dependencies": [ + ] } diff --git a/Templates/CppToolGem/template.json b/Templates/CppToolGem/template.json index b516dbaec3..16874326ef 100644 --- a/Templates/CppToolGem/template.json +++ b/Templates/CppToolGem/template.json @@ -1,10 +1,16 @@ { "template_name": "CppToolGem", - "origin": "The primary repo for CppToolGem goes here: i.e. http://www.mydomain.com", - "license": "What license CppToolGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "template_restricted_platform_relative_path": "Templates/CppToolGem", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "display_name": "CppToolGem", "summary": "A gem template for a custom tool in C++ that gets registered with the Editor.", - "canonical_tags": [], + "canonical_tags": [ + "Template", + "Gem" + ], "user_tags": [ "CppToolGem" ], @@ -12,371 +18,255 @@ "copyFiles": [ { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Code/${NameLower}_editor_files.cmake", - "origin": "Code/${NameLower}_editor_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_shared_files.cmake", - "origin": "Code/${NameLower}_editor_shared_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_tests_files.cmake", - "origin": "Code/${NameLower}_editor_tests_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_files.cmake", - "origin": "Code/${NameLower}_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_shared_files.cmake", - "origin": "Code/${NameLower}_shared_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_tests_files.cmake", - "origin": "Code/${NameLower}_tests_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/CMakeLists.txt", - "origin": "Code/CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/${NameLower}_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_android_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/PAL_android.cmake", - "origin": "Code/Platform/Android/PAL_android.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/PAL_linux.cmake", - "origin": "Code/Platform/Linux/PAL_linux.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/PAL_mac.cmake", - "origin": "Code/Platform/Mac/PAL_mac.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/PAL_windows.cmake", - "origin": "Code/Platform/Windows/PAL_windows.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/PAL_ios.cmake", - "origin": "Code/Platform/iOS/PAL_ios.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}.qrc", - "origin": "Code/Source/${Name}.qrc", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorModule.cpp", - "origin": "Code/Source/${Name}EditorModule.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.cpp", - "origin": "Code/Source/${Name}EditorSystemComponent.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.h", - "origin": "Code/Source/${Name}EditorSystemComponent.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}Module.cpp", - "origin": "Code/Source/${Name}Module.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}ModuleInterface.h", - "origin": "Code/Source/${Name}ModuleInterface.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}SystemComponent.cpp", - "origin": "Code/Source/${Name}SystemComponent.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}SystemComponent.h", - "origin": "Code/Source/${Name}SystemComponent.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}Widget.cpp", - "origin": "Code/Source/${Name}Widget.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}Widget.h", - "origin": "Code/Source/${Name}Widget.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/toolbar_icon.svg", - "origin": "Code/Source/toolbar_icon.svg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Code/Tests/${Name}EditorTest.cpp", - "origin": "Code/Tests/${Name}EditorTest.cpp", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Code/Tests/${Name}Test.cpp", - "origin": "Code/Tests/${Name}Test.cpp", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Android/android_gem.cmake", - "origin": "Platform/Android/android_gem.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Android/android_gem.json", - "origin": "Platform/Android/android_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Linux/linux_gem.cmake", - "origin": "Platform/Linux/linux_gem.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Linux/linux_gem.json", - "origin": "Platform/Linux/linux_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_gem.cmake", - "origin": "Platform/Mac/mac_gem.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_gem.json", - "origin": "Platform/Mac/mac_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_gem.cmake", - "origin": "Platform/Windows/windows_gem.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_gem.json", - "origin": "Platform/Windows/windows_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_gem.cmake", - "origin": "Platform/iOS/ios_gem.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_gem.json", - "origin": "Platform/iOS/ios_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" }, { - "dir": "Code", - "origin": "Code" + "dir": "Code" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "Code/Include" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "Code/Include/${Name}" }, { - "dir": "Code/Platform", - "origin": "Code/Platform" + "dir": "Code/Platform" }, { - "dir": "Code/Platform/Android", - "origin": "Code/Platform/Android" + "dir": "Code/Platform/Android" }, { - "dir": "Code/Platform/Linux", - "origin": "Code/Platform/Linux" + "dir": "Code/Platform/Linux" }, { - "dir": "Code/Platform/Mac", - "origin": "Code/Platform/Mac" + "dir": "Code/Platform/Mac" }, { - "dir": "Code/Platform/Windows", - "origin": "Code/Platform/Windows" + "dir": "Code/Platform/Windows" }, { - "dir": "Code/Platform/iOS", - "origin": "Code/Platform/iOS" + "dir": "Code/Platform/iOS" }, { - "dir": "Code/Source", - "origin": "Code/Source" + "dir": "Code/Source" }, { - "dir": "Code/Tests", - "origin": "Code/Tests" + "dir": "Code/Tests" }, { - "dir": "Platform", - "origin": "Platform" + "dir": "Platform" }, { - "dir": "Platform/Android", - "origin": "Platform/Android" + "dir": "Platform/Android" }, { - "dir": "Platform/Linux", - "origin": "Platform/Linux" + "dir": "Platform/Linux" }, { - "dir": "Platform/Mac", - "origin": "Platform/Mac" + "dir": "Platform/Mac" }, { - "dir": "Platform/Windows", - "origin": "Platform/Windows" + "dir": "Platform/Windows" }, { - "dir": "Platform/iOS", - "origin": "Platform/iOS" + "dir": "Platform/iOS" } ] } diff --git a/Templates/DefaultGem/Template/CMakeLists.txt b/Templates/DefaultGem/Template/CMakeLists.txt index b19ea2edce..f4c55dd1a5 100644 --- a/Templates/DefaultGem/Template/CMakeLists.txt +++ b/Templates/DefaultGem/Template/CMakeLists.txt @@ -6,12 +6,11 @@ # # {END_LICENSE} -set(o3de_gem_path ${CMAKE_CURRENT_LIST_DIR}) -set(o3de_gem_json ${o3de_gem_path}/gem.json) -o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name") -o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path) +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${o3de_gem_restricted_path}" ${o3de_gem_path} ${o3de_gem_name}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # project cmake for this platform. diff --git a/Templates/DefaultGem/Template/Code/CMakeLists.txt b/Templates/DefaultGem/Template/Code/CMakeLists.txt index f462e7f2d4..c5ff305b2a 100644 --- a/Templates/DefaultGem/Template/Code/CMakeLists.txt +++ b/Templates/DefaultGem/Template/Code/CMakeLists.txt @@ -8,11 +8,11 @@ # Currently we are in the Code folder: ${CMAKE_CURRENT_LIST_DIR} # Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} -# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform +# Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform # in which case it will see if that platform is present here or in the restricted folder. # i.e. It could here in our gem : Gems/${Name}/Code/Platform/ or # //Gems/${Name}/Code -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # traits for this platform. Traits for a platform are defines for things like whether or not something in this gem diff --git a/Templates/DefaultGem/Template/gem.json b/Templates/DefaultGem/Template/gem.json index d4ff637bee..05be122226 100644 --- a/Templates/DefaultGem/Template/gem.json +++ b/Templates/DefaultGem/Template/gem.json @@ -1,11 +1,12 @@ { "gem_name": "${Name}", "display_name": "${Name}", - "license": "What license ${Name} uses goes here: i.e. Apache-2.0 Or MIT", - "license_url": "", - "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", "type": "Code", - "summary": "A short description of ${Name}.", + "summary": "A short description of ${Name} goes here.", "canonical_tags": [ "Gem" ], @@ -13,5 +14,8 @@ "${Name}" ], "icon_path": "preview.png", - "requirements": "" + "requirements": "Notice of any requirements ${Name} has goes here. i.e. This requires X other gem", + "documentation_url": "Link to any documentation of ${Name} goes here: i.e. https://o3de.org/docs/user-guide/gems/reference/design/white-box/", + "dependencies": [ + ] } diff --git a/Templates/DefaultGem/template.json b/Templates/DefaultGem/template.json index e24632d6a0..e5dc570cbe 100644 --- a/Templates/DefaultGem/template.json +++ b/Templates/DefaultGem/template.json @@ -1,12 +1,16 @@ { "template_name": "DefaultGem", + "template_restricted_platform_relative_path": "Templates/DefaultGem", "restricted_name": "o3de", - "restricted_platform_relative_path": "Templates", - "origin": "The primary repo for DefaultGem goes here: i.e. http://www.mydomain.com", - "license": "What license DefaultGem uses goes here: i.e. https://opensource.org/licenses/MIT", - "display_name": "DefaultGem", - "summary": "A short description of DefaultGem.", - "canonical_tags": [], + "restricted_platform_relative_path": "Templates/DefaultGem", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "display_name": "Default Gem Template", + "summary": "This is the gem template that will be used if no gem template is specified during gem creation.", + "canonical_tags": [ + "Template", + "Gem" + ], "user_tags": [ "DefaultGem" ], @@ -14,347 +18,239 @@ "copyFiles": [ { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_files.cmake", - "origin": "Code/${NameLower}_editor_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_shared_files.cmake", - "origin": "Code/${NameLower}_editor_shared_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_tests_files.cmake", - "origin": "Code/${NameLower}_editor_tests_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_files.cmake", - "origin": "Code/${NameLower}_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_shared_files.cmake", - "origin": "Code/${NameLower}_shared_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_tests_files.cmake", - "origin": "Code/${NameLower}_tests_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/CMakeLists.txt", - "origin": "Code/CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/${NameLower}_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_android_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Android/PAL_android.cmake", - "origin": "Code/Platform/Android/PAL_android.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/PAL_linux.cmake", - "origin": "Code/Platform/Linux/PAL_linux.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/PAL_mac.cmake", - "origin": "Code/Platform/Mac/PAL_mac.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/PAL_windows.cmake", - "origin": "Code/Platform/Windows/PAL_windows.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/iOS/PAL_ios.cmake", - "origin": "Code/Platform/iOS/PAL_ios.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorModule.cpp", - "origin": "Code/Source/${Name}EditorModule.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.cpp", - "origin": "Code/Source/${Name}EditorSystemComponent.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.h", - "origin": "Code/Source/${Name}EditorSystemComponent.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}Module.cpp", - "origin": "Code/Source/${Name}Module.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}ModuleInterface.h", - "origin": "Code/Source/${Name}ModuleInterface.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}SystemComponent.cpp", - "origin": "Code/Source/${Name}SystemComponent.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}SystemComponent.h", - "origin": "Code/Source/${Name}SystemComponent.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Tests/${Name}EditorTest.cpp", - "origin": "Code/Tests/${Name}EditorTest.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Tests/${Name}Test.cpp", - "origin": "Code/Tests/${Name}Test.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Android/android_gem.cmake", - "origin": "Platform/Android/android_gem.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Android/android_gem.json", - "origin": "Platform/Android/android_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Linux/linux_gem.cmake", - "origin": "Platform/Linux/linux_gem.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Linux/linux_gem.json", - "origin": "Platform/Linux/linux_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_gem.cmake", - "origin": "Platform/Mac/mac_gem.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Mac/mac_gem.json", - "origin": "Platform/Mac/mac_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_gem.cmake", - "origin": "Platform/Windows/windows_gem.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Windows/windows_gem.json", - "origin": "Platform/Windows/windows_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_gem.cmake", - "origin": "Platform/iOS/ios_gem.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/iOS/ios_gem.json", - "origin": "Platform/iOS/ios_gem.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" }, { - "dir": "Code", - "origin": "Code" + "dir": "Code" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "Code/Include" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "Code/Include/${Name}" }, { - "dir": "Code/Platform", - "origin": "Code/Platform" + "dir": "Code/Platform" }, { - "dir": "Code/Platform/Android", - "origin": "Code/Platform/Android" + "dir": "Code/Platform/Android" }, { - "dir": "Code/Platform/Linux", - "origin": "Code/Platform/Linux" + "dir": "Code/Platform/Linux" }, { - "dir": "Code/Platform/Mac", - "origin": "Code/Platform/Mac" + "dir": "Code/Platform/Mac" }, { - "dir": "Code/Platform/Windows", - "origin": "Code/Platform/Windows" + "dir": "Code/Platform/Windows" }, { - "dir": "Code/Platform/iOS", - "origin": "Code/Platform/iOS" + "dir": "Code/Platform/iOS" }, { - "dir": "Code/Source", - "origin": "Code/Source" + "dir": "Code/Source" }, { - "dir": "Code/Tests", - "origin": "Code/Tests" + "dir": "Code/Tests" }, { - "dir": "Platform", - "origin": "Platform" + "dir": "Platform" }, { - "dir": "Platform/Android", - "origin": "Platform/Android" + "dir": "Platform/Android" }, { - "dir": "Platform/Linux", - "origin": "Platform/Linux" + "dir": "Platform/Linux" }, { - "dir": "Platform/Mac", - "origin": "Platform/Mac" + "dir": "Platform/Mac" }, { - "dir": "Platform/Windows", - "origin": "Platform/Windows" + "dir": "Platform/Windows" }, { - "dir": "Platform/iOS", - "origin": "Platform/iOS" + "dir": "Platform/iOS" } ] } diff --git a/Templates/DefaultProject/Template/CMakeLists.txt b/Templates/DefaultProject/Template/CMakeLists.txt index ae4bb662a3..420a92948d 100644 --- a/Templates/DefaultProject/Template/CMakeLists.txt +++ b/Templates/DefaultProject/Template/CMakeLists.txt @@ -29,5 +29,4 @@ else() set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${project_target_name}) - add_subdirectory(Code) endif() diff --git a/Templates/DefaultProject/Template/Code/${NameLower}_files.cmake b/Templates/DefaultProject/Template/Gem/${NameLower}_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/${NameLower}_files.cmake rename to Templates/DefaultProject/Template/Gem/${NameLower}_files.cmake diff --git a/Templates/DefaultProject/Template/Code/${NameLower}_shared_files.cmake b/Templates/DefaultProject/Template/Gem/${NameLower}_shared_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/${NameLower}_shared_files.cmake rename to Templates/DefaultProject/Template/Gem/${NameLower}_shared_files.cmake diff --git a/Templates/MinimalProject/Template/Code/CMakeLists.txt b/Templates/DefaultProject/Template/Gem/CMakeLists.txt similarity index 87% rename from Templates/MinimalProject/Template/Code/CMakeLists.txt rename to Templates/DefaultProject/Template/Gem/CMakeLists.txt index 5e646c0704..fc3eab6535 100644 --- a/Templates/MinimalProject/Template/Code/CMakeLists.txt +++ b/Templates/DefaultProject/Template/Gem/CMakeLists.txt @@ -6,13 +6,17 @@ # # {END_LICENSE} +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + # Currently we are in the ${Name}/Code folder: ${CMAKE_CURRENT_LIST_DIR} # Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} -# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform +# Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform # in which case it will see if that platform is present here or in the restricted folder. -# i.e. It could here : ${Name}/Code/Platform/ or +# i.e. It could here : ${Name}/Code/Platform/ or # //${Name}/Code -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_project_restricted_path} ${o3de_project_path} ${o3de_project_name}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # traits for this platform. Traits for a platform are defines for things like whether or not something in this project @@ -71,7 +75,6 @@ ly_create_alias(NAME ${Name}.Servers NAMESPACE Gem TARGETS Gem::${Name}) # Enable the specified list of gems from GEM_FILE or GEMS list for this specific project: ly_enable_gems(PROJECT_NAME ${Name} GEM_FILE enabled_gems.cmake) - if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) # this property causes it to actually make a ServerLauncher. # if you don't want a Server application, you can remove this and the diff --git a/Templates/DefaultProject/Template/Code/Include/${Name}/${Name}Bus.h b/Templates/DefaultProject/Template/Gem/Include/${Name}/${Name}Bus.h similarity index 99% rename from Templates/DefaultProject/Template/Code/Include/${Name}/${Name}Bus.h rename to Templates/DefaultProject/Template/Gem/Include/${Name}/${Name}Bus.h index d09bb2b009..d72b5785c3 100644 --- a/Templates/DefaultProject/Template/Code/Include/${Name}/${Name}Bus.h +++ b/Templates/DefaultProject/Template/Gem/Include/${Name}/${Name}Bus.h @@ -22,7 +22,7 @@ namespace ${SanitizedCppName} virtual ~${SanitizedCppName}Requests() = default; // Put your public methods here }; - + class ${SanitizedCppName}BusTraits : public AZ::EBusTraits { diff --git a/Templates/DefaultProject/Template/Code/Platform/Android/${NameLower}_android_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Android/${NameLower}_android_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Android/${NameLower}_android_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Android/${NameLower}_android_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Android/${NameLower}_shared_android_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Android/${NameLower}_shared_android_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Android/${NameLower}_shared_android_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Android/${NameLower}_shared_android_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Android/PAL_android.cmake b/Templates/DefaultProject/Template/Gem/Platform/Android/PAL_android.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Android/PAL_android.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Android/PAL_android.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Linux/${NameLower}_linux_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Linux/${NameLower}_linux_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Linux/${NameLower}_linux_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Linux/${NameLower}_linux_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Linux/${NameLower}_shared_linux_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Linux/${NameLower}_shared_linux_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Linux/PAL_linux.cmake b/Templates/DefaultProject/Template/Gem/Platform/Linux/PAL_linux.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Linux/PAL_linux.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Linux/PAL_linux.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Mac/${NameLower}_mac_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Mac/${NameLower}_mac_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Mac/${NameLower}_mac_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Mac/${NameLower}_mac_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Mac/${NameLower}_shared_mac_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Mac/${NameLower}_shared_mac_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Mac/PAL_mac.cmake b/Templates/DefaultProject/Template/Gem/Platform/Mac/PAL_mac.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Mac/PAL_mac.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Mac/PAL_mac.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Windows/${NameLower}_shared_windows_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Windows/${NameLower}_shared_windows_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Windows/${NameLower}_windows_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/Windows/${NameLower}_windows_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Windows/${NameLower}_windows_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Windows/${NameLower}_windows_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/Windows/PAL_windows.cmake b/Templates/DefaultProject/Template/Gem/Platform/Windows/PAL_windows.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/Windows/PAL_windows.cmake rename to Templates/DefaultProject/Template/Gem/Platform/Windows/PAL_windows.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/iOS/${NameLower}_ios_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/iOS/${NameLower}_ios_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/iOS/${NameLower}_ios_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/iOS/${NameLower}_ios_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/iOS/${NameLower}_shared_ios_files.cmake b/Templates/DefaultProject/Template/Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/iOS/${NameLower}_shared_ios_files.cmake rename to Templates/DefaultProject/Template/Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake diff --git a/Templates/DefaultProject/Template/Code/Platform/iOS/PAL_ios.cmake b/Templates/DefaultProject/Template/Gem/Platform/iOS/PAL_ios.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/Platform/iOS/PAL_ios.cmake rename to Templates/DefaultProject/Template/Gem/Platform/iOS/PAL_ios.cmake diff --git a/Templates/DefaultProject/Template/Code/Source/${Name}Module.cpp b/Templates/DefaultProject/Template/Gem/Source/${Name}Module.cpp similarity index 100% rename from Templates/DefaultProject/Template/Code/Source/${Name}Module.cpp rename to Templates/DefaultProject/Template/Gem/Source/${Name}Module.cpp diff --git a/Templates/DefaultProject/Template/Code/Source/${Name}SystemComponent.cpp b/Templates/DefaultProject/Template/Gem/Source/${Name}SystemComponent.cpp similarity index 99% rename from Templates/DefaultProject/Template/Code/Source/${Name}SystemComponent.cpp rename to Templates/DefaultProject/Template/Gem/Source/${Name}SystemComponent.cpp index cfb6ae3c42..487391c716 100644 --- a/Templates/DefaultProject/Template/Code/Source/${Name}SystemComponent.cpp +++ b/Templates/DefaultProject/Template/Gem/Source/${Name}SystemComponent.cpp @@ -52,7 +52,7 @@ namespace ${SanitizedCppName} void ${SanitizedCppName}SystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) { } - + ${SanitizedCppName}SystemComponent::${SanitizedCppName}SystemComponent() { if (${SanitizedCppName}Interface::Get() == nullptr) diff --git a/Templates/DefaultProject/Template/Code/Source/${Name}SystemComponent.h b/Templates/DefaultProject/Template/Gem/Source/${Name}SystemComponent.h similarity index 100% rename from Templates/DefaultProject/Template/Code/Source/${Name}SystemComponent.h rename to Templates/DefaultProject/Template/Gem/Source/${Name}SystemComponent.h diff --git a/Templates/DefaultProject/Template/Code/enabled_gems.cmake b/Templates/DefaultProject/Template/Gem/enabled_gems.cmake similarity index 100% rename from Templates/DefaultProject/Template/Code/enabled_gems.cmake rename to Templates/DefaultProject/Template/Gem/enabled_gems.cmake diff --git a/Templates/DefaultProject/Template/Gem/gem.json b/Templates/DefaultProject/Template/Gem/gem.json new file mode 100644 index 0000000000..b60f512006 --- /dev/null +++ b/Templates/DefaultProject/Template/Gem/gem.json @@ -0,0 +1,21 @@ +{ + "gem_name": "${Name}", + "display_name": "${Name}", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "type": "", + "summary": "A short description of ${Name}.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "${Name}" + ], + "icon_path": "preview.png", + "requirements": "", + "documentation_url": "", + "dependencies": [ + ] +} diff --git a/Templates/DefaultProject/Template/project.json b/Templates/DefaultProject/Template/project.json index f8d4643ce9..6d1875fcaa 100644 --- a/Templates/DefaultProject/Template/project.json +++ b/Templates/DefaultProject/Template/project.json @@ -2,7 +2,7 @@ "project_name": "${Name}", "project_id": "${ProjectId}", "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", - "license": "What license ${Name} uses goes here: i.e. https://opensource.org/licenses/MIT", + "license": "What license ${Name} uses goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT etc.", "display_name": "${Name}", "summary": "A short description of ${Name}.", "canonical_tags": [ @@ -13,5 +13,8 @@ ], "icon_path": "preview.png", "engine": "o3de", - "external_subdirectories": [] + "external_subdirectories": [ + "Gem" + ], + "restricted": "${Name}" } diff --git a/Templates/DefaultProject/template.json b/Templates/DefaultProject/template.json index fcffafcb34..203e1ec4ef 100644 --- a/Templates/DefaultProject/template.json +++ b/Templates/DefaultProject/template.json @@ -1,12 +1,18 @@ { "template_name": "DefaultProject", + "template_restricted_platform_relative_path": "Templates/DefaultProject", "restricted_name": "o3de", - "restricted_platform_relative_path": "Templates", - "origin": "The primary repo for DefaultProject goes here: i.e. http://www.mydomain.com", - "license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT", - "display_name": "Standard", - "summary": "This template has everything you need to build a full online 3D game or application.", - "canonical_tags": [], + "restricted_platform_relative_path": "Templates/DefaultProject", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "display_name": "Default Project Template", + "summary": "This is the project template that will be used if no project template is specified during project creation.", + "canonical_tags": [ + "Template", + "Project" + ], "user_tags": [ "DefaultProject" ], @@ -14,657 +20,459 @@ "copyFiles": [ { "file": ".gitignore", - "origin": ".gitignore", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/${NameLower}_files.cmake", - "origin": "Code/${NameLower}_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/${NameLower}_shared_files.cmake", - "origin": "Code/${NameLower}_shared_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/CMakeLists.txt", - "origin": "Code/CMakeLists.txt", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/${NameLower}_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_android_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/PAL_android.cmake", - "origin": "Code/Platform/Android/PAL_android.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/PAL_linux.cmake", - "origin": "Code/Platform/Linux/PAL_linux.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/PAL_mac.cmake", - "origin": "Code/Platform/Mac/PAL_mac.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/PAL_windows.cmake", - "origin": "Code/Platform/Windows/PAL_windows.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/PAL_ios.cmake", - "origin": "Code/Platform/iOS/PAL_ios.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}Module.cpp", - "origin": "Code/Source/${Name}Module.cpp", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}SystemComponent.cpp", - "origin": "Code/Source/${Name}SystemComponent.cpp", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}SystemComponent.h", - "origin": "Code/Source/${Name}SystemComponent.h", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/enabled_gems.cmake", - "origin": "Code/enabled_gems.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/gem.json", - "origin": "Code/gem.json", - "isTemplated": true, - "isOptional": true - }, - { - "file": "Config/shader_global_build_options.json", - "origin": "Config/shader_global_build_options.json", - "isTemplated": false, - "isOptional": false - }, - { - "file": "Config/default_aws_resource_mappings.json", - "origin": "Config/default_aws_resource_mappings.json", - "isTemplated": false, - "isOptional": false + "isTemplated": true }, { "file": "cmake/EngineFinder.cmake", - "origin": "cmake/EngineFinder.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": true }, { "file": "cmake/CompilerSettings.cmake", - "origin": "cmake/CompilerSettings.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "cmake/Platform/Linux/CompilerSettings_linux.cmake", - "origin": "cmake/Platform/Linux/CompilerSettings_linux.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false + }, + { + "file": "Config/default_aws_resource_mappings.json", + "isTemplated": false + }, + { + "file": "Config/shader_global_build_options.json", + "isTemplated": false + }, + { + "file": "Gem/${NameLower}_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/${NameLower}_shared_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/CMakeLists.txt", + "isTemplated": true + }, + { + "file": "Gem/Include/${Name}/${Name}Bus.h", + "isTemplated": true + }, + { + "file": "Gem/Platform/Android/${NameLower}_android_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Android/${NameLower}_shared_android_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Android/PAL_android.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Linux/${NameLower}_linux_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Linux/PAL_linux.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Mac/${NameLower}_mac_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Mac/PAL_mac.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Windows/${NameLower}_windows_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/Windows/PAL_windows.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/iOS/${NameLower}_ios_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake", + "isTemplated": false + }, + { + "file": "Gem/Platform/iOS/PAL_ios.cmake", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}Module.cpp", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}SystemComponent.cpp", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}SystemComponent.h", + "isTemplated": true + }, + { + "file": "Gem/enabled_gems.cmake", + "isTemplated": true + }, + { + "file": "Gem/gem.json", + "isTemplated": true }, { "file": "Platform/Android/android_project.cmake", - "origin": "Platform/Android/android_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Android/android_project.json", - "origin": "Platform/Android/android_project.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Linux/linux_project.cmake", - "origin": "Platform/Linux/linux_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Linux/linux_project.json", - "origin": "Platform/Linux/linux_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_project.cmake", - "origin": "Platform/Mac/mac_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_project.json", - "origin": "Platform/Mac/mac_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_project.cmake", - "origin": "Platform/Windows/windows_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_project.json", - "origin": "Platform/Windows/windows_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_project.cmake", - "origin": "Platform/iOS/ios_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_project.json", - "origin": "Platform/iOS/ios_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Registry/assets_scan_folders.setreg", - "origin": "Registry/assets_scan_folders.setreg", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Registry/awscoreconfiguration.setreg", - "origin": "Registry/awscoreconfiguration.setreg", - "isTemplated": false, - "isOptional": false - }, - { - "file": "Resources/LegacyLogoLauncher.bmp", - "origin": "Resources/LegacyLogoLauncher.bmp", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/GameSDK.ico", - "origin": "Resources/GameSDK.ico", - "isTemplated": false, - "isOptional": false + "isTemplated": false + }, + { + "file": "Resources/LegacyLogoLauncher.bmp", + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/Contents.json", - "origin": "Resources/Platform/Mac/Images.xcassets/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "isTemplated": false, - "isOptional": false - }, - { - "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false + }, + { + "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128_2x.png", + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16_2x.png", - "isTemplated": false, - "isOptional": false - }, - { - "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false + }, + { + "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256_2x.png", + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Info.plist", - "origin": "Resources/Platform/Mac/Info.plist", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Resources/Platform/iOS/Images.xcassets/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon152x152.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon152x152.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon76x76.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon76x76.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadProAppIcon167x167.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadProAppIcon167x167.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon29x29.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon29x29.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon58x58.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon58x58.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon40x40.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon40x40.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon80x80.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon80x80.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon120x120.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon120x120.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon180x180.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon180x180.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon58x58.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon58x58.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon87x87.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon87x87.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon120x120.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon120x120.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon80x80.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon80x80.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Info.plist", - "origin": "Resources/Platform/iOS/Info.plist", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "ShaderLib/README.md", - "origin": "ShaderLib/README.md", - "isTemplated": false, - "isOptional": true + "isTemplated": false }, { "file": "ShaderLib/scenesrg.srgi", - "origin": "ShaderLib/scenesrg.srgi", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "ShaderLib/viewsrg.srgi", - "origin": "ShaderLib/viewsrg.srgi", - "isTemplated": true, - "isOptional": false + "isTemplated": false }, { "file": "autoexec.cfg", - "origin": "autoexec.cfg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "game.cfg", - "origin": "game.cfg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "project.json", - "origin": "project.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" }, { - "dir": "Code", - "origin": "Code" + "dir": "cmake" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "cmake/Platform" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "cmake/Platform/Linux" }, { - "dir": "Code/Platform", - "origin": "Code/Platform" + "dir": "Config" }, { - "dir": "Code/Platform/Android", - "origin": "Code/Platform/Android" + "dir": "Gem" }, { - "dir": "Code/Platform/Linux", - "origin": "Code/Platform/Linux" + "dir": "Gem/Include" }, { - "dir": "Code/Platform/Mac", - "origin": "Code/Platform/Mac" + "dir": "Gem/Include/${Name}" }, { - "dir": "Code/Platform/Windows", - "origin": "Code/Platform/Windows" + "dir": "Gem/Platform" }, { - "dir": "Code/Platform/iOS", - "origin": "Code/Platform/iOS" + "dir": "Gem/Platform/Android" }, { - "dir": "Code/Source", - "origin": "Code/Source" + "dir": "Gem/Platform/Linux" }, { - "dir": "Config", - "origin": "Config" + "dir": "Gem/Platform/Mac" }, { - "dir": "Platform", - "origin": "Platform" + "dir": "Gem/Platform/Windows" }, { - "dir": "Platform/Android", - "origin": "Platform/Android" + "dir": "Gem/Platform/iOS" }, { - "dir": "Platform/Linux", - "origin": "Platform/Linux" + "dir": "Gem/Source" }, { - "dir": "Platform/Mac", - "origin": "Platform/Mac" + "dir": "Platform" }, { - "dir": "Platform/Windows", - "origin": "Platform/Windows" + "dir": "Platform/Android" }, { - "dir": "Platform/iOS", - "origin": "Platform/iOS" + "dir": "Platform/Linux" }, { - "dir": "Registry", - "origin": "Registry" + "dir": "Platform/Mac" }, { - "dir": "Resources", - "origin": "Resources" + "dir": "Platform/Windows" }, { - "dir": "Resources/Platform", - "origin": "Resources/Platform" + "dir": "Platform/iOS" }, { - "dir": "Resources/Platform/Mac", - "origin": "Resources/Platform/Mac" + "dir": "Registry" }, { - "dir": "Resources/Platform/Mac/Images.xcassets", - "origin": "Resources/Platform/Mac/Images.xcassets" + "dir": "Resources" }, { - "dir": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset" + "dir": "Resources/Platform" }, { - "dir": "Resources/Platform/iOS", - "origin": "Resources/Platform/iOS" + "dir": "Resources/Platform/Mac" }, { - "dir": "Resources/Platform/iOS/Images.xcassets", - "origin": "Resources/Platform/iOS/Images.xcassets" + "dir": "Resources/Platform/Mac/Images.xcassets" }, { - "dir": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage" + "dir": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset" }, { - "dir": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset" + "dir": "Resources/Platform/iOS" }, { - "dir": "ShaderLib", - "origin": "ShaderLib" + "dir": "Resources/Platform/iOS/Images.xcassets" }, { - "dir": "Shaders", - "origin": "Shaders" + "dir": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage" }, { - "dir": "Shaders/ShaderResourceGroups", - "origin": "Shaders/ShaderResourceGroups" + "dir": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset" + }, + { + "dir": "ShaderLib" + }, + { + "dir": "Shaders" + }, + { + "dir": "Shaders/ShaderResourceGroups" } ] } diff --git a/Templates/GemRepo/Template/gem.json b/Templates/GemRepo/Template/gem.json index 292681b2b5..7ba555a127 100644 --- a/Templates/GemRepo/Template/gem.json +++ b/Templates/GemRepo/Template/gem.json @@ -1,19 +1,23 @@ { - "gem_name": "${Name}Gem", - "display_name": "${Name}Gem", - "license": "What license ${Name}Gem uses goes here: i.e. Apache-2.0 Or MIT", - "license_url": "", - "origin": "The primary repo for ${Name}Gem goes here: i.e. http://www.mydomain.com", - "summary": "A short description of ${Name}Gem which is zipped up in an archive named gem.zip in the root of the Gem Repo. Though not required, it is recommended that the sha256 of the gem.zip file should be placed in the sha256 field of this gem.json so the download can be verified.", + "gem_name": "${Name}", + "display_name": "${Name}", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of ${Name} which is zipped up in an archive named gem.zip in the root of the Gem Repo. Though not required, it is recommended that the sha256 of the gem.zip file be placed in the sha256 field of this gem.json so the download can be verified.", "origin_uri": "${RepoURI}/gem.zip", "sha256": "", - "type": "Code", "canonical_tags": [ "Gem" ], "user_tags": [ - "${Name}Gem" + "${Name}" ], "icon_path": "preview.png", - "requirements": "" + "requirements": "", + "documentation_url": "", + "dependencies": [ + ] } diff --git a/Templates/GemRepo/template.json b/Templates/GemRepo/template.json index 88123a9dae..ca042329be 100644 --- a/Templates/GemRepo/template.json +++ b/Templates/GemRepo/template.json @@ -1,10 +1,14 @@ { "template_name": "GemRepo", - "origin": "The primary repo for GemRepo goes here: i.e. http://www.mydomain.com", - "license": "What license GemRepo uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "display_name": "GemRepo", "summary": "A Gem Repository that contains a single Gem.", - "canonical_tags": [], + "canonical_tags": [ + "Gem", + "Repo" + ], "user_tags": [ "GemRepo" ], @@ -12,15 +16,11 @@ "copyFiles": [ { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "repo.json", - "origin": "repo.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true } ], "createDirectories": [] diff --git a/Templates/MinimalProject/Template/CMakeLists.txt b/Templates/MinimalProject/Template/CMakeLists.txt index ae4bb662a3..420a92948d 100644 --- a/Templates/MinimalProject/Template/CMakeLists.txt +++ b/Templates/MinimalProject/Template/CMakeLists.txt @@ -29,5 +29,4 @@ else() set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${project_target_name}) - add_subdirectory(Code) endif() diff --git a/Templates/MinimalProject/Template/Code/${NameLower}_files.cmake b/Templates/MinimalProject/Template/Gem/${NameLower}_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/${NameLower}_files.cmake rename to Templates/MinimalProject/Template/Gem/${NameLower}_files.cmake diff --git a/Templates/MinimalProject/Template/Code/${NameLower}_shared_files.cmake b/Templates/MinimalProject/Template/Gem/${NameLower}_shared_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/${NameLower}_shared_files.cmake rename to Templates/MinimalProject/Template/Gem/${NameLower}_shared_files.cmake diff --git a/Templates/DefaultProject/Template/Code/CMakeLists.txt b/Templates/MinimalProject/Template/Gem/CMakeLists.txt similarity index 87% rename from Templates/DefaultProject/Template/Code/CMakeLists.txt rename to Templates/MinimalProject/Template/Gem/CMakeLists.txt index 7bbb9a0852..6b1dcf9172 100644 --- a/Templates/DefaultProject/Template/Code/CMakeLists.txt +++ b/Templates/MinimalProject/Template/Gem/CMakeLists.txt @@ -6,13 +6,17 @@ # # {END_LICENSE} +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + # Currently we are in the ${Name}/Code folder: ${CMAKE_CURRENT_LIST_DIR} # Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} -# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform +# Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform # in which case it will see if that platform is present here or in the restricted folder. -# i.e. It could here : ${Name}/Code/Platform/ or +# i.e. It could here : ${Name}/Code/Platform/ or # //${Name}/Code -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_project_restricted_path} ${o3de_project_path} ${o3de_project_name}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # traits for this platform. Traits for a platform are defines for things like whether or not something in this project @@ -71,6 +75,7 @@ ly_create_alias(NAME ${Name}.Servers NAMESPACE Gem TARGETS Gem::${Name}) # Enable the specified list of gems from GEM_FILE or GEMS list for this specific project: ly_enable_gems(PROJECT_NAME ${Name} GEM_FILE enabled_gems.cmake) + if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) # this property causes it to actually make a ServerLauncher. # if you don't want a Server application, you can remove this and the diff --git a/Templates/MinimalProject/Template/Code/Include/${Name}/${Name}Bus.h b/Templates/MinimalProject/Template/Gem/Include/${Name}/${Name}Bus.h similarity index 100% rename from Templates/MinimalProject/Template/Code/Include/${Name}/${Name}Bus.h rename to Templates/MinimalProject/Template/Gem/Include/${Name}/${Name}Bus.h diff --git a/Templates/MinimalProject/Template/Code/Platform/Android/${NameLower}_android_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Android/${NameLower}_android_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Android/${NameLower}_android_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Android/${NameLower}_android_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Android/${NameLower}_shared_android_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Android/${NameLower}_shared_android_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Android/${NameLower}_shared_android_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Android/${NameLower}_shared_android_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Android/PAL_android.cmake b/Templates/MinimalProject/Template/Gem/Platform/Android/PAL_android.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Android/PAL_android.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Android/PAL_android.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Linux/${NameLower}_linux_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Linux/${NameLower}_linux_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Linux/${NameLower}_linux_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Linux/${NameLower}_linux_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Linux/${NameLower}_shared_linux_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Linux/${NameLower}_shared_linux_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Linux/PAL_linux.cmake b/Templates/MinimalProject/Template/Gem/Platform/Linux/PAL_linux.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Linux/PAL_linux.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Linux/PAL_linux.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Mac/${NameLower}_mac_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Mac/${NameLower}_mac_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Mac/${NameLower}_mac_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Mac/${NameLower}_mac_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Mac/${NameLower}_shared_mac_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Mac/${NameLower}_shared_mac_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Mac/PAL_mac.cmake b/Templates/MinimalProject/Template/Gem/Platform/Mac/PAL_mac.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Mac/PAL_mac.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Mac/PAL_mac.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Windows/${NameLower}_shared_windows_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Windows/${NameLower}_shared_windows_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Windows/${NameLower}_windows_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/Windows/${NameLower}_windows_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Windows/${NameLower}_windows_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Windows/${NameLower}_windows_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/Windows/PAL_windows.cmake b/Templates/MinimalProject/Template/Gem/Platform/Windows/PAL_windows.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/Windows/PAL_windows.cmake rename to Templates/MinimalProject/Template/Gem/Platform/Windows/PAL_windows.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/iOS/${NameLower}_ios_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/iOS/${NameLower}_ios_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/iOS/${NameLower}_ios_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/iOS/${NameLower}_ios_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/iOS/${NameLower}_shared_ios_files.cmake b/Templates/MinimalProject/Template/Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/iOS/${NameLower}_shared_ios_files.cmake rename to Templates/MinimalProject/Template/Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake diff --git a/Templates/MinimalProject/Template/Code/Platform/iOS/PAL_ios.cmake b/Templates/MinimalProject/Template/Gem/Platform/iOS/PAL_ios.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/Platform/iOS/PAL_ios.cmake rename to Templates/MinimalProject/Template/Gem/Platform/iOS/PAL_ios.cmake diff --git a/Templates/MinimalProject/Template/Code/Source/${Name}Module.cpp b/Templates/MinimalProject/Template/Gem/Source/${Name}Module.cpp similarity index 100% rename from Templates/MinimalProject/Template/Code/Source/${Name}Module.cpp rename to Templates/MinimalProject/Template/Gem/Source/${Name}Module.cpp diff --git a/Templates/MinimalProject/Template/Code/Source/${Name}SystemComponent.cpp b/Templates/MinimalProject/Template/Gem/Source/${Name}SystemComponent.cpp similarity index 100% rename from Templates/MinimalProject/Template/Code/Source/${Name}SystemComponent.cpp rename to Templates/MinimalProject/Template/Gem/Source/${Name}SystemComponent.cpp diff --git a/Templates/MinimalProject/Template/Code/Source/${Name}SystemComponent.h b/Templates/MinimalProject/Template/Gem/Source/${Name}SystemComponent.h similarity index 100% rename from Templates/MinimalProject/Template/Code/Source/${Name}SystemComponent.h rename to Templates/MinimalProject/Template/Gem/Source/${Name}SystemComponent.h diff --git a/Templates/MinimalProject/Template/Code/enabled_gems.cmake b/Templates/MinimalProject/Template/Gem/enabled_gems.cmake similarity index 100% rename from Templates/MinimalProject/Template/Code/enabled_gems.cmake rename to Templates/MinimalProject/Template/Gem/enabled_gems.cmake diff --git a/Templates/MinimalProject/Template/Gem/gem.json b/Templates/MinimalProject/Template/Gem/gem.json new file mode 100644 index 0000000000..b60f512006 --- /dev/null +++ b/Templates/MinimalProject/Template/Gem/gem.json @@ -0,0 +1,21 @@ +{ + "gem_name": "${Name}", + "display_name": "${Name}", + "license": "What license ${Name} uses goes here: i.e. Apache-2.0 or MIT", + "license_url": "Link to the license web site goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "type": "", + "summary": "A short description of ${Name}.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "${Name}" + ], + "icon_path": "preview.png", + "requirements": "", + "documentation_url": "", + "dependencies": [ + ] +} diff --git a/Templates/MinimalProject/Template/cmake/CompilerSettings.cmake b/Templates/MinimalProject/Template/cmake/CompilerSettings.cmake index 60bda1d45b..4efaecd60f 100644 --- a/Templates/MinimalProject/Template/cmake/CompilerSettings.cmake +++ b/Templates/MinimalProject/Template/cmake/CompilerSettings.cmake @@ -1,10 +1,10 @@ -# +# {BEGIN_LICENSE} # Copyright (c) Contributors to the Open 3D Engine Project. # For complete copyright and license terms please see the LICENSE at the root of this distribution. # # SPDX-License-Identifier: Apache-2.0 OR MIT # -# +# {END_LICENSE} # File to tweak compiler settings before compiler detection happens (before project() is called) # We dont have PAL enabled at this point, so we can only use pure-CMake variables diff --git a/Templates/MinimalProject/Template/cmake/Platform/Linux/CompilerSettings_linux.cmake b/Templates/MinimalProject/Template/cmake/Platform/Linux/CompilerSettings_linux.cmake index 9bb629c53b..386117873f 100644 --- a/Templates/MinimalProject/Template/cmake/Platform/Linux/CompilerSettings_linux.cmake +++ b/Templates/MinimalProject/Template/cmake/Platform/Linux/CompilerSettings_linux.cmake @@ -1,10 +1,10 @@ -# +# {BEGIN_LICENSE} # Copyright (c) Contributors to the Open 3D Engine Project. # For complete copyright and license terms please see the LICENSE at the root of this distribution. # # SPDX-License-Identifier: Apache-2.0 OR MIT # -# +# {END_LICENSE} if(NOT CMAKE_C_COMPILER AND NOT CMAKE_CXX_COMPILER AND NOT "$ENV{CC}" AND NOT "$ENV{CXX}") set(path_search diff --git a/Templates/MinimalProject/Template/project.json b/Templates/MinimalProject/Template/project.json index f8d4643ce9..a303186a64 100644 --- a/Templates/MinimalProject/Template/project.json +++ b/Templates/MinimalProject/Template/project.json @@ -2,7 +2,7 @@ "project_name": "${Name}", "project_id": "${ProjectId}", "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", - "license": "What license ${Name} uses goes here: i.e. https://opensource.org/licenses/MIT", + "license": "What license ${Name} uses goes here: i.e. https://opensource.org/licenses/Apache-2.0 Or https://opensource.org/licenses/MIT etc.", "display_name": "${Name}", "summary": "A short description of ${Name}.", "canonical_tags": [ @@ -13,5 +13,7 @@ ], "icon_path": "preview.png", "engine": "o3de", - "external_subdirectories": [] + "external_subdirectories": [ + "Gem" + ] } diff --git a/Templates/MinimalProject/template.json b/Templates/MinimalProject/template.json index 7d6a4f9b94..4cc3031ff5 100644 --- a/Templates/MinimalProject/template.json +++ b/Templates/MinimalProject/template.json @@ -1,10 +1,18 @@ { "template_name": "MinimalProject", - "origin": "The primary repo for MinimalProject goes here: i.e. http://www.mydomain.com", - "license": "What license MinimalProject uses goes here: i.e. https://opensource.org/licenses/MIT", - "display_name": "Minimal", - "summary": "This will be a good starting point for developers who are looking for building the game with the bare minimum of gems in O3DE, and adding more when needed. ", - "canonical_tags": [], + "template_restricted_platform_relative_path": "Templates/MinimalProject", + "restricted_name": "o3de", + "restricted_platform_relative_path": "Templates/MinimalProject", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "display_name": "Minimal Project Template", + "summary": "Use this project template to create project that is the absolute minimum needed to get started in O3DE.", + "canonical_tags": [ + "Template", + "Project" + ], "user_tags": [ "MinimalProject" ], @@ -12,645 +20,454 @@ "copyFiles": [ { "file": ".gitignore", - "origin": ".gitignore", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/${NameLower}_files.cmake", - "origin": "Code/${NameLower}_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/${NameLower}_shared_files.cmake", - "origin": "Code/${NameLower}_shared_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/CMakeLists.txt", - "origin": "Code/CMakeLists.txt", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/${NameLower}_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_android_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "origin": "Code/Platform/Android/${NameLower}_shared_android_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Android/PAL_android.cmake", - "origin": "Code/Platform/Android/PAL_android.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Linux/PAL_linux.cmake", - "origin": "Code/Platform/Linux/PAL_linux.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Mac/PAL_mac.cmake", - "origin": "Code/Platform/Mac/PAL_mac.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/Windows/PAL_windows.cmake", - "origin": "Code/Platform/Windows/PAL_windows.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_ios_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "origin": "Code/Platform/iOS/${NameLower}_shared_ios_files.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Platform/iOS/PAL_ios.cmake", - "origin": "Code/Platform/iOS/PAL_ios.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}Module.cpp", - "origin": "Code/Source/${Name}Module.cpp", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}SystemComponent.cpp", - "origin": "Code/Source/${Name}SystemComponent.cpp", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/Source/${Name}SystemComponent.h", - "origin": "Code/Source/${Name}SystemComponent.h", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/enabled_gems.cmake", - "origin": "Code/enabled_gems.cmake", - "isTemplated": true, - "isOptional": false - }, - { - "file": "Code/gem.json", - "origin": "Code/gem.json", - "isTemplated": true, - "isOptional": true - }, - { - "file": "Config/shader_global_build_options.json", - "origin": "Config/shader_global_build_options.json", - "isTemplated": false, - "isOptional": false + "isTemplated": true }, { "file": "cmake/EngineFinder.cmake", - "origin": "cmake/EngineFinder.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "cmake/CompilerSettings.cmake", - "origin": "cmake/CompilerSettings.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "cmake/Platform/Linux/CompilerSettings_linux.cmake", - "origin": "cmake/Platform/Linux/CompilerSettings_linux.cmake", - "isTemplated": false, - "isOptional": false + "isTemplated": false + }, + { + "file": "Config/shader_global_build_options.json", + "isTemplated": false + }, + { + "file": "Gem/${NameLower}_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/${NameLower}_shared_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/CMakeLists.txt", + "isTemplated": true + }, + { + "file": "Gem/Include/${Name}/${Name}Bus.h", + "isTemplated": true + }, + { + "file": "Gem/Platform/Android/${NameLower}_android_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Android/${NameLower}_shared_android_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Android/PAL_android.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Linux/${NameLower}_linux_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Linux/${NameLower}_shared_linux_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Linux/PAL_linux.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Mac/${NameLower}_mac_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Mac/${NameLower}_shared_mac_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Mac/PAL_mac.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Windows/${NameLower}_shared_windows_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Windows/${NameLower}_windows_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/Windows/PAL_windows.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/iOS/${NameLower}_ios_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/iOS/${NameLower}_shared_ios_files.cmake", + "isTemplated": true + }, + { + "file": "Gem/Platform/iOS/PAL_ios.cmake", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}Module.cpp", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}SystemComponent.cpp", + "isTemplated": true + }, + { + "file": "Gem/Source/${Name}SystemComponent.h", + "isTemplated": true + }, + { + "file": "Gem/enabled_gems.cmake", + "isTemplated": true + }, + { + "file": "Gem/gem.json", + "isTemplated": true }, { "file": "Platform/Android/android_project.cmake", - "origin": "Platform/Android/android_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Android/android_project.json", - "origin": "Platform/Android/android_project.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Linux/linux_project.cmake", - "origin": "Platform/Linux/linux_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Linux/linux_project.json", - "origin": "Platform/Linux/linux_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Mac/mac_project.cmake", - "origin": "Platform/Mac/mac_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Mac/mac_project.json", - "origin": "Platform/Mac/mac_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/Windows/windows_project.cmake", - "origin": "Platform/Windows/windows_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/Windows/windows_project.json", - "origin": "Platform/Windows/windows_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Platform/iOS/ios_project.cmake", - "origin": "Platform/iOS/ios_project.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Platform/iOS/ios_project.json", - "origin": "Platform/iOS/ios_project.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Registry/assets_scan_folders.setreg", - "origin": "Registry/assets_scan_folders.setreg", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Resources/LegacyLogoLauncher.bmp", - "origin": "Resources/LegacyLogoLauncher.bmp", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/GameSDK.ico", - "origin": "Resources/GameSDK.ico", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/Contents.json", - "origin": "Resources/Platform/Mac/Images.xcassets/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_16_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_32_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512_2x.png", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_512_2x.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/Mac/Info.plist", - "origin": "Resources/Platform/Mac/Info.plist", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Resources/Platform/iOS/Images.xcassets/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/Contents.json", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon152x152.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon152x152.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon76x76.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadAppIcon76x76.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadProAppIcon167x167.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadProAppIcon167x167.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon29x29.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon29x29.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon58x58.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSettingsIcon58x58.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon40x40.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon40x40.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon80x80.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPadSpotlightIcon80x80.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon120x120.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon120x120.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon180x180.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneAppIcon180x180.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon58x58.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon58x58.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon87x87.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSettingsIcon87x87.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon120x120.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon120x120.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon80x80.png", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset/iPhoneSpotlightIcon80x80.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Resources/Platform/iOS/Info.plist", - "origin": "Resources/Platform/iOS/Info.plist", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "ShaderLib/README.md", - "origin": "ShaderLib/README.md", - "isTemplated": false, - "isOptional": true + "isTemplated": false }, { "file": "ShaderLib/scenesrg.srgi", - "origin": "ShaderLib/scenesrg.srgi", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "ShaderLib/viewsrg.srgi", - "origin": "ShaderLib/viewsrg.srgi", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "autoexec.cfg", - "origin": "autoexec.cfg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "game.cfg", - "origin": "game.cfg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "project.json", - "origin": "project.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" }, { - "dir": "Code", - "origin": "Code" + "dir": "cmake" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "cmake/Platform" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "cmake/Platform/Linux" }, { - "dir": "Code/Platform", - "origin": "Code/Platform" + "dir": "Config" }, { - "dir": "Code/Platform/Android", - "origin": "Code/Platform/Android" + "dir": "Gem" }, { - "dir": "Code/Platform/Linux", - "origin": "Code/Platform/Linux" + "dir": "Gem/Include" }, { - "dir": "Code/Platform/Mac", - "origin": "Code/Platform/Mac" + "dir": "Gem/Include/${Name}" }, { - "dir": "Code/Platform/Windows", - "origin": "Code/Platform/Windows" + "dir": "Gem/Platform" }, { - "dir": "Code/Platform/iOS", - "origin": "Code/Platform/iOS" + "dir": "Gem/Platform/Android" }, { - "dir": "Code/Source", - "origin": "Code/Source" + "dir": "Gem/Platform/Linux" }, { - "dir": "Config", - "origin": "Config" + "dir": "Gem/Platform/Mac" }, { - "dir": "Platform", - "origin": "Platform" + "dir": "Gem/Platform/Windows" }, { - "dir": "Platform/Android", - "origin": "Platform/Android" + "dir": "Gem/Platform/iOS" }, { - "dir": "Platform/Linux", - "origin": "Platform/Linux" + "dir": "Gem/Source" }, { - "dir": "Platform/Mac", - "origin": "Platform/Mac" + "dir": "Config" }, { - "dir": "Platform/Windows", - "origin": "Platform/Windows" + "dir": "Platform" }, { - "dir": "Platform/iOS", - "origin": "Platform/iOS" + "dir": "Platform/Android" }, { - "dir": "Registry", - "origin": "Registry" + "dir": "Platform/Linux" }, { - "dir": "Resources", - "origin": "Resources" + "dir": "Platform/Mac" }, { - "dir": "Resources/Platform", - "origin": "Resources/Platform" + "dir": "Platform/Windows" }, { - "dir": "Resources/Platform/Mac", - "origin": "Resources/Platform/Mac" + "dir": "Platform/iOS" }, { - "dir": "Resources/Platform/Mac/Images.xcassets", - "origin": "Resources/Platform/Mac/Images.xcassets" + "dir": "Registry" }, { - "dir": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset", - "origin": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset" + "dir": "Resources" }, { - "dir": "Resources/Platform/iOS", - "origin": "Resources/Platform/iOS" + "dir": "Resources/Platform" }, { - "dir": "Resources/Platform/iOS/Images.xcassets", - "origin": "Resources/Platform/iOS/Images.xcassets" + "dir": "Resources/Platform/Mac" }, { - "dir": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage", - "origin": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage" + "dir": "Resources/Platform/Mac/Images.xcassets" }, { - "dir": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset", - "origin": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset" + "dir": "Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset" }, { - "dir": "ShaderLib", - "origin": "ShaderLib" + "dir": "Resources/Platform/iOS" }, { - "dir": "Shaders", - "origin": "Shaders" + "dir": "Resources/Platform/iOS/Images.xcassets" }, { - "dir": "Shaders/ShaderResourceGroups", - "origin": "Shaders/ShaderResourceGroups" + "dir": "Resources/Platform/iOS/Images.xcassets/LaunchImage.launchimage" + }, + { + "dir": "Resources/Platform/iOS/Images.xcassets/TestDPAppIcon.appiconset" + }, + { + "dir": "ShaderLib" + }, + { + "dir": "Shaders" + }, + { + "dir": "Shaders/ShaderResourceGroups" } ] } diff --git a/Templates/PythonToolGem/Template/gem.json b/Templates/PythonToolGem/Template/gem.json index 84f5b65a3e..3164c7b5b8 100644 --- a/Templates/PythonToolGem/Template/gem.json +++ b/Templates/PythonToolGem/Template/gem.json @@ -2,8 +2,9 @@ "gem_name": "${Name}", "display_name": "${Name}", "license": "What license ${Name} uses goes here: i.e. Apache-2.0 Or MIT", - "license_url": "", - "origin": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "origin": "The name of the originator goes here. i.e. XYZ Inc.", + "origin_url": "The primary repo for ${Name} goes here: i.e. http://www.mydomain.com", "type": "Code", "summary": "A short description of ${Name}.", "canonical_tags": [ @@ -14,6 +15,7 @@ ], "icon_path": "preview.png", "requirements": "", + "documentation_url": "", "dependencies": [ "QtForPython" ] diff --git a/Templates/PythonToolGem/template.json b/Templates/PythonToolGem/template.json index 6dc68de3fc..3af74eb49f 100644 --- a/Templates/PythonToolGem/template.json +++ b/Templates/PythonToolGem/template.json @@ -1,12 +1,18 @@ { "template_name": "PythonToolGem", + "template_restricted_platform_relative_path": "Templates/PythonToolGem", "restricted_name": "o3de", - "restricted_platform_relative_path": "Templates", - "origin": "The primary repo for PythonToolGem goes here: i.e. http://www.mydomain.com", - "license": "What license PythonToolGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "restricted_platform_relative_path": "Templates/PythonToolGem", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "display_name": "PythonToolGem", "summary": "A gem template for a custom tool in Python that gets registered with the Editor.", - "canonical_tags": [], + "canonical_tags": [ + "Python", + "Gem" + ], "user_tags": [ "PythonToolGem" ], @@ -14,221 +20,153 @@ "copyFiles": [ { "file": ".gitignore", - "origin": ".gitignore", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_files.cmake", - "origin": "Code/${NameLower}_editor_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_shared_files.cmake", - "origin": "Code/${NameLower}_editor_shared_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/${NameLower}_editor_tests_files.cmake", - "origin": "Code/${NameLower}_editor_tests_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/CMakeLists.txt", - "origin": "Code/CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "origin": "Code/Platform/Linux/${NameLower}_shared_linux_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Linux/PAL_linux.cmake", - "origin": "Code/Platform/Linux/PAL_linux.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "origin": "Code/Platform/Mac/${NameLower}_shared_mac_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Mac/PAL_mac.cmake", - "origin": "Code/Platform/Mac/PAL_mac.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_shared_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "origin": "Code/Platform/Windows/${NameLower}_windows_files.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Platform/Windows/PAL_windows.cmake", - "origin": "Code/Platform/Windows/PAL_windows.cmake", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}.qrc", - "origin": "Code/Source/${Name}.qrc", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorModule.cpp", - "origin": "Code/Source/${Name}EditorModule.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.cpp", - "origin": "Code/Source/${Name}EditorSystemComponent.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}EditorSystemComponent.h", - "origin": "Code/Source/${Name}EditorSystemComponent.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/${Name}ModuleInterface.h", - "origin": "Code/Source/${Name}ModuleInterface.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Code/Source/toolbar_icon.svg", - "origin": "Code/Source/toolbar_icon.svg", - "isTemplated": false, - "isOptional": false + "isTemplated": false }, { "file": "Code/Tests/${Name}EditorTest.cpp", - "origin": "Code/Tests/${Name}EditorTest.cpp", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Editor/Scripts/__init__.py", - "origin": "Editor/Scripts/__init__.py", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Editor/Scripts/bootstrap.py", - "origin": "Editor/Scripts/bootstrap.py", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "Editor/Scripts/${NameLower}_dialog.py", - "origin": "Editor/Scripts/${NameLower}_dialog.py", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" }, { - "dir": "Code", - "origin": "Code" + "dir": "Code" }, { - "dir": "Editor", - "origin": "Editor" + "dir": "Editor" }, { - "dir": "Editor/Scripts", - "origin": "Editor/Scripts" + "dir": "Editor/Scripts" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "Code/Include" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "Code/Include/${Name}" }, { - "dir": "Code/Platform", - "origin": "Code/Platform" + "dir": "Code/Platform" }, { - "dir": "Code/Platform/Linux", - "origin": "Code/Platform/Linux" + "dir": "Code/Platform/Linux" }, { - "dir": "Code/Platform/Mac", - "origin": "Code/Platform/Mac" + "dir": "Code/Platform/Mac" }, { - "dir": "Code/Platform/Windows", - "origin": "Code/Platform/Windows" + "dir": "Code/Platform/Windows" }, { - "dir": "Code/Source", - "origin": "Code/Source" + "dir": "Code/Source" }, { - "dir": "Code/Tests", - "origin": "Code/Tests" + "dir": "Code/Tests" } ] } diff --git a/cmake/3rdParty.cmake b/cmake/3rdParty.cmake index 7d98c3ea3e..1bea5f4f67 100644 --- a/cmake/3rdParty.cmake +++ b/cmake/3rdParty.cmake @@ -186,7 +186,7 @@ function(ly_add_external_target) endif() # Check if there is a pal file - ly_get_absolute_pal_filename(pal_file ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/${ly_add_external_target_PACKAGE}_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + o3de_pal_dir(pal_file ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/${ly_add_external_target_PACKAGE}_${PAL_PLATFORM_NAME_LOWERCASE}.cmake ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) if(NOT EXISTS ${pal_file}) set(pal_file ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/${ly_add_external_target_PACKAGE}_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) endif() @@ -357,12 +357,12 @@ endfunction() # Add the 3rdParty folder to find the modules list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/3rdParty) -ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/3rdParty/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/3rdParty/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) list(APPEND CMAKE_MODULE_PATH ${pal_dir}) if(NOT INSTALLED_ENGINE) # Add the 3rdParty cmake files to the IDE ly_include_cmake_file_list(cmake/3rdParty/cmake_files.cmake) - ly_get_absolute_pal_filename(pal_3rdparty_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdParty/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(pal_3rdparty_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdParty/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) ly_include_cmake_file_list(${pal_3rdparty_dir}/cmake_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake) endif() diff --git a/cmake/3rdParty/BuiltInPackages.cmake b/cmake/3rdParty/BuiltInPackages.cmake index 743e2e983e..e81cfffe01 100644 --- a/cmake/3rdParty/BuiltInPackages.cmake +++ b/cmake/3rdParty/BuiltInPackages.cmake @@ -12,9 +12,9 @@ # cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake #include the platform-specific 3rd party packages. -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) -set(LY_PAL_PACKAGE_FILE_NAME ${CMAKE_CURRENT_LIST_DIR}/${pal_dir}/BuiltInPackages_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) +set(LY_PAL_PACKAGE_FILE_NAME ${pal_dir}/BuiltInPackages_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) include(${LY_PAL_PACKAGE_FILE_NAME}) # add the above file to the ALLFILES list, so that they show up in IDEs diff --git a/cmake/3rdPartyPackages.cmake b/cmake/3rdPartyPackages.cmake index a3f15bdb22..f9a72672c0 100644 --- a/cmake/3rdPartyPackages.cmake +++ b/cmake/3rdPartyPackages.cmake @@ -614,7 +614,7 @@ endfunction() # and ensure the path to the package root is added to the find_package search paths. # For example # ly_associate_package(TARGETS zlib PACKAGE_NAME zlib-1.2.8-multiplatform PACKAGE_HASH e6f34b8ac16acf881e3d666ef9fd0c1aee94c3f69283fb6524d35d6f858eebbb) -# - this waill cause it to automatically download and activate this package if it finds a target that +# - this will cause it to automatically download and activate this package if it finds a target that # depends on '3rdParty::zlib' in its runtime or its build time dependency list. # - note that '3rdParty' is implied, do not specify it in the TARGETS list. function(ly_associate_package) @@ -684,6 +684,7 @@ endmacro() # is associated with a package, as above. If it is, it makes sure that the package # is brought into scope (and if necessary, downloaded.) macro(ly_download_associated_package find_library_name) + unset(package_name) ly_get_package_association(${find_library_name} package_name) if (package_name) # it is an associated package. diff --git a/cmake/Configurations.cmake b/cmake/Configurations.cmake index 51dee2f07b..709c81e3d2 100644 --- a/cmake/Configurations.cmake +++ b/cmake/Configurations.cmake @@ -189,5 +189,5 @@ foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES) endforeach() # flags are defined per platform, follow platform files under Platform//Configurations_.cmake -ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/Configurations_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/cmake/FileUtil.cmake b/cmake/FileUtil.cmake index 4607e14452..5721cf452c 100644 --- a/cmake/FileUtil.cmake +++ b/cmake/FileUtil.cmake @@ -26,8 +26,16 @@ function(ly_include_cmake_file_list file) include(${file}) get_filename_component(file_path "${file}" PATH) if(file_path) - list(TRANSFORM FILES PREPEND ${file_path}/) + foreach(f ${FILES}) + cmake_path(IS_RELATIVE f is_relative) + if(is_relative) + string(PREPEND f ${file_path}/) + endif() + list(APPEND TRANSFORMED_FILES ${f}) + endforeach() + set(FILES ${TRANSFORMED_FILES}) endif() + foreach(f ${FILES}) get_filename_component(absolute_path ${f} ABSOLUTE) if(NOT EXISTS ${absolute_path}) @@ -41,12 +49,19 @@ function(ly_include_cmake_file_list file) list(APPEND UNITY_AUTO_EXCLUSIONS ${f}) endif() endif() - endforeach() + list(APPEND FILES ${file}) # Add the _files.cmake to the list so it shows in the IDE if(file_path) - list(TRANSFORM SKIP_UNITY_BUILD_INCLUSION_FILES PREPEND ${file_path}/) + foreach(f ${SKIP_UNITY_BUILD_INCLUSION_FILES}) + cmake_path(IS_RELATIVE f is_relative) + if(is_relative) + string(PREPEND f ${file_path}/) + endif() + list(APPEND SKIP_UNITY_BUILD_INCLUSION_TRANSFORMED_FILES ${f}) + endforeach() + set(SKIP_UNITY_BUILD_INCLUSION_FILES ${SKIP_UNITY_BUILD_INCLUSION_TRANSFORMED_FILES}) endif() # Check if there are any files to exclude from unity groupings diff --git a/cmake/Install.cmake b/cmake/Install.cmake index b558590b9e..55f56b05e8 100644 --- a/cmake/Install.cmake +++ b/cmake/Install.cmake @@ -30,7 +30,7 @@ function(ly_install) install(CODE "endif()\n" ALL_COMPONENTS) else() install(${ARGN}) - endif() + endif() endfunction() @@ -195,6 +195,6 @@ function(ly_install_run_script SCRIPT) endfunction() if(LY_INSTALL_ENABLED) - ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) + o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/Install_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) endif() diff --git a/cmake/LYTestWrappers.cmake b/cmake/LYTestWrappers.cmake index 03146b6045..9f4cd41a47 100644 --- a/cmake/LYTestWrappers.cmake +++ b/cmake/LYTestWrappers.cmake @@ -141,7 +141,7 @@ function(ly_add_test) set(wrapper_file ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/LYTestWrappers_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) if(NOT EXISTS ${wrapper_file}) - ly_get_absolute_pal_filename(wrapper_file ${wrapper_file}) + o3de_pal_dir(wrapper_file ${wrapper_file} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) endif() include(${wrapper_file}) diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake index d4bf1d7423..a2f4359fd5 100644 --- a/cmake/LYWrappers.cmake +++ b/cmake/LYWrappers.cmake @@ -11,7 +11,7 @@ set(LY_UNITY_BUILD ON CACHE BOOL "UNITY builds") include(CMakeFindDependencyMacro) include(cmake/LyAutoGen.cmake) -ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/LYWrappers_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # Not all platforms support unity builds diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index 67ed17b6d4..d0d1ad5396 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -15,67 +15,205 @@ # PAL_PLATFORM_NAME_LOWERCASE: name of the platform in lower case (part of filenames) # -file(GLOB detection_files "cmake/Platform/*/PALDetection_*.cmake") -foreach(detection_file ${detection_files}) - include(${detection_file}) -endforeach() - - -#! o3de_restricted_id: Reads the "restricted" key from the o3de manifest +#! o3de_get_home_path: returns the home path # -# \arg:o3de_json_file name of the o3de json file to read the "restricted_name" key from -# \arg:restricted returns the restricted association element from an o3de json, otherwise engine 'o3de' is assumed -# \arg:o3de_json_file name of the o3de json file -function(o3de_restricted_id o3de_json_file restricted) - ly_file_read(${o3de_json_file} json_data) - string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted_name") +# \arg:o3de_manifest_path returns the path of the manifest +function(o3de_get_home_path o3de_home_path) + # The o3de_manifest.json is in the home directory / .o3de folder + file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_path) # Windows + if(NOT EXISTS ${home_path}) + file(TO_CMAKE_PATH "$ENV{HOME}" home_path) # Unix + if (NOT EXISTS ${home_path}) + message(FATAL_ERROR "o3de Home path not found") + endif() + endif() + set(${o3de_home_path} ${home_path} PARENT_SCOPE) +endfunction() + +#! o3de_get_manifest_path: returns the path to the manifest +# +# \arg:o3de_manifest_path returns the path of the manifest +function(o3de_get_manifest_path o3de_manifest_path) + # The o3de_manifest.json is in the home directory / .o3de folder + o3de_get_home_path(o3de_home_path) + set(${o3de_manifest_path} ${o3de_home_path}/.o3de/o3de_manifest.json PARENT_SCOPE) +endfunction() + +#! o3de_read_manifest: returns the contents of the manifest +# +# \arg:restricted_subdirs returns the restricted elements from the manifest +function(o3de_read_manifest o3de_manifest_json_data) + #get the manifest path + o3de_get_manifest_path(o3de_manifest_path) + if(EXISTS ${o3de_manifest_path}) + ly_file_read(${o3de_manifest_path} json_data) + set(${o3de_manifest_json_data} ${json_data} PARENT_SCOPE) + endif() +endfunction() + +#! o3de_recurse_gems: returns the gem paths +# +# \arg:object json path +# \arg:gems returns the gems from the external subdirectory elements from the manifest +function(o3de_recurse_gems object_json_path gems) + get_filename_component(object_json_parent_path ${object_json_path} DIRECTORY) + ly_file_read(${object_json_path} json_data) + string(JSON external_subdirectories_count ERROR_VARIABLE json_error LENGTH ${json_data} "external_subdirectories") + if(NOT json_error) + if(external_subdirectories_count GREATER 0) + math(EXPR external_subdirectories_range "${external_subdirectories_count}-1") + foreach(external_subdirectories_index RANGE ${external_subdirectories_range}) + string(JSON external_subdirectories_entry ERROR_VARIABLE json_error GET ${json_data} "external_subdirectories" "${external_subdirectories_index}") + cmake_path(IS_RELATIVE external_subdirectories_entry is_relative) + if(${is_relative}) + cmake_path(ABSOLUTE_PATH external_subdirectories_entry BASE_DIRECTORY ${object_json_parent_path} NORMALIZE OUTPUT_VARIABLE external_subdirectories_entry) + endif() + if(EXISTS ${external_subdirectories_entry}/gem.json) + list(APPEND gem_entries ${external_subdirectories_entry}) + o3de_recurse_gems(${external_subdirectories_entry}/gem.json gem_entries) + endif() + endforeach() + endif() + endif() + set(${gems} ${gem_entries} PARENT_SCOPE) +endfunction() + +#! o3de_find_gem: returns the gem path +# +# \arg:gem_name the gem name to find +# \arg:the path of the gem +function(o3de_find_gem gem_name gem_path) + o3de_get_manifest_path(manifest_path) + if(EXISTS ${manifest_path}) + o3de_recurse_gems(${manifest_path} gems) + endif() + o3de_recurse_gems(${LY_ROOT_FOLDER}/engine.json gems) + foreach(gem ${gems}) + ly_file_read(${gem}/gem.json json_data) + string(JSON gem_json_name ERROR_VARIABLE json_error GET ${json_data} "gem_name") + if(gem_json_name STREQUAL gem_name) + set(${gem_path} ${gem} PARENT_SCOPE) + return() + endif() + endforeach() +endfunction() + +#! o3de_manifest_restricted: returns the manifests restricted paths +# +# \arg:restricted returns the restricted elements from the manifest +function(o3de_manifest_restricted restricted) + #read the manifest + o3de_read_manifest(o3de_manifest_json_data) + string(JSON restricted_count ERROR_VARIABLE json_error LENGTH ${o3de_manifest_json_data} "restricted") if(json_error) # Restricted fields can never be a requirement so no warning is issued return() endif() - if(restricted_entry) - set(${restricted} ${restricted_entry} PARENT_SCOPE) + if(restricted_count GREATER 0) + math(EXPR restricted_range "${restricted_count}-1") + foreach(restricted_index RANGE ${restricted_range}) + string(JSON restricted_entry ERROR_VARIABLE json_error GET ${o3de_manifest_json_data} "restricted" "${restricted_index}") + list(APPEND restricted_entries ${restricted_entry}) + endforeach() endif() + set(${restricted} ${restricted_entries} PARENT_SCOPE) +endfunction() + +#! o3de_json_restricted: returns the restricted element from a json +# +# \arg:restricted returns the restricted element of the json +function(o3de_json_restricted json_path restricted) + if(EXISTS ${json_path}) + ly_file_read(${json_path} json_data) + string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted") + if(json_error) + # Restricted fields can never be a requirement so no warning is issued + return() + endif() + set(${restricted} ${restricted_entry} PARENT_SCOPE) + endif() +endfunction() + +#! o3de_restricted_id: determines the restricted object for this json +# +# Find this objects restricted name. If the object has a "restricted" element +# If it does not have one it inherits its parents "restricted" element if it has one +# If the parent does not have one it inherits its parents parent "restricted" element is it has one and so on... +# We stop looking if the object or parent is in the manifest, as the manifest only has top level objects +# which means they have no children. +# +# \arg:o3de_json_file name of the o3de json file to read the "restricted" key from +# \arg:restricted returns the restricted association element from an o3de json, otherwise its doesnt change anything +# \arg:o3de_json_file name of the o3de json file +function(o3de_restricted_id o3de_json_file restricted parent_relative_path) + # read the passed in o3de json and see if "restricted" is set + o3de_json_restricted(${o3de_json_file} restricted_name) + if(restricted_name) + set(${parent_relative_path} "" PARENT_SCOPE) + set(${restricted} ${restricted_name} PARENT_SCOPE) + return() + endif() + + # This object did not have a "restricted" set, now we must look at the parent + # Stop if this is a top level object + o3de_manifest_restricted(manifest_restricted_paths) + get_filename_component(o3de_json_file_parent ${o3de_json_file} DIRECTORY) + get_filename_component(relative_path ${o3de_json_file_parent} NAME) + get_filename_component(o3de_json_file_parent ${o3de_json_file_parent} DIRECTORY) + if(${o3de_json_file_parent} IN_LIST manifest_restricted_paths) + set(${parent_relative_path} "" PARENT_SCOPE) + set(${restricted} "" PARENT_SCOPE) + return() + endif() + + string(LENGTH ${o3de_json_file_parent} parent_len) + while(parent_len) + if(EXISTS ${o3de_json_file_parent}/engine.json) + o3de_json_restricted(${o3de_json_file_parent}/engine.json restricted_name) + if(restricted_name) + set(${parent_relative_path} ${relative_path} PARENT_SCOPE) + set(${restricted} ${restricted_name} PARENT_SCOPE) + return() + endif() + endif() + if(EXISTS ${o3de_json_file_parent}/project.json) + o3de_json_restricted(${o3de_json_file_parent}/project.json restricted_name) + if(restricted_name) + set(${parent_relative_path} ${relative_path} PARENT_SCOPE) + set(${restricted} ${restricted_name} PARENT_SCOPE) + return() + endif() + endif() + if(EXISTS ${o3de_json_file_parent}/gem.json) + o3de_json_restricted(${o3de_json_file_parent}/gem.json restricted_name) + if(restricted_name) + set(${parent_relative_path} ${relative_path} PARENT_SCOPE) + set(${restricted} ${restricted_name} PARENT_SCOPE) + return() + endif() + endif() + + if(${o3de_json_file_parent} IN_LIST manifest_restricted_paths) + set(${parent_relative_path} "" PARENT_SCOPE) + set(${restricted} "" PARENT_SCOPE) + return() + endif() + + get_filename_component(parent ${o3de_json_file_parent} NAME) + string(PREPEND relative_path ${parent}/) + get_filename_component(o3de_json_file_parent ${o3de_json_file_parent} DIRECTORY) + string(LENGTH ${o3de_json_file_parent} parent_len) + endwhile() endfunction() #! o3de_find_restricted_folder: # -# \arg:restricted_path returns the path of the o3de restricted folder with name restricted_name +# \arg:restricted_path returns the path of the o3de restricted folder using the restricted_name # \arg:restricted_name name of the restricted function(o3de_find_restricted_folder restricted_name restricted_path) - # Read the restricted path from engine.json if one EXISTS - ly_file_read(${LY_ROOT_FOLDER}/engine.json engine_json_data) - string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${engine_json_data} "restricted") - if(restricted_subdirs_count GREATER 0) - string(JSON restricted_subdir ERROR_VARIABLE engine_json_error GET ${engine_json_data} "restricted" "0") - set(${restricted_path} ${restricted_subdir} PARENT_SCOPE) - return() - endif() - - - file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory) # Windows - if(NOT EXISTS ${home_directory}) - file(TO_CMAKE_PATH "$ENV{HOME}" home_directory) # Unix - if (NOT EXISTS ${home_directory}) - return() - endif() - endif() - - # Examine the o3de manifest file for the list of restricted directories - set(o3de_manifest_path ${home_directory}/.o3de/o3de_manifest.json) - if(EXISTS ${o3de_manifest_path}) - ly_file_read(${o3de_manifest_path} o3de_manifest_json_data) - string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${o3de_manifest_json_data} "restricted") - if(restricted_subdirs_count GREATER 0) - math(EXPR restricted_subdirs_range "${restricted_subdirs_count}-1") - foreach(restricted_subdir_index RANGE ${restricted_subdirs_range}) - string(JSON restricted_subdir ERROR_VARIABLE engine_json_error GET ${o3de_manifest_json_data} "restricted" "${restricted_subdir_index}") - list(APPEND restricted_subdirs ${restricted_subdir}) - endforeach() - endif() - endif() + o3de_manifest_restricted(restricted_entries) # Iterate over the restricted directories from the manifest file - foreach(restricted_entry ${restricted_subdirs}) + foreach(restricted_entry ${restricted_entries}) set(restricted_json_file ${restricted_entry}/restricted.json) ly_file_read(${restricted_json_file} restricted_json) string(JSON this_restricted_name ERROR_VARIABLE json_error GET ${restricted_json} "restricted_name") @@ -95,30 +233,30 @@ endfunction() # # \arg:o3de_json_file json file to read restricted id from # \arg:restricted_name name of the restricted object -function(o3de_restricted_path o3de_json_file restricted_path) - o3de_restricted_id(${o3de_json_file} restricted_name) +function(o3de_restricted_path o3de_json_file restricted_path parent_relative_path) + o3de_restricted_id(${o3de_json_file} restricted_name parent_relative) + set(${parent_relative_path} ${parent_relative} PARENT_SCOPE) if(restricted_name) o3de_find_restricted_folder(${restricted_name} restricted_folder) if(restricted_folder) set(${restricted_path} ${restricted_folder} PARENT_SCOPE) + else() + get_filename_component(o3de_json_file_parent ${o3de_json_file} DIRECTORY) + set(${restricted_path} ${o3de_json_file_parent}/restricted PARENT_SCOPE) endif() endif() endfunction() -#! read_engine_restricted_path: Locates the restricted path within the engine from a json file -# -# \arg:output_restricted_path returns the path of the o3de restricted folder with name restricted_name -function(read_engine_restricted_path output_restricted_path) - # Set manifest path to path in the user home directory - set(manifest_path ${LY_ROOT_FOLDER}/engine.json) - if(EXISTS ${manifest_path}) - o3de_restricted_path(${manifest_path} read_restricted_path) - set(${output_restricted_path} ${read_restricted_path} PARENT_SCOPE) - endif() -endfunction() +# detect open platforms +file(GLOB detection_files "cmake/Platform/*/PALDetection_*.cmake") +foreach(detection_file ${detection_files}) + include(${detection_file}) +endforeach() -read_engine_restricted_path(O3DE_ENGINE_RESTRICTED_PATH) +# set the O3DE_ENGINE_RESTRICTED_PATH +o3de_restricted_path(${LY_ROOT_FOLDER}/engine.json O3DE_ENGINE_RESTRICTED_PATH engine_has_no_parent) +# detect platforms in the restricted path file(GLOB detection_files ${O3DE_ENGINE_RESTRICTED_PATH}/*/cmake/PALDetection_*.cmake) foreach(detection_file ${detection_files}) include(${detection_file}) @@ -146,21 +284,16 @@ foreach(pal_restricted_file ${pal_restricted_files}) string(TOLOWER ${platform} platform_lower) list(APPEND PAL_RESTRICTED_PLATFORMS ${platform_lower}) endforeach() +list(REMOVE_DUPLICATES PAL_RESTRICTED_PLATFORMS) + ly_set(PAL_RESTRICTED_PLATFORMS ${PAL_RESTRICTED_PLATFORMS}) function(ly_get_absolute_pal_filename out_name in_name) - set(full_name ${in_name}) + message(DEPRECATION "ly_get_list_relative_pal_filename is being deprecated, change your code to use o3de_pal_dir instead.") + # parent relative path is optional if(${ARGC} GREATER 4) - # The object name is used to resolve ambiguities when a PAL directory is requested from - # two different external subdirectory root paths - # Such as if a PAL directory for two root object paths with same relative structure was requested to be Palified - # i.e /Platform//IO and /Platform//IO - # Normally the restricted PAL path for both gems would be "//IO". - # The object name can be used to make this path unique - # "///IO" for gem 1 and - # "///IO" for gem 2 - set(object_name ${ARGV4}) + set(parent_relative_path ${ARGV4}) endif() # The Default object path for path is the LY_ROOT_FOLDER @@ -170,14 +303,30 @@ function(ly_get_absolute_pal_filename out_name in_name) cmake_path(SET object_path NORMALIZE ${ARGV3}) endif() - # The Default restricted object path is the result of the read_engine_restricted_path function + # The default restricted object path is O3DE_ENGINE_RESTRICTED_PATH cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") if(${ARGC} GREATER 2) # The user has supplied an object restricted path cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) endif() - # The input path must exist in order to form a PAL path + if(${ARGC} GREATER 4) + o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path} ${parent_relative_path}) + else() + o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path}) + endif() + set(${out_name} ${abs_name} PARENT_SCOPE) +endfunction() + +function(o3de_pal_dir out_name in_name object_restricted_path object_path) #parent_relative_path) + set(full_name ${in_name}) + + # parent relative path is optional + if(${ARGC} GREATER 4) + set(parent_relative_path ${ARGV4}) + endif() + + # The input path must not exist in order to form a restricted PAL path if (NOT EXISTS ${full_name}) # if the file is not in the object path then we cannot determine a PAL file for it cmake_path(IS_PREFIX object_path ${full_name} is_input_path_in_root) @@ -222,7 +371,7 @@ function(ly_get_absolute_pal_filename out_name in_name) if(NOT EXISTS ${candidate_PAL_path}) string(TOLOWER ${candidate_platform_name} candidate_platform_name_lower) if("${candidate_platform_name_lower}" IN_LIST PAL_RESTRICTED_PLATFORMS) - cmake_path(APPEND object_restricted_path ${candidate_platform_name} ${object_name} + cmake_path(APPEND object_restricted_path ${candidate_platform_name} ${parent_relative_path} ${pre_platform_paths} OUTPUT_VARIABLE candidate_PAL_path) endif() endif() @@ -236,17 +385,43 @@ function(ly_get_absolute_pal_filename out_name in_name) endfunction() function(ly_get_list_relative_pal_filename out_name in_name) - ly_get_absolute_pal_filename(abs_name ${in_name} ${ARGN}) + message(DEPRECATION "ly_get_list_relative_pal_filename is being deprecated, change your code to use o3de_pal_dir instead.") + + # parent relative path is optional + if(${ARGC} GREATER 4) + set(parent_relative_path ${ARGV4}) + endif() + + # The Default object path for path is the LY_ROOT_FOLDER + cmake_path(SET object_path NORMALIZE "${LY_ROOT_FOLDER}") + if(${ARGC} GREATER 3) + # The user has supplied an object restricted path, the object path for consideration + cmake_path(SET object_path NORMALIZE ${ARGV3}) + endif() + + # The default restricted object path is O3DE_ENGINE_RESTRICTED_PATH + cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") + if(${ARGC} GREATER 2) + # The user has supplied an object restricted path + cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + endif() + + if(${ARGC} GREATER 4) + o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path} ${parent_relative_path}) + else() + o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path}) + endif() + cmake_path(RELATIVE_PATH abs_name BASE_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE relative_name) set(${out_name} ${relative_name} PARENT_SCOPE) endfunction() -ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_cmake_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) -ly_include_cmake_file_list(${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake) +ly_include_cmake_file_list(${pal_cmake_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake) -include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) -include(${pal_dir}/Toolchain_${PAL_PLATFORM_NAME_LOWERCASE}.cmake OPTIONAL) +include(${pal_cmake_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) +include(${pal_cmake_dir}/Toolchain_${PAL_PLATFORM_NAME_LOWERCASE}.cmake OPTIONAL) set(LY_DISABLE_TEST_MODULES FALSE CACHE BOOL "Option to forcibly disable the inclusion of test targets in the build") diff --git a/cmake/PALTools.cmake b/cmake/PALTools.cmake index 2204abf5ae..88e827f9c2 100644 --- a/cmake/PALTools.cmake +++ b/cmake/PALTools.cmake @@ -35,14 +35,14 @@ ly_set(LY_PAL_TOOLS_DEFINES ${LY_PAL_TOOLS_DEFINES}) # Include files to the CMakeFiles project foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${enabled_platform}) + o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${enabled_platform}) ly_include_cmake_file_list(${pal_dir}/pal_tools_${enabled_platform_lowercase}_files.cmake) endforeach() function(ly_get_pal_tool_dirs out_list pal_path) set(pal_paths "") foreach(platform ${LY_PAL_TOOLS_ENABLED}) - ly_get_absolute_pal_filename(path ${pal_path}/${platform}) + o3d_pal_dir(path ${pal_path}/${platform} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) list(APPEND pal_paths ${path}) endforeach() set(${out_list} ${pal_paths} PARENT_SCOPE) diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake index ecef5261b1..81409369dc 100644 --- a/cmake/Packaging.cmake +++ b/cmake/Packaging.cmake @@ -73,7 +73,7 @@ set(CPACK_PROJECT_CONFIG_FILE ${CPACK_SOURCE_DIR}/PackagingConfig.cmake) set(CPACK_AUTO_GEN_TAG ${LY_INSTALLER_AUTO_GEN_TAG}) # attempt to apply platform specific settings -ly_get_absolute_pal_filename(pal_dir ${CPACK_SOURCE_DIR}/Platform/${PAL_HOST_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CPACK_SOURCE_DIR}/Platform/${PAL_HOST_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/Packaging_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake) # if we get here and the generator hasn't been set, then a non fatal error occurred disabling packaging support diff --git a/cmake/Projects.cmake b/cmake/Projects.cmake index 13161c9e0f..c6aa6c382a 100644 --- a/cmake/Projects.cmake +++ b/cmake/Projects.cmake @@ -118,17 +118,27 @@ function(ly_generate_project_build_path_setreg project_real_path) file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content}) endfunction() +function(add_gem_json_external_subdirectories gem_path) + set(gem_json_path ${gem_path}/gem.json) + if(EXISTS ${gem_json_path}) + read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json) + foreach(gem_external_subdir ${gem_external_subdirs}) + file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path}) + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) + add_gem_json_external_subdirectories(${real_external_subdir}) + endforeach() + endif() +endfunction() function(add_project_json_external_subdirectories project_path) set(project_json_path ${project_path}/project.json) if(EXISTS ${project_json_path}) - read_json_external_subdirs(external_subdirs ${project_path}/project.json) - foreach(external_subdir ${external_subdirs}) - file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${project_path}) - list(APPEND project_external_subdirs ${real_external_subdir}) + read_json_external_subdirs(project_external_subdirs ${project_path}/project.json) + foreach(project_external_subdir ${project_external_subdirs}) + file(REAL_PATH ${project_external_subdir} real_external_subdir BASE_DIRECTORY ${project_path}) + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir}) + add_gem_json_external_subdirectories(${real_external_subdir}) endforeach() - - set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${project_external_subdirs}) endif() endfunction() diff --git a/cmake/RuntimeDependencies.cmake b/cmake/RuntimeDependencies.cmake index 9cc7315b08..d36789791f 100644 --- a/cmake/RuntimeDependencies.cmake +++ b/cmake/RuntimeDependencies.cmake @@ -6,6 +6,6 @@ # # -ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/RuntimeDependencies_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) diff --git a/engine.json b/engine.json index 737ac24fea..51b6738001 100644 --- a/engine.json +++ b/engine.json @@ -1,6 +1,6 @@ { "engine_name": "o3de", - "restricted_name": "o3de", + "restricted": "o3de", "FileVersion": 1, "O3DEVersion": "0.0.0.0", "O3DECopyrightYear": 2021, diff --git a/scripts/o3de/CMakeLists.txt b/scripts/o3de/CMakeLists.txt index 79836305c0..fced0f7727 100644 --- a/scripts/o3de/CMakeLists.txt +++ b/scripts/o3de/CMakeLists.txt @@ -8,7 +8,7 @@ add_subdirectory(tests) -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER}) include(${pal_dir}/o3de_install_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) ly_install_files(FILES ../o3de.py diff --git a/scripts/o3de/o3de/disable_gem.py b/scripts/o3de/o3de/disable_gem.py index 0b0e465d12..eecc765d32 100644 --- a/scripts/o3de/o3de/disable_gem.py +++ b/scripts/o3de/o3de/disable_gem.py @@ -98,9 +98,6 @@ def disable_gem_in_project(gem_name: str = None, def _run_disable_gem_in_project(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - return disable_gem_in_project(args.gem_name, args.gem_path, args.project_name, @@ -133,9 +130,6 @@ def add_parser_args(parser): help='The cmake enabled gem file in which gem names are to be removed from.' 'If not specified it will assume ') - parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False, - help='By default the home folder is the user folder, override it to this folder.') - parser.set_defaults(func=_run_disable_gem_in_project) diff --git a/scripts/o3de/o3de/download.py b/scripts/o3de/o3de/download.py index 8e28561e50..a7d5b56440 100644 --- a/scripts/o3de/o3de/download.py +++ b/scripts/o3de/o3de/download.py @@ -277,9 +277,6 @@ def is_o3de_restricted_update_available(restricted_name: str, local_last_updated return is_o3de_object_update_available(restricted_name, 'restricted_name', local_last_updated) def _run_download(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - if args.engine_name: return download_engine(args.engine_name, args.dest_path, @@ -331,8 +328,6 @@ def add_parser_args(parser): parser.add_argument('-f', '--force', action='store_true', required=False, default=False, help = 'Force overwrite the current object') - parser.add_argument('-ohf', '--override-home-folder', type=str, required=False, - help='By default the home folder is the user folder, override it to this folder.') parser.set_defaults(func=_run_download) diff --git a/scripts/o3de/o3de/enable_gem.py b/scripts/o3de/o3de/enable_gem.py index fc4dc6e9cf..ea79f6c73f 100644 --- a/scripts/o3de/o3de/enable_gem.py +++ b/scripts/o3de/o3de/enable_gem.py @@ -115,9 +115,6 @@ def enable_gem_in_project(gem_name: str = None, def _run_enable_gem_in_project(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - return enable_gem_in_project(args.gem_name, args.gem_path, args.project_name, @@ -150,9 +147,6 @@ def add_parser_args(parser): help='The cmake enabled_gem file in which the gem names are specified.' 'If not specified it will assume enabled_gems.cmake') - parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False, - help='By default the home folder is the user folder, override it to this folder.') - parser.set_defaults(func=_run_enable_gem_in_project) diff --git a/scripts/o3de/o3de/engine_template.py b/scripts/o3de/o3de/engine_template.py index 6b2e098cf0..d9993fb5d0 100755 --- a/scripts/o3de/o3de/engine_template.py +++ b/scripts/o3de/o3de/engine_template.py @@ -80,10 +80,20 @@ restricted_platforms = { 'Provo', 'Salem', 'Jasper', - 'Paris' + 'Paris', + 'Xenia', + 'Lancaster' } -template_file_name = 'template.json' +O3DE_LICENSE_TEXT = \ + """'# {BEGIN_LICENSE} +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# {END_LICENSE} +""" + this_script_parent = pathlib.Path(os.path.dirname(os.path.realpath(__file__))) @@ -165,7 +175,8 @@ def _execute_template_json(json_data: dict, destination_path: pathlib.Path, template_path: pathlib.Path, replacements: list, - keep_license_text: bool = False) -> None: + keep_license_text: bool = False, + keep_restricted_in_instance: bool = False) -> None: # create dirs first # for each createDirectory entry, transform the folder name for create_directory in json_data['createDirectories']: @@ -174,6 +185,18 @@ def _execute_template_json(json_data: dict, # transform the folder name new_dir = _transform(new_dir.as_posix(), replacements, keep_license_text) + new_dir = pathlib.Path(new_dir) + + if not keep_restricted_in_instance and 'Platform' in new_dir.parts: + try: + # the name of the Platform should follow the '/Platform/' + pattern = r'/Platform/(?P[^/:*?\"<>|\r\n]+/?)' + found_platform = re.search(pattern, new_dir.as_posix()).group('Platform') + found_platform = found_platform.replace('/', '') + if found_platform in restricted_platforms: + continue + except Exception as e: + pass # create the folder os.makedirs(new_dir, exist_ok=True) @@ -184,16 +207,23 @@ def _execute_template_json(json_data: dict, # construct the input file name in_file = template_path / 'Template' / copy_file['file'] - # the file can be marked as optional, if it is and it does not exist skip - if copy_file['isOptional'] and copy_file['isOptional'] == 'true': - if not os.path.isfile(in_file): - continue - # construct the output file name out_file = destination_path / copy_file['file'] # transform the output file name out_file = _transform(out_file.as_posix(), replacements, keep_license_text) + out_file = pathlib.Path(out_file) + + if not keep_restricted_in_instance and 'Platform' in out_file.parts: + try: + # the name of the Platform should follow the '/Platform/' + pattern = r'/Platform/(?P[^/:*?\"<>|\r\n]+/?)' + found_platform = re.search(pattern, out_file.as_posix()).group('Platform') + found_platform = found_platform.replace('/', '') + if found_platform in restricted_platforms: + continue + except Exception as e: + pass # if for some reason the output folder for this file was not created above do it now os.makedirs(os.path.dirname(out_file), exist_ok=True) @@ -205,18 +235,20 @@ def _execute_template_json(json_data: dict, shutil.copy(in_file, out_file) -def _execute_restricted_template_json(json_data: dict, +def _execute_restricted_template_json(template_json_data: dict, + json_data: dict, restricted_platform: str, destination_name, - template_name, destination_path: pathlib.Path, destination_restricted_path: pathlib.Path, + template_path: pathlib.Path, template_restricted_path: pathlib.Path, destination_restricted_platform_relative_path: pathlib.Path, template_restricted_platform_relative_path: pathlib.Path, replacements: list, keep_restricted_in_instance: bool = False, keep_license_text: bool = False) -> None: + # if we are not keeping restricted in instance make restricted.json if not present if not keep_restricted_in_instance: restricted_json = destination_restricted_path / 'restricted.json' @@ -227,50 +259,96 @@ def _execute_restricted_template_json(json_data: dict, restricted_json_data.update({"restricted_name": destination_name}) s.write(json.dumps(restricted_json_data, indent=4) + '\n') + ################################################################################### + # for each createDirectories in the template copy any entries in the json_data that are for this platform + for create_directory in template_json_data['createDirectories']: + new_dir = pathlib.Path(create_directory['dir']) + if not keep_restricted_in_instance and 'Platform' in new_dir.parts: + try: + # the name of the Platform should follow the '/Platform/' + pattern = r'/Platform/(?P[^/:*?\"<>|\r\n]+/?)' + found_platform = re.search(pattern, new_dir.as_posix()).group('Platform') + except Exception as e: + pass + else: + found_platform = found_platform.replace('/', '') + if found_platform == restricted_platform: + create_dirs = [] + if 'createDirectories' in json_data.keys(): + create_dirs = json_data['createDirectories'] + create_dirs.append(create_directory) + json_data.update({'createDirectories': create_dirs}) + + # for each copyFiles in the template copy any entries in the json_data that are for this platform + for copy_file in template_json_data['copyFiles']: + new_file = pathlib.Path(copy_file['file']) + if not keep_restricted_in_instance and 'Platform' in new_file.parts: + try: + # the name of the Platform should follow the '/Platform/' + pattern = r'/Platform/(?P[^/:*?\"<>|\r\n]+/?)' + found_platform = re.search(pattern, new_file.as_posix()).group('Platform') + except Exception as e: + pass + else: + found_platform = found_platform.replace('/', '') + if found_platform == restricted_platform: + copy_files = [] + if 'copyFiles' in json_data.keys(): + copy_files = json_data['copyFiles'] + copy_files.append(copy_file) + json_data.update({'copyFiles': copy_files}) + + ################################################################################### + + # every entry is saved in its combined location, so if not keep_restricted_in_instance + # then we need to palify into the restricted folder + # create dirs first # for each createDirectory entry, transform the folder name - for create_directory in json_data['createDirectories']: - # construct the new folder name - new_dir = destination_restricted_path / restricted_platform / destination_restricted_platform_relative_path\ - / destination_name / create_directory['dir'] - if keep_restricted_in_instance: - new_dir = destination_path / create_directory['origin'] + if 'createDirectories' in json_data: + for create_directory in json_data['createDirectories']: + # construct the new folder name + if keep_restricted_in_instance: + new_dir = destination_path / create_directory['dir'] + else: + pal_dir = create_directory['dir'].replace(f'Platform/{restricted_platform}','') + new_dir = destination_restricted_path / restricted_platform / destination_restricted_platform_relative_path / pal_dir - # transform the folder name - new_dir = _transform(new_dir.as_posix(), replacements, keep_license_text) + # transform the folder name + new_dir = _transform(new_dir.as_posix(), replacements, keep_license_text) - # create the folder - os.makedirs(new_dir, exist_ok=True) + # create the folder + os.makedirs(new_dir, exist_ok=True) # for each copyFiles entry, _transformCopy the templated source file into a concrete instance file or # regular copy if not templated - for copy_file in json_data['copyFiles']: - # construct the input file name - in_file = template_restricted_path / restricted_platform / template_restricted_platform_relative_path\ - / template_name / 'Template' / copy_file['file'] + if 'copyFiles' in json_data: + for copy_file in json_data['copyFiles']: + # construct the input file name + if template_restricted_path: + pal_file = copy_file['file'].replace(f'Platform/{restricted_platform}/', '') + in_file = template_restricted_path / restricted_platform / template_restricted_platform_relative_path / 'Template' / pal_file + else: + in_file = template_path / 'Template' / copy_file['file'] - # the file can be marked as optional, if it is and it does not exist skip - if copy_file['isOptional'] and copy_file['isOptional'] == 'true': - if not os.path.isfile(in_file): - continue + # construct the output file name + if keep_restricted_in_instance: + out_file = destination_path / copy_file['file'] + else: + pal_file = copy_file['file'].replace(f'Platform/{restricted_platform}/', '') + out_file = destination_restricted_path / restricted_platform / destination_restricted_platform_relative_path / pal_file - # construct the output file name - out_file = destination_restricted_path / restricted_platform / destination_restricted_platform_relative_path\ - / destination_name / copy_file['file'] - if keep_restricted_in_instance: - out_file = destination_path / copy_file['origin'] + # transform the output file name + out_file = _transform(out_file.as_posix(), replacements, keep_license_text) - # transform the output file name - out_file = _transform(out_file.as_posix(), replacements, keep_license_text) + # if for some reason the output folder for this file was not created above do it now + os.makedirs(os.path.dirname(out_file), exist_ok=True) - # if for some reason the output folder for this file was not created above do it now - os.makedirs(os.path.dirname(out_file), exist_ok=True) - - # if templated _transformCopy the file, if not just copy it - if copy_file['isTemplated']: - _transform_copy(in_file, out_file, replacements, keep_license_text) - else: - shutil.copy(in_file, out_file) + # if templated _transformCopy the file, if not just copy it + if copy_file['isTemplated']: + _transform_copy(in_file, out_file, replacements, keep_license_text) + else: + shutil.copy(in_file, out_file) def _instantiate_template(template_json_data: dict, @@ -309,46 +387,51 @@ def _instantiate_template(template_json_data: dict, :return: 0 for success or non 0 failure code """ # execute the template json + # this will filter out any restricted platforms in the template _execute_template_json(template_json_data, destination_path, template_path, replacements, - keep_license_text) + keep_license_text, + keep_restricted_in_instance) - # execute restricted platform jsons if any - if template_restricted_path: - for restricted_platform in os.listdir(template_restricted_path): - if os.path.isfile(restricted_platform): - continue + # we execute the jason data again if there are any restricted platforms in the main template and + # execute any restricted platform jsons if separate + + for restricted_platform in restricted_platforms: + restricted_json_data = {} + if template_restricted_path: template_restricted_platform = template_restricted_path / restricted_platform - template_restricted_platform_path_rel = template_restricted_platform / template_restricted_platform_relative_path / template_name - platform_json = template_restricted_platform_path_rel / template_file_name + template_restricted_platform_path_rel = template_restricted_platform / template_restricted_platform_relative_path + platform_json = template_restricted_platform_path_rel / 'template.json' if os.path.isfile(platform_json): if not validation.valid_o3de_template_json(platform_json): logger.error(f'Template json {platform_json} is invalid.') return 1 - # load the template json and execute it + # load the template json with open(platform_json, 'r') as s: try: - json_data = json.load(s) + restricted_json_data = json.load(s) except json.JSONDecodeError as e: logger.error(f'Failed to load {platform_json}: ' + str(e)) return 1 - else: - _execute_restricted_template_json(json_data, - restricted_platform, - destination_name, - template_name, - destination_path, - destination_restricted_path, - template_restricted_path, - destination_restricted_platform_relative_path, - template_restricted_platform_relative_path, - replacements, - keep_restricted_in_instance, - keep_license_text) + + # execute for this restricted platform + _execute_restricted_template_json(template_json_data, + restricted_json_data, + restricted_platform, + destination_name, + destination_path, + destination_restricted_path, + template_path, + template_restricted_path, + destination_restricted_platform_relative_path, + template_restricted_platform_relative_path, + replacements, + keep_restricted_in_instance, + keep_license_text) return 0 @@ -365,7 +448,8 @@ def create_template(source_path: pathlib.Path, keep_restricted_in_template: bool = False, keep_license_text: bool = False, replace: list = None, - force: bool = False) -> int: + force: bool = False, + no_register: bool = False) -> int: """ Create a template from a source directory using replacement @@ -391,6 +475,7 @@ def create_template(source_path: pathlib.Path, this controls if you want to keep the license text from the template in the new instance. It is false by default because most people will not want license text in their instances. :param force Overrides existing files even if they exist + :param no_register: whether or not after completion that the new object is registered :return: 0 for success or non 0 failure code """ @@ -401,15 +486,19 @@ def create_template(source_path: pathlib.Path, if not source_path.is_dir(): logger.error(f'Src path {source_path} is not a folder.') return 1 - source_path = source_path.resolve() - # source_name is now the last component of the source_path + + # if not specified, source_name defaults to the last component of the source_path if not source_name: source_name = os.path.basename(source_path) sanitized_source_name = utils.sanitize_identifier_for_cpp(source_name) # if no template path, use default_templates_folder path if not template_path: + logger.info(f'Template path empty. Using source name {source_name}') + template_path = source_name + # if the template_path is not an absolute path, then it default to relative from the default template folder + if not template_path.is_absolute(): default_templates_folder = manifest.get_registered(default_folder='templates') template_path = default_templates_folder / source_name logger.info(f'Template path empty. Using default templates folder {template_path}') @@ -423,7 +512,8 @@ def create_template(source_path: pathlib.Path, except ValueError: pass else: - logger.error(f'Template output path {template_path} cannot be a subdirectory of the source_path {source_path}\n') + logger.error( + f'Template output path {template_path} cannot be a subdirectory of the source_path {source_path}\n') return 1 # template name is now the last component of the template_path @@ -434,69 +524,61 @@ def create_template(source_path: pathlib.Path, logger.error(f'Template path cannot be a restricted name. {template_name}') return 1 + # if the source restricted name was given and no source restricted path, look up the restricted name to fill + # in the path if source_restricted_name and not source_restricted_path: source_restricted_path = manifest.get_registered(restricted_name=source_restricted_name) - # source_restricted_path + # if we have a source restricted path, make sure its a real restricted object if source_restricted_path: - if not os.path.isabs(source_restricted_path): - engine_json = manifest.get_this_engine_path() / 'engine.json' - if not validation.valid_o3de_engine_json(engine_json): - logger.error(f"Engine json {engine_json} is not valid.") - return 1 - with open(engine_json) as s: - try: - engine_json_data = json.load(s) - except json.JSONDecodeError as e: - logger.error(f"Failed to read engine json {engine_json}: {str(e)}") - return 1 - try: - engine_restricted = engine_json_data['restricted_name'] - except KeyError as e: - logger.error(f"Engine json {engine_json} restricted not found.") - return 1 - engine_restricted_folder = manifest.get_registered(restricted_name=engine_restricted) - new_source_restricted_path = engine_restricted_folder / source_restricted_path - logger.info(f'Source restricted path {source_restricted_path} not a full path. We must assume this engines' - f' restricted folder {new_source_restricted_path}') - if not os.path.isdir(source_restricted_path): + if not source_restricted_path.is_dir(): logger.error(f'Source restricted path {source_restricted_path} is not a folder.') return 1 + restricted_json = source_restricted_path / 'restricted.json' + if not validation.valid_o3de_restricted_json(restricted_json): + logger.error(f"Restricted json {restricted_json} is not valid.") + return 1 + with open(restricted_json, 'r') as s: + try: + restricted_json_data = json.load(s) + except json.JSONDecodeError as e: + logger.error(f'Failed to load {restricted_json}: ' + str(e)) + return 1 + try: + source_restricted_name = restricted_json_data['restricted_name'] + except KeyError as e: + logger.error(f'Failed to read restricted_name from {restricted_json}') + return 1 + # if the template restricted name was given and no template restricted path, look up the restricted name to fill + # in the path if template_restricted_name and not template_restricted_path: template_restricted_path = manifest.get_registered(restricted_name=template_restricted_name) + # if we dont have a template restricted name then set it to the templates name if not template_restricted_name: template_restricted_name = template_name - # template_restricted_path + # if we have a template restricted path, it must either not exist yet or must be a restricted object already if template_restricted_path: - if not os.path.isabs(template_restricted_path): - default_templates_restricted_folder = manifest.get_registered(restricted_name='templates') - new_template_restricted_path = default_templates_restricted_folder / template_restricted_path - logger.info(f'Template restricted path {template_restricted_path} not a full path. We must assume the' - f' default templates restricted folder {new_template_restricted_path}') - template_restricted_path = new_template_restricted_path - - if os.path.isdir(template_restricted_path): + if template_restricted_path.is_dir(): # see if this is already a restricted path, if it is get the "restricted_name" from the restricted json # so we can set "restricted_name" to it for this template restricted_json = template_restricted_path / 'restricted.json' - if os.path.isfile(restricted_json): - if not validation.valid_o3de_restricted_json(restricted_json): - logger.error(f'{restricted_json} is not valid.') + if not validation.valid_o3de_restricted_json(restricted_json): + logger.error(f'{restricted_json} is not valid.') + return 1 + with open(restricted_json, 'r') as s: + try: + restricted_json_data = json.load(s) + except json.JSONDecodeError as e: + logger.error(f'Failed to load {restricted_json}: ' + str(e)) + return 1 + try: + template_restricted_name = restricted_json_data['restricted_name'] + except KeyError as e: + logger.error(f'Failed to read restricted_name from {restricted_json}') return 1 - with open(restricted_json, 'r') as s: - try: - restricted_json_data = json.load(s) - except json.JSONDecodeError as e: - logger.error(f'Failed to load {restricted_json}: ' + str(e)) - return 1 - try: - template_restricted_name = restricted_json_data['restricted_name'] - except KeyError as e: - logger.error(f'Failed to read restricted_name from {restricted_json}') - return 1 else: os.makedirs(template_restricted_path, exist_ok=True) @@ -610,36 +692,7 @@ def create_template(source_path: pathlib.Path, else: return False, t_data - def _transform_into_template_restricted_filename(s_data: object, - platform: str) -> (bool, object): - """ - Internal function to transform a restricted platform file name into restricted template file name - :param s_data: the input data, this could be file data or file name data - :return: bool: whether or not the returned data MAY need to be transformed to instantiate it - t_data: potentially transformed data 0 for success or non 0 failure code - """ - # copy the src data to the transformed data, then operate only on transformed data - t_data = s_data - - # run all the replacements - for replacement in replacements: - t_data = t_data.replace(replacement[0], replacement[1]) - - # the name of the Platform should follow the '/Platform/{platform}' - t_data = t_data.replace(f"Platform/{platform}", '') - - # we want to send back the transformed data and whether or not this file - # may require transformation when instantiated. So if the input data is not the - # same as the output, then we transformed it which means there may be a transformation - # needed to instance it. - if s_data != t_data: - return True, t_data - else: - return False, t_data - - def _transform_restricted_into_copyfiles_and_createdirs(source_path: pathlib.Path, - restricted_platform: str, - root_abs: pathlib.Path, + def _transform_restricted_into_copyfiles_and_createdirs(root_abs: pathlib.Path, path_abs: pathlib.Path = None) -> None: """ Internal function recursively called to transform any paths files into copyfiles and create dirs relative to @@ -657,70 +710,49 @@ def create_template(source_path: pathlib.Path, # create the absolute entry by joining the path_abs and the entry entry_abs = path_abs / entry + # report what file we are processing so we have a good idea if it breaks on what file it broke on + logger.info(f'Processing file: {entry_abs}') + # create the relative entry by removing the root_abs try: entry_rel = entry_abs.relative_to(root_abs) except ValueError as err: - logger.warning(f'Unable to create relative path: {str(err)}') + logger.fatal(f'Unable to create relative path: {str(err)}') - # report what file we are processing so we have a good idea if it breaks on what file it broke on - logger.info(f'Processing file: {entry_abs}') - - # this is a restricted file, so we need to transform it, unpalify it - # restricted///some/folders/ -> - # /some/folders/Platform// - # - # C:/repo/Lumberyard/restricted/Jasper/TestDP/CMakeLists.txt -> - # C:/repo/Lumberyard/TestDP/Platform/Jasper/CMakeLists.txt - # - _, origin_entry_rel = _transform_into_template(entry_rel.as_posix()) - components = list(origin_entry_rel.parts) - num_components = len(components) - - # see how far along the source path the restricted folder matches - # then hopefully there is a Platform folder, warn if there isn't - before = [] - after = [] - relative = '' - - if os.path.isdir(entry_abs): - for x in range(0, num_components): - relative += f'{components[x]}/' - if os.path.isdir(f'{source_path}/{relative}'): - before.append(components[x]) - else: - after.append(components[x]) - else: - for x in range(0, num_components - 1): - relative += f'{components[x]}/' - if os.path.isdir(f'{source_path}/{relative}'): - before.append(components[x]) - else: - after.append(components[x]) - - after.append(components[num_components - 1]) - - before.append("Platform") - warn_if_not_platform = source_path / pathlib.Path(*before) - before.append(restricted_platform) - before.extend(after) - - origin_entry_rel = pathlib.Path(*before) - - if not os.path.isdir(warn_if_not_platform): - logger.warning( - f'{entry_abs} -> {origin_entry_rel}: Other Platforms not found in {warn_if_not_platform}') - - destination_entry_rel = origin_entry_rel - destination_entry_abs = template_path / 'Template' / origin_entry_rel + # templatize the entry relative into the destination entry relative + _, destination_entry_rel = _transform_into_template(entry_rel.as_posix()) + destination_entry_rel = pathlib.Path(destination_entry_rel) # clean up any relative leading slashes - if origin_entry_rel.as_posix().startswith('/'): - origin_entry_rel = pathlib.Path(origin_entry_rel.as_posix().lstrip('/')) if destination_entry_rel.as_posix().startswith('/'): destination_entry_rel = pathlib.Path(destination_entry_rel.as_posix().lstrip('/')) + if isinstance(destination_entry_rel, pathlib.Path): + destination_entry_rel = destination_entry_rel.as_posix() - # make sure the dst folder may or may not exist yet, make sure it does exist before we transform + if template_restricted_path: + destination_entry_abs = template_restricted_path / restricted_platform / template_restricted_platform_relative_path / 'Template' / destination_entry_rel + destination_entry_rel = pathlib.Path(destination_entry_rel) + first = True + for component in destination_entry_rel.parts: + if first: + first = False + result = pathlib.Path(component) / 'Platform' / restricted_platform + else: + result = result / component + destination_entry_rel = result.as_posix() + else: + destination_entry_rel = pathlib.Path(destination_entry_rel) + first = True + for component in destination_entry_rel.parts: + if first: + first = False + result = pathlib.Path(component) / 'Platform' / restricted_platform + else: + result = result / component + destination_entry_rel = result.as_posix() + destination_entry_abs = template_path / 'Template' / destination_entry_rel + + # the destination folder may or may not exist yet, make sure it does exist before we transform # data into it os.makedirs(os.path.dirname(destination_entry_abs), exist_ok=True) @@ -730,8 +762,8 @@ def create_template(source_path: pathlib.Path, if os.path.isfile(entry_abs): # if this file is a known binary file, there is no transformation needed and just copy it - # if not a known binary file open it and try to transform the data. if it is an unknown binary - # type it will throw and we catch copy + # if not a known binary file open it and try to transform the data. + # if it is an unknown binary type it will throw and we catch copy # if we had no known binary type it would still work, but much slower name, ext = os.path.splitext(entry) if ext in binary_file_ext: @@ -743,7 +775,7 @@ def create_template(source_path: pathlib.Path, source_data = s.read() templated, source_data = _transform_into_template(source_data, _is_cpp_file(entry_abs)) - # if the file type is a file that we expect to fins license header and we don't find any + # if the file type is a file that we expect to find a license header and we don't find any # warn that the we didn't find the license info, this makes it easy to make sure we didn't # miss any files we want to have license info in. if keep_license_text and ext in expect_license_info_ext: @@ -761,19 +793,26 @@ def create_template(source_path: pathlib.Path, shutil.copy(entry_abs, destination_entry_abs) pass - copy_files.append({ - "file": destination_entry_rel, - "origin": origin_entry_rel, - "isTemplated": templated, - "isOptional": False - }) + if keep_restricted_in_template: + copy_files.append({ + "file": destination_entry_rel, + "isTemplated": templated + }) + else: + restricted_platform_entries[restricted_platform]['copyFiles'].append({ + "file": destination_entry_rel, + "isTemplated": templated + }) else: - create_dirs.append({ - "dir": destination_entry_rel, - "origin": origin_entry_rel - }) - _transform_restricted_into_copyfiles_and_createdirs(source_path, restricted_platform, root_abs, - entry_abs) + if keep_restricted_in_template: + create_dirs.append({ + "dir": destination_entry_rel + }) + else: + restricted_platform_entries[restricted_platform]['createDirs'].append({ + "dir": destination_entry_rel + }) + _transform_restricted_into_copyfiles_and_createdirs(root_abs, entry_abs) def _transform_dir_into_copyfiles_and_createdirs(root_abs: pathlib.Path, path_abs: pathlib.Path = None) -> None: @@ -793,18 +832,21 @@ def create_template(source_path: pathlib.Path, # create the absolute entry by joining the path_abs and the entry entry_abs = path_abs / entry - # create the relative entry by removing the root_abs - entry_rel = entry_abs - try: - entry_rel = entry_abs.relative_to(root_abs) - except ValueError as err: - logger.warning(f'Unable to create relative path: {str(err)}') - # report what file we are processing so we have a good idea if it breaks on what file it broke on logger.info(f'Processing file: {entry_abs}') - # see if the entry is a platform file, if it is then we save its copyfile data in a platform specific list - # then at the end we can save the restricted ones separately + # create the relative entry by removing the root_abs + try: + entry_rel = entry_abs.relative_to(root_abs).as_posix() + except ValueError as err: + logger.fatal(f'Unable to create relative path: {str(err)}') + + # templatize the entry relative into the origin entry relative + _, destination_entry_rel = _transform_into_template(entry_rel) + destination_entry_rel = pathlib.Path(destination_entry_rel) + + # see if the entry is a restricted platform file, if it is then we save its copyfile data in a + # platform specific list then at the end we can save the restricted ones separately found_platform = '' platform = False if not keep_restricted_in_template and 'Platform' in entry_abs.parts: @@ -812,7 +854,7 @@ def create_template(source_path: pathlib.Path, try: # the name of the Platform should follow the '/Platform/' pattern = r'/Platform/(?P[^/:*?\"<>|\r\n]+/?)' - found_platform = re.search(pattern, entry_abs).group('Platform') + found_platform = re.search(pattern, entry_abs.as_posix()).group('Platform') found_platform = found_platform.replace('/', '') except Exception as e: pass @@ -831,30 +873,35 @@ def create_template(source_path: pathlib.Path, # Now if we found a platform and still have a found_platform which is a restricted platform # then transform the entry relative name into a dst relative entry name and dst abs entry. # if not then create a normal relative and abs dst entry name - _, origin_entry_rel = _transform_into_template(entry_rel.as_posix()) if platform and found_platform in restricted_platforms: # if we don't have a template restricted path and we found restricted files... warn and skip # the file/dir if not template_restricted_path: - logger.warning("Restricted platform files found!!! {entry_rel}, {found_platform}") + logger.warning("Restricted platform file found!!! {destination_entry_rel}, {found_platform}") continue - _, destination_entry_rel = _transform_into_template_restricted_filename(entry_rel, found_platform) - destination_entry_abs = template_restricted_path / found_platform\ - / template_restricted_platform_relative_path / template_name / 'Template'\ - / destination_entry_rel + + # run all the replacements + for replacement in replacements: + destination_entry_rel = destination_entry_rel.replace(replacement[0], replacement[1]) + + # the name of the Platform should follow the '/Platform/{found_platform}' + destination_entry_rel = destination_entry_rel.replace(f"Platform/{found_platform}", '') + destination_entry_rel = destination_entry_rel.lstrip('/') + + # construct the absolute entry from the relative + if template_restricted_platform_relative_path: + destination_entry_abs = template_restricted_path / found_platform / template_restricted_platform_relative_path / template_name / 'Template' / destination_entry_rel + else: + destination_entry_abs = template_restricted_path / found_platform / 'Template' / destination_entry_rel else: - destination_entry_rel = origin_entry_rel + # construct the absolute entry from the relative destination_entry_abs = template_path / 'Template' / destination_entry_rel # clean up any relative leading slashes - if isinstance(origin_entry_rel, pathlib.Path): - origin_entry_rel = origin_entry_rel.as_posix() - if origin_entry_rel.startswith('/'): - origin_entry_rel = pathlib.Path(origin_entry_rel.lstrip('/')) if isinstance(destination_entry_rel, pathlib.Path): destination_entry_rel = destination_entry_rel.as_posix() if destination_entry_rel.startswith('/'): - destination_entry_rel = pathlib.Path(destination_entry_rel.lstrip('/')) + destination_entry_rel = destination_entry_rel.lstrip('/') # make sure the dst folder may or may not exist yet, make sure it does exist before we transform # data into it @@ -902,29 +949,23 @@ def create_template(source_path: pathlib.Path, if platform and found_platform in restricted_platforms: restricted_platform_entries[found_platform]['copyFiles'].append({ "file": destination_entry_rel, - "origin": origin_entry_rel, - "isTemplated": templated, - "isOptional": False + "isTemplated": templated }) else: copy_files.append({ "file": destination_entry_rel, - "origin": origin_entry_rel, - "isTemplated": templated, - "isOptional": False + "isTemplated": templated }) else: # if the folder was for a restricted platform add the entry to the restricted platform, otherwise add it # to the non restricted if platform and found_platform in restricted_platforms: restricted_platform_entries[found_platform]['createDirs'].append({ - "dir": destination_entry_rel, - "origin": origin_entry_rel + "dir": destination_entry_rel }) else: create_dirs.append({ - "dir": destination_entry_rel, - "origin": origin_entry_rel + "dir": destination_entry_rel }) # recurse using the same root and this folder @@ -937,11 +978,11 @@ def create_template(source_path: pathlib.Path, # when we run the transformation any restricted platforms entries we find will go in here restricted_platform_entries = {} - # Every project will have a unrestricted folder which is src_path_abs which MAY have restricted files in it, and - # each project MAY have a restricted folder which will only have restricted files in them. The process is the + # Every template will have a unrestricted folder which is src_path_abs which MAY have restricted files in it, and + # each template MAY have a restricted folder which will only have restricted files in them. The process is the # same for all of them and the result will be a separation of all restricted files from unrestricted files. We do - # this by running the transformation first over the src path abs and then on each restricted folder for this project - # we find. This will effectively combine all sources then separates all the restricted. + # this by running the transformation first over the src path abs and then on each restricted folder for this + # template we find. This will effectively combine all sources then separates all the restricted. # run the transformation on the src, which may or may not have restricted files _transform_dir_into_copyfiles_and_createdirs(source_path) @@ -950,11 +991,12 @@ def create_template(source_path: pathlib.Path, # run the transformation on each src restricted folder if source_restricted_path: for restricted_platform in os.listdir(source_restricted_path): - restricted_platform_src_path_abs = source_restricted_path / restricted_platform\ - / source_restricted_platform_relative_path / source_name + restricted_platform_src_path_abs = source_restricted_path / restricted_platform \ + / source_restricted_platform_relative_path if os.path.isdir(restricted_platform_src_path_abs): - _transform_restricted_into_copyfiles_and_createdirs(source_path, restricted_platform, - restricted_platform_src_path_abs) + if restricted_platform not in restricted_platform_entries: + restricted_platform_entries.update({restricted_platform: {'copyFiles': [], 'createDirs': []}}) + _transform_restricted_into_copyfiles_and_createdirs(restricted_platform_src_path_abs) # sort copy_files.sort(key=lambda x: x['file']) @@ -972,39 +1014,47 @@ def create_template(source_path: pathlib.Path, json_data.update({'canonical_tags': []}) json_data.update({'user_tags': [f"{template_name}"]}) json_data.update({'icon_path': "preview.png"}) - if template_restricted_path: + if not keep_restricted_in_template and template_restricted_path: json_data.update({'restricted_name': template_restricted_name}) if template_restricted_platform_relative_path != '': - json_data.update({'template_restricted_platform_relative_path': template_restricted_platform_relative_path}) + json_data.update({'template_restricted_platform_relative_path': template_restricted_platform_relative_path.as_posix()}) json_data.update({'copyFiles': copy_files}) json_data.update({'createDirectories': create_dirs}) - json_name = template_path / template_file_name + json_name = template_path / source_restricted_platform_relative_path / 'template.json' with json_name.open('w') as s: s.write(json.dumps(json_data, indent=4) + '\n') # copy the default preview.png preview_png_src = this_script_parent / 'resources' / 'preview.png' - preview_png_dst = template_path / 'Template' / 'preview.png' + preview_png_dst = template_path / 'preview.png' if not os.path.isfile(preview_png_dst): shutil.copy(preview_png_src, preview_png_dst) # if no restricted template path was given and restricted platform files were found - if not template_restricted_path and len(restricted_platform_entries): + if not keep_restricted_in_template and not template_restricted_path and len(restricted_platform_entries): logger.info(f'Restricted platform files found!!! and no template restricted path was found...') - if template_restricted_path: + if not keep_restricted_in_template and template_restricted_path: + json_name = template_restricted_path / 'restricted.json' + if not json_name.is_file(): + json_data = {} + json_data.update({'restricted_name': template_restricted_name}) + os.makedirs(os.path.dirname(json_name), exist_ok=True) + + with json_name.open('w') as s: + s.write(json.dumps(json_data, indent=4) + '\n') + # now write out each restricted platform template json separately for restricted_platform in restricted_platform_entries: - restricted_template_path = template_restricted_path / restricted_platform\ - / template_restricted_platform_relative_path / template_name - + restricted_template_path = template_restricted_path / restricted_platform / template_restricted_platform_relative_path # sort restricted_platform_entries[restricted_platform]['copyFiles'].sort(key=lambda x: x['file']) restricted_platform_entries[restricted_platform]['createDirs'].sort(key=lambda x: x['dir']) json_data = {} + json_data.update({'restricted_name': template_name}) json_data.update({'template_name': template_name}) json_data.update( {'origin': f'The primary repo for {template_name} goes here: i.e. http://www.mydomain.com'}) @@ -1012,23 +1062,25 @@ def create_template(source_path: pathlib.Path, {'license': f'What license {template_name} uses goes here: i.e. https://opensource.org/licenses/MIT'}) json_data.update({'display_name': template_name}) json_data.update({'summary': f"A short description of {template_name}."}) - json_data.update({'canonical_tags': []}) + json_data.update({'canonical_tags': [f'{restricted_platform}']}) json_data.update({'user_tags': [f'{template_name}']}) - json_data.update({'icon_path': "preview.png"}) json_data.update({'copyFiles': restricted_platform_entries[restricted_platform]['copyFiles']}) json_data.update({'createDirectories': restricted_platform_entries[restricted_platform]['createDirs']}) - json_name = restricted_template_path / template_file_name + json_name = restricted_template_path / 'template.json' os.makedirs(os.path.dirname(json_name), exist_ok=True) with json_name.open('w') as s: s.write(json.dumps(json_data, indent=4) + '\n') - preview_png_dst = restricted_template_path / 'Template' /' preview.png' - if not os.path.isfile(preview_png_dst): - shutil.copy(preview_png_src, preview_png_dst) + # Register the restricted + if not no_register: + if register.register(restricted_path=template_restricted_path): + logger.error(f'Failed to register the restricted {template_restricted_path}.') + return 1 - return 0 + # Register the template + return register.register(template_path=template_path) if not no_register else 0 def create_from_template(destination_path: pathlib.Path, @@ -1044,7 +1096,8 @@ def create_from_template(destination_path: pathlib.Path, keep_restricted_in_instance: bool = False, keep_license_text: bool = False, replace: list = None, - force: bool = False) -> int: + force: bool = False, + no_register: bool = False) -> int: """ Generic template instantiation for non o3de object templates. This function makes NO assumptions! Assumptions are made only for specializations like create_project or create_gem etc... So this function @@ -1251,17 +1304,18 @@ def create_from_template(destination_path: pathlib.Path, # destination restricted path elif destination_restricted_path: - if os.path.isabs(destination_restricted_path): + if not os.path.isabs(destination_restricted_path): restricted_default_path = manifest.get_registered(default_folder='restricted') - new_destination_restricted_path = restricted_default_path / destination_restricted_path + new_destination_restricted_path = restricted_default_path / "Templates" / destination_restricted_path logger.info(f'{destination_restricted_path} is not a full path, making it relative' f' to default restricted path = {new_destination_restricted_path}') destination_restricted_path = new_destination_restricted_path - elif template_restricted_path: - restricted_default_path = manifest.get_registered(restricted_name='restricted') - logger.info(f'--destination-restricted-path is not specified, using default restricted path / destination name' - f' = {restricted_default_path}') - destination_restricted_path = restricted_default_path + else: + restricted_default_path = manifest.get_registered(default_folder='restricted') + new_destination_restricted_path = restricted_default_path / "Templates" / destination_name + logger.info(f'--destination-restricted-path is not specified, using default restricted path' + f' / Templates / destination name = {new_destination_restricted_path}') + destination_restricted_path = new_destination_restricted_path # destination restricted relative if not destination_restricted_platform_relative_path: @@ -1306,7 +1360,7 @@ def create_from_template(destination_path: pathlib.Path, if destination_restricted_path: os.makedirs(destination_restricted_path, exist_ok=True) - # read the restricted_name from the destination restricted.json + # write the restricted_name to the destination restricted.json restricted_json = destination_restricted_path / 'restricted.json' if not os.path.isfile(restricted_json): with open(restricted_json, 'w') as s: @@ -1314,6 +1368,12 @@ def create_from_template(destination_path: pathlib.Path, restricted_json_data.update({'restricted_name': destination_name}) s.write(json.dumps(restricted_json_data, indent=4) + '\n') + # Register the restricted + if not no_register: + if register.register(restricted_path=destination_restricted_path): + logger.error(f'Failed to register the restricted {destination_restricted_path}.') + return 1 + logger.warning(f'Instantiation successful. NOTE: This is a generic instantiation of the template. If this' f' was a template of an o3de object like a project, gem, template, etc. then the create-project' f' or create-gem command can be used to register the object type via its project.json or gem.json, etc.' @@ -1364,6 +1424,7 @@ def create_project(project_path: pathlib.Path, Ex. ${Name},TestGem,${Player},TestGemPlayer This will cause all references to ${Name} be replaced by TestGem, and all ${Player} replaced by 'TestGemPlayer' :param force Overrides existing files even if they exist + :param no_register: whether or not after completion that the new object is registered :param system_component_class_id: optionally specify a uuid for the system component class, default is random uuid :param editor_system_component_class_id: optionally specify a uuid for the editor system component class, default is random uuid @@ -1422,12 +1483,10 @@ def create_project(project_path: pathlib.Path, # see if the template itself specifies a restricted name if not template_restricted_name and not template_restricted_path: try: - template_json_restricted_name = template_json_data['restricted_name'] + template_restricted_name = template_json_data['restricted_name'] except KeyError as e: # the template json doesn't have a 'restricted_name' element warn and use it logger.info(f'The template does not specify a "restricted_name".') - else: - template_restricted_name = template_json_restricted_name # if no restricted name or path we continue on as if there is no template restricted files. if template_restricted_name or template_restricted_path: @@ -1523,8 +1582,13 @@ def create_project(project_path: pathlib.Path, if not project_path: logger.error('Project path cannot be empty.') return 1 - project_path = project_path.resolve() + if not os.path.isabs(project_path): + default_projects_folder = manifest.get_registered(default_folder='projects') + new_project_path = default_projects_folder / project_path + logger.info(f'Project Path {project_path} is not a full path, we must assume its relative' + f' to default projects path = {new_project_path}') + project_path = new_project_path if not force and project_path.is_dir() and len(list(project_path.iterdir())): logger.error(f'Project path {project_path} already exists and is not empty.') return 1 @@ -1536,7 +1600,8 @@ def create_project(project_path: pathlib.Path, project_name = os.path.basename(project_path) if not utils.validate_identifier(project_name): - logger.error(f'Project name must be fewer than 64 characters, contain only alphanumeric, "_" or "-" characters, and start with a letter. {project_name}') + logger.error( + f'Project name must be fewer than 64 characters, contain only alphanumeric, "_" or "-" characters, and start with a letter. {project_name}') return 1 # project name cannot be the same as a restricted platform name @@ -1546,21 +1611,19 @@ def create_project(project_path: pathlib.Path, # project restricted name if project_restricted_name and not project_restricted_path: - project_restricted_path = manifest.get_registered(restricted_name=project_restricted_name) + gem_restricted_path = manifest.get_registered(restricted_name=project_restricted_name) + if not gem_restricted_path: + logger.error(f'Project Restricted Name {project_restricted_name} cannot be found.') + return 1 # project restricted path - elif project_restricted_path: + if project_restricted_path: if not os.path.isabs(project_restricted_path): - default_projects_restricted_folder = manifest.get_registered(restricted_name='projects') - new_project_restricted_path = default_projects_restricted_folder/ project_restricted_path - logger.info(f'Project restricted path {project_restricted_path} is not a full path, we must assume its' - f' relative to default projects restricted path = {new_project_restricted_path}') - project_restricted_path = new_project_restricted_path - elif template_restricted_path: - project_restricted_default_path = manifest.get_registered(restricted_name='projects') - logger.info(f'--project-restricted-path is not specified, using default project restricted path / project name' - f' = {project_restricted_default_path}') - project_restricted_path = project_restricted_default_path + logger.error(f'Project Restricted Path {project_restricted_path} is not an absolute path.') + return 1 + # neither put it in the default restricted projects + else: + project_restricted_path = manifest.get_o3de_restricted_folder() / 'Projects' / project_name # project restricted relative path if not project_restricted_platform_relative_path: @@ -1639,7 +1702,7 @@ def create_project(project_path: pathlib.Path, os.makedirs(project_restricted_path, exist_ok=True) # read the restricted_name from the projects restricted.json - restricted_json = project_restricted_path / 'restricted.json' + restricted_json = project_restricted_path / 'restricted.json' if os.path.isfile(restricted_json): if not validation.valid_o3de_restricted_json(restricted_json): logger.error(f'Restricted json {restricted_json} is not valid.') @@ -1663,7 +1726,8 @@ def create_project(project_path: pathlib.Path, logger.error(f'Failed to read "restricted_name" from restricted json {restricted_json}.') return 1 - # set the "restricted_name": "restricted_name" element of the project.json + # set the "restricted": element of the project.json + project_json = project_path / 'project.json' if not validation.valid_o3de_project_json(project_json): logger.error(f'Project json {project_json} is not valid.') return 1 @@ -1675,7 +1739,7 @@ def create_project(project_path: pathlib.Path, logger.error(f'Failed to load project json {project_json}.') return 1 - project_json_data.update({"restricted_name": restricted_name}) + project_json_data.update({"restricted": restricted_name}) os.unlink(project_json) with open(project_json, 'w') as s: try: @@ -1684,20 +1748,11 @@ def create_project(project_path: pathlib.Path, logger.error(f'Failed to write project json {project_json}.') return 1 - for restricted_platform in restricted_platforms: - restricted_project = project_restricted_path / restricted_platform / project_name - os.makedirs(restricted_project, exist_ok=True) - cmakelists_file_name = restricted_project/ 'CMakeLists.txt' - if not os.path.isfile(cmakelists_file_name): - with open(cmakelists_file_name, 'w') as d: - if keep_license_text: - d.write('# {BEGIN_LICENSE}\n') - d.write('# Copyright (c) Contributors to the Open 3D Engine Project.\n') - d.write('# For complete copyright and license terms please see the LICENSE at the root of this distribution.\n') - d.write('#\n') - d.write('# SPDX-License-Identifier: Apache-2.0 OR MIT\n') - d.write('# {END_LICENSE}\n') - + # Register the restricted + if not no_register: + if register.register(restricted_path=project_restricted_path): + logger.error(f'Failed to register the restricted {project_restricted_path}.') + return 1 # Register the project with the either o3de_manifest.json or engine.json # and set the project.json "engine" field to match the @@ -1906,10 +1961,15 @@ def create_gem(gem_path: pathlib.Path, if not gem_path: logger.error('Gem path cannot be empty.') return 1 - gem_path = gem_path.resolve() + if not os.path.isabs(gem_path): + default_gems_folder = manifest.get_registered(default_folder='gems') + new_gem_path = default_gems_folder / gem_path + logger.info(f'Gem Path {gem_path} is not a full path, we must assume its relative' + f' to default gems path = {new_gem_path}') + gem_path = new_gem_path if not force and gem_path.is_dir() and len(list(gem_path.iterdir())): - logger.error(f'Gem path {gem_path} already exists and is not empty.') + logger.error(f'Gem path {gem_path} already exists.') return 1 else: os.makedirs(gem_path, exist_ok=force) @@ -1930,22 +1990,18 @@ def create_gem(gem_path: pathlib.Path, # gem restricted name if gem_restricted_name and not gem_restricted_path: gem_restricted_path = manifest.get_registered(restricted_name=gem_restricted_name) + if not gem_restricted_path: + logger.error(f'Gem Restricted Name {gem_restricted_name} cannot be found.') + return 1 # gem restricted path - elif gem_restricted_path: + if gem_restricted_path: if not os.path.isabs(gem_restricted_path): - gem_restricted_default_path = manifest.get_registered(restricted_name='gems') - if gem_restricted_default_path: - new_gem_restricted_path = gem_restricted_default_path / gem_restricted_path - logger.info(f'Gem restricted path {gem_restricted_path} is not a full path, we must assume its' - f' relative to default gems restricted path = {new_gem_restricted_path}') - gem_restricted_path = new_gem_restricted_path + logger.error(f'Gem Restricted Path {gem_restricted_path} is not an absolute path.') + return 1 + # neither put it in the default restricted gems else: - gem_restricted_default_path = manifest.get_registered(restricted_name='gems') - if gem_restricted_default_path: - logger.info(f'--gem-restricted-path is not specified, using default / ' - f' = {gem_restricted_default_path}') - gem_restricted_path = gem_restricted_default_path / gem_name + gem_restricted_path = manifest.get_o3de_restricted_folder() / "Gems" / gem_name # gem restricted relative if not gem_restricted_platform_relative_path: @@ -2035,47 +2091,49 @@ def create_gem(gem_path: pathlib.Path, logger.error(f'Failed to load restricted json {restricted_json}.') return 1 + try: + restricted_name = restricted_json_data["restricted_name"] + except KeyError as e: + logger.error(f'Failed to read "restricted_name" from restricted json {restricted_json}.') + return 1 + + # set the "restricted_name": element of the gem.json + gem_json = gem_path / 'gem.json' + if not validation.valid_o3de_gem_json(gem_json): + logger.error(f'Gem json {gem_json} is not valid.') + return 1 + + with open(gem_json, 'r') as s: try: - restricted_name = restricted_json_data["restricted_name"] - except KeyError as e: - logger.error(f'Failed to read "restricted_name" from restricted json {restricted_json}.') + gem_json_data = json.load(s) + except json.JSONDecodeError as e: + logger.error(f'Failed to load gem json {gem_json}.') return 1 - # set the "restricted_name": "restricted_name" element of the gem.json - gem_json = gem_path / 'gem.json' - if not validation.valid_o3de_gem_json(gem_json): - logger.error(f'Gem json {gem_json} is not valid.') + gem_json_data.update({"restricted": restricted_name}) + os.unlink(gem_json) + with open(gem_json, 'w') as s: + try: + s.write(json.dumps(gem_json_data, indent=4) + '\n') + except OSError as e: + logger.error(f'Failed to write project json {gem_json}.') + return 1 + ''' + for restricted_platform in restricted_platforms: + restricted_gem = gem_restricted_path / restricted_platform / gem_name + os.makedirs(restricted_gem, exist_ok=True) + cmakelists_file_name = restricted_gem / 'CMakeLists.txt' + if not os.path.isfile(cmakelists_file_name): + with open(cmakelists_file_name, 'w') as d: + if keep_license_text: + d.write(O3DE_LICENSE_TEXT) + ''' + # Register the restricted + if not no_register: + if register.register(restricted_path=gem_restricted_path): + logger.error(f'Failed to register the restricted {gem_restricted_path}.') return 1 - with open(gem_json, 'r') as s: - try: - gem_json_data = json.load(s) - except json.JSONDecodeError as e: - logger.error(f'Failed to load gem json {gem_json}.') - return 1 - - gem_json_data.update({"restricted_name": restricted_name}) - os.unlink(gem_json) - with open(gem_json, 'w') as s: - try: - s.write(json.dumps(gem_json_data, indent=4) + '\n') - except OSError as e: - logger.error(f'Failed to write project json {gem_json}.') - return 1 - - for restricted_platform in restricted_platforms: - restricted_gem = gem_restricted_path / restricted_platform/ gem_name - os.makedirs(restricted_gem, exist_ok=True) - cmakelists_file_name = restricted_gem / 'CMakeLists.txt' - if not os.path.isfile(cmakelists_file_name): - with open(cmakelists_file_name, 'w') as d: - if keep_license_text: - d.write('# {BEGIN_LICENSE}\n') - d.write('# Copyright (c) Contributors to the Open 3D Engine Project.\n') - d.write('# For complete copyright and license terms please see the LICENSE at the root of this distribution.\n') - d.write('#\n') - d.write('# SPDX-License-Identifier: Apache-2.0 OR MIT\n') - d.write('# {END_LICENSE}\n') # Register the gem with the either o3de_manifest.json, engine.json or project.json based on the gem path return register.register(gem_path=gem_path) if not no_register else 0 @@ -2093,7 +2151,8 @@ def _run_create_template(args: argparse) -> int: args.keep_restricted_in_template, args.keep_license_text, args.replace, - args.force) + args.force, + args.no_register) def _run_create_from_template(args: argparse) -> int: @@ -2110,7 +2169,8 @@ def _run_create_from_template(args: argparse) -> int: args.keep_restricted_in_instance, args.keep_license_text, args.replace, - args.force) + args.force, + args.no_register) def _run_create_project(args: argparse) -> int: @@ -2166,7 +2226,6 @@ def add_args(subparsers) -> None: call add_args and execute: python o3de.py create-gem --gem-path TestGem :param subparsers: the caller instantiates subparsers and passes it in here """ - # turn a directory into a template create_template_subparser = subparsers.add_parser('create-template') @@ -2242,7 +2301,10 @@ def add_args(subparsers) -> None: ' Note: is automatically ${NameLower}' ' Note: is automatically ${NameUpper}') create_template_subparser.add_argument('-f', '--force', action='store_true', default=False, - help='Copies to new template directory even if it exist.') + help='Copies to new template directory even if it exist.') + create_template_subparser.add_argument('--no-register', action='store_true', default=False, + help='If the template is created successfully, it will not register the' + ' template with the global or engine manifest file.') create_template_subparser.set_defaults(func=_run_create_template) # create from template @@ -2268,11 +2330,11 @@ def add_args(subparsers) -> None: ' resolve the --template-path.') create_from_template_subparser.add_argument('-dn', '--destination-name', type=str, - help='The name to use when substituting the ${Name} placeholder in instantiated template,' - ' must be alphanumeric, ' - ' and can contain _ and - characters.' - ' If no name is provided, will use last component of destination path.' - ' Ex. New_Gem') + help='The name to use when substituting the ${Name} placeholder in instantiated template,' + ' must be alphanumeric, ' + ' and can contain _ and - characters.' + ' If no name is provided, will use last component of destination path.' + ' Ex. New_Gem') group = create_from_template_subparser.add_mutually_exclusive_group(required=False) group.add_argument('-drp', '--destination-restricted-path', type=pathlib.Path, required=False, @@ -2293,7 +2355,8 @@ def add_args(subparsers) -> None: help='The name of the registered restricted path to read from if any. If supplied this will' ' resolve the --template-restricted-path.') - create_from_template_subparser.add_argument('-drprp', '--destination-restricted-platform-relative-path', type=pathlib.Path, + create_from_template_subparser.add_argument('-drprp', '--destination-restricted-platform-relative-path', + type=pathlib.Path, required=False, default=None, help='Any path to append to the --destination-restricted-path/' @@ -2301,7 +2364,8 @@ def add_args(subparsers) -> None: ' --destination-restricted-path C:/instance' ' --destination-restricted-platform-relative-path some/folder' ' => C:/instance//some/folder/') - create_from_template_subparser.add_argument('-trprp', '--template-restricted-platform-relative-path', type=pathlib.Path, + create_from_template_subparser.add_argument('-trprp', '--template-restricted-platform-relative-path', + type=pathlib.Path, required=False, default=None, help='Any path to append to the --template-restricted-path/' @@ -2329,7 +2393,10 @@ def add_args(subparsers) -> None: ' Note: ${NameLower} is automatically ' ' Note: ${NameUpper} is automatically ') create_from_template_subparser.add_argument('-f', '--force', action='store_true', default=False, - help='Copies over instantiated template directory even if it exist.') + help='Copies over instantiated template directory even if it exist.') + create_from_template_subparser.add_argument('--no-register', action='store_true', default=False, + help='If the project template is instantiated successfully, it will not register the' + ' project with the global or engine manifest file.') create_from_template_subparser.set_defaults(func=_run_create_from_template) # creation of a project from a template (like create from template but makes project assumptions) @@ -2430,10 +2497,10 @@ def add_args(subparsers) -> None: help='The str id you want to associate with the project, default is a random uuid' ' Ex. {b60c92eb-3139-454b-a917-a9d3c5819594}') create_project_subparser.add_argument('-f', '--force', action='store_true', default=False, - help='Copies over instantiated template directory even if it exist.') + help='Copies over instantiated template directory even if it exist.') create_project_subparser.add_argument('--no-register', action='store_true', default=False, - help='If the project template is instantiated successfully, it will not register the' - ' project with the global or engine manifest file.') + help='If the project template is instantiated successfully, it will not register the' + ' project with the global or engine manifest file.') create_project_subparser.set_defaults(func=_run_create_project) # creation of a gem from a template (like create from template but makes gem assumptions) @@ -2445,11 +2512,11 @@ def add_args(subparsers) -> None: create_gem_subparser.add_argument('-gp', '--gem-path', type=pathlib.Path, required=True, help='The gem path, can be absolute or relative to the current working directory') create_gem_subparser.add_argument('-gn', '--gem-name', type=str, - help='The name to use when substituting the ${Name} placeholder for the gem,' - ' must be alphanumeric, ' - ' and can contain _ and - characters.' - ' If no name is provided, will use last component of gem path.' - ' Ex. New_Gem') + help='The name to use when substituting the ${Name} placeholder for the gem,' + ' must be alphanumeric, ' + ' and can contain _ and - characters.' + ' If no name is provided, will use last component of gem path.' + ' Ex. New_Gem') group = create_gem_subparser.add_mutually_exclusive_group(required=False) group.add_argument('-tp', '--template-path', type=pathlib.Path, required=False, @@ -2529,7 +2596,7 @@ def add_args(subparsers) -> None: help='The uuid you want to associate with the gem module,' ' default is a random uuid Ex. {b60c92eb-3139-454b-a917-a9d3c5819594}') create_gem_subparser.add_argument('-f', '--force', action='store_true', default=False, - help='Copies over instantiated template directory even if it exist.') + help='Copies over instantiated template directory even if it exist.') create_gem_subparser.add_argument('--no-register', action='store_true', default=False, help='If the gem template is instantiated successfully, it will not register the' ' gem with the global, project or engine manifest file.') diff --git a/scripts/o3de/o3de/get_registration.py b/scripts/o3de/o3de/get_registration.py index d64056e8b2..1271d56804 100644 --- a/scripts/o3de/o3de/get_registration.py +++ b/scripts/o3de/o3de/get_registration.py @@ -14,9 +14,6 @@ from o3de import manifest def _run_get_registered(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - registered_path = manifest.get_registered(args.engine_name, args.project_name, args.gem_name, @@ -55,9 +52,6 @@ def add_parser_args(parser): group.add_argument('-rsn', '--restricted-name', type=str, required=False, help='Restricted name.') - parser.add_argument('-ohf', '--override-home-folder', type=str, required=False, - help='By default the home folder is the user folder, override it to this folder.') - parser.set_defaults(func=_run_get_registered) diff --git a/scripts/o3de/o3de/manifest.py b/scripts/o3de/o3de/manifest.py index a334109e6a..88e6ae8229 100644 --- a/scripts/o3de/o3de/manifest.py +++ b/scripts/o3de/o3de/manifest.py @@ -22,18 +22,13 @@ logger = logging.getLogger('o3de.manifest') logging.basicConfig(format=utils.LOG_FORMAT) # Directory methods -override_home_folder = None - def get_this_engine_path() -> pathlib.Path: return pathlib.Path(os.path.realpath(__file__)).parents[3].resolve() def get_home_folder() -> pathlib.Path: - if override_home_folder: - return pathlib.Path(override_home_folder).resolve() - else: - return pathlib.Path(os.path.expanduser("~")).resolve() + return pathlib.Path(os.path.expanduser("~")).resolve() def get_o3de_folder() -> pathlib.Path: @@ -42,12 +37,6 @@ def get_o3de_folder() -> pathlib.Path: return o3de_folder -def get_o3de_user_folder() -> pathlib.Path: - o3de_user_folder = get_home_folder() / 'O3DE' - o3de_user_folder.mkdir(parents=True, exist_ok=True) - return o3de_user_folder - - def get_o3de_registry_folder() -> pathlib.Path: registry_folder = get_o3de_folder() / 'Registry' registry_folder.mkdir(parents=True, exist_ok=True) @@ -73,19 +62,19 @@ def get_o3de_engines_folder() -> pathlib.Path: def get_o3de_projects_folder() -> pathlib.Path: - projects_folder = get_o3de_user_folder() / 'Projects' + projects_folder = get_o3de_folder() / 'Projects' projects_folder.mkdir(parents=True, exist_ok=True) return projects_folder def get_o3de_gems_folder() -> pathlib.Path: - gems_folder = get_o3de_user_folder() / 'Gems' + gems_folder = get_o3de_folder() / 'Gems' gems_folder.mkdir(parents=True, exist_ok=True) return gems_folder def get_o3de_templates_folder() -> pathlib.Path: - templates_folder = get_o3de_user_folder() / 'Templates' + templates_folder = get_o3de_folder() / 'Templates' templates_folder.mkdir(parents=True, exist_ok=True) return templates_folder @@ -117,6 +106,10 @@ def get_default_o3de_manifest_json_data() -> dict: username = os.path.split(get_home_folder())[-1] o3de_folder = get_o3de_folder() + default_registry_folder = get_o3de_registry_folder() + default_cache_folder = get_o3de_cache_folder() + default_downloads_folder = get_o3de_download_folder() + default_logs_folder = get_o3de_logs_folder() default_engines_folder = get_o3de_engines_folder() default_projects_folder = get_o3de_projects_folder() default_gems_folder = get_o3de_gems_folder() @@ -124,12 +117,20 @@ def get_default_o3de_manifest_json_data() -> dict: default_restricted_folder = get_o3de_restricted_folder() default_third_party_folder = get_o3de_third_party_folder() - default_projects_restricted_folder = default_projects_folder / 'Restricted' - default_projects_restricted_folder.mkdir(parents=True, exist_ok=True) - default_gems_restricted_folder = default_gems_folder / 'Restricted' - default_gems_restricted_folder.mkdir(parents=True, exist_ok=True) - default_templates_restricted_folder = default_templates_folder / 'Restricted' - default_templates_restricted_folder.mkdir(parents=True, exist_ok=True) + default_restricted_projects_folder = default_restricted_folder / 'Projects' + default_restricted_projects_folder.mkdir(parents=True, exist_ok=True) + default_restricted_gems_folder = default_restricted_folder / 'Gems' + default_restricted_gems_folder.mkdir(parents=True, exist_ok=True) + default_restricted_engine_folder = default_restricted_folder / 'Engines' / 'o3de' + default_restricted_engine_folder.mkdir(parents=True, exist_ok=True) + default_restricted_templates_folder = default_restricted_folder / 'Templates' + default_restricted_templates_folder.mkdir(parents=True, exist_ok=True) + default_restricted_engine_folder_json = default_restricted_engine_folder / 'restricted.json' + if not default_restricted_engine_folder_json.is_file(): + with default_restricted_engine_folder_json.open('w') as s: + restricted_json_data = {} + restricted_json_data.update({'restricted_name': 'o3de'}) + s.write(json.dumps(restricted_json_data, indent=4) + '\n') json_data = {} json_data.update({'o3de_manifest_name': f'{username}'}) @@ -140,45 +141,14 @@ def get_default_o3de_manifest_json_data() -> dict: json_data.update({'default_templates_folder': default_templates_folder.as_posix()}) json_data.update({'default_restricted_folder': default_restricted_folder.as_posix()}) json_data.update({'default_third_party_folder': default_third_party_folder.as_posix()}) - - json_data.update({'engines': []}) json_data.update({'projects': []}) json_data.update({'external_subdirectories': []}) json_data.update({'templates': []}) - json_data.update({'restricted': []}) + json_data.update({'restricted': [default_restricted_engine_folder.as_posix()]}) json_data.update({'repos': []}) - - default_restricted_folder_json = default_restricted_folder / 'restricted.json' - if not default_restricted_folder_json.is_file(): - with default_restricted_folder_json.open('w') as s: - restricted_json_data = {} - restricted_json_data.update({'restricted_name': 'o3de'}) - s.write(json.dumps(restricted_json_data, indent=4) + '\n') - - default_projects_restricted_folder_json = default_projects_restricted_folder / 'restricted.json' - if not default_projects_restricted_folder_json.is_file(): - with default_projects_restricted_folder_json.open('w') as s: - restricted_json_data = {} - restricted_json_data.update({'restricted_name': 'projects'}) - s.write(json.dumps(restricted_json_data, indent=4) + '\n') - - default_gems_restricted_folder_json = default_gems_restricted_folder / 'restricted.json' - if not default_gems_restricted_folder_json.is_file(): - with default_gems_restricted_folder_json.open('w') as s: - restricted_json_data = {} - restricted_json_data.update({'restricted_name': 'gems'}) - s.write(json.dumps(restricted_json_data, indent=4) + '\n') - - default_templates_restricted_folder_json = default_templates_restricted_folder / 'restricted.json' - if not default_templates_restricted_folder_json.is_file(): - with default_templates_restricted_folder_json.open('w') as s: - restricted_json_data = {} - restricted_json_data.update({'restricted_name': 'templates'}) - s.write(json.dumps(restricted_json_data, indent=4) + '\n') - + json_data.update({'engines': []}) return json_data - def get_o3de_manifest() -> pathlib.Path: manifest_path = get_o3de_folder() / 'o3de_manifest.json' if not manifest_path.is_file(): @@ -229,12 +199,12 @@ def save_o3de_manifest(json_data: dict, manifest_path: pathlib.Path = None) -> b return False -def get_gems_from_subdirectories(external_subdirs: list) -> list: - """ +def get_gems_from_external_subdirectories(external_subdirs: list) -> list: + ''' Helper Method for scanning a set of external subdirectories for gem.json files - """ + ''' def is_gem_subdirectory(subdir_files): - for name in subdir_files: + for name in files: if name == 'gem.json': return True return False @@ -250,7 +220,8 @@ def get_gems_from_subdirectories(external_subdirs: list) -> list: return gem_directories -def get_engines() -> list: +# Data query methods +def get_manifest_engines() -> list: json_data = load_o3de_manifest() engine_list = json_data['engines'] if 'engines' in json_data else [] # Convert each engine dict entry into a string entry @@ -259,31 +230,31 @@ def get_engines() -> list: engine_list)) -def get_projects() -> list: +def get_manifest_projects() -> list: json_data = load_o3de_manifest() return json_data['projects'] if 'projects' in json_data else [] -def get_gems() -> list: - return get_gems_from_subdirectories(get_external_subdirectories()) +def get_manifest_gems() -> list: + return get_gems_from_external_subdirectories(get_manifest_external_subdirectories()) -def get_external_subdirectories() -> list: +def get_manifest_external_subdirectories() -> list: json_data = load_o3de_manifest() return json_data['external_subdirectories'] if 'external_subdirectories' in json_data else [] -def get_templates() -> list: +def get_manifest_templates() -> list: json_data = load_o3de_manifest() return json_data['templates'] if 'templates' in json_data else [] -def get_restricted() -> list: +def get_manifest_restricted() -> list: json_data = load_o3de_manifest() return json_data['restricted'] if 'restricted' in json_data else [] -def get_repos() -> list: +def get_manifest_repos() -> list: json_data = load_o3de_manifest() return json_data['repos'] if 'repos' in json_data else [] @@ -299,7 +270,7 @@ def get_engine_projects() -> list: def get_engine_gems() -> list: - return get_gems_from_subdirectories(get_engine_external_subdirectories()) + return get_gems_from_external_subdirectories(get_engine_external_subdirectories()) def get_engine_external_subdirectories() -> list: @@ -320,23 +291,9 @@ def get_engine_templates() -> list: return [] -def get_engine_restricted() -> list: - engine_path = get_this_engine_path() - engine_object = get_engine_json_data(engine_path=engine_path) - if engine_object: - return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(), - engine_object['restricted'])) if 'restricted' in engine_object else [] - return [] - - # project.json queries -def get_project_engine_name(project_path: pathlib.Path) -> str or None: - project_object = get_project_json_data(project_path=project_path) - return project_object.get('engine', None) if project_object else None - - def get_project_gems(project_path: pathlib.Path) -> list: - return get_gems_from_subdirectories(get_project_external_subdirectories(project_path)) + return get_gems_from_external_subdirectories(get_project_external_subdirectories(project_path)) def get_project_external_subdirectories(project_path: pathlib.Path) -> list: @@ -355,74 +312,95 @@ def get_project_templates(project_path: pathlib.Path) -> list: return [] -def get_project_restricted(project_path: pathlib.Path) -> list: - project_object = get_project_json_data(project_path=project_path) - if project_object: - return list(map(lambda rel_path: (pathlib.Path(project_path) / rel_path).as_posix(), - project_object['restricted'])) if 'restricted' in project_object else [] +# gem.json queries +def get_gem_gems(gem_path: pathlib.Path) -> list: + return get_gems_from_external_subdirectories(get_gem_external_subdirectories(gem_path)) + + +def get_gem_external_subdirectories(gem_path: pathlib.Path) -> list: + gem_object = get_gem_json_data(gem_path=gem_path) + if gem_object: + return list(map(lambda rel_path: (pathlib.Path(gem_path) / rel_path).as_posix(), + gem_object[ + 'external_subdirectories'])) if 'external_subdirectories' in gem_object else [] + return [] + + +def get_gem_templates(gem_path: pathlib.Path) -> list: + gem_object = get_gem_json_data(gem_path=gem_path) + if gem_object: + return list(map(lambda rel_path: (pathlib.Path(gem_path) / rel_path).as_posix(), + gem_object['templates'])) if 'templates' in gem_object else [] return [] # Combined manifest queries def get_all_projects() -> list: - projects_data = get_projects() + projects_data = get_manifest_projects() projects_data.extend(get_engine_projects()) # Remove duplicates from the list return list(dict.fromkeys(projects_data)) def get_all_gems(project_path: pathlib.Path = None) -> list: - gems_data = get_gems() - gems_data.extend(get_engine_gems()) - if project_path: - gems_data.extend(get_project_gems(project_path)) - return list(dict.fromkeys(gems_data)) + return get_gems_from_external_subdirectories(get_all_external_subdirectories(project_path)) def get_all_external_subdirectories(project_path: pathlib.Path = None) -> list: - external_subdirectories_data = get_external_subdirectories() + external_subdirectories_data = get_manifest_external_subdirectories() external_subdirectories_data.extend(get_engine_external_subdirectories()) if project_path: external_subdirectories_data.extend(get_project_external_subdirectories(project_path)) + + def descend_gems(gem_path: pathlib.Path): + new_external_subdirectories_data = get_gem_external_subdirectories(gem_path) + external_subdirectories_data.extend(new_external_subdirectories_data) + new_gems_data = get_gems_from_external_subdirectories(new_external_subdirectories_data) + for new_gem in new_gems_data: + descend_gems(new_gem) + + gems_data = get_gems_from_external_subdirectories(external_subdirectories_data) + for gem in gems_data: + descend_gems(gem) + + # Remove duplicates from the list return list(dict.fromkeys(external_subdirectories_data)) def get_all_templates(project_path: pathlib.Path = None) -> list: - templates_data = get_templates() + templates_data = get_manifest_templates() templates_data.extend(get_engine_templates()) if project_path: templates_data.extend(get_project_templates(project_path)) + + gems_data = get_all_gems(project_path) + for gem_path in gems_data: + templates_data.extend(get_gem_templates(gem_path)) + + # Remove duplicates from the list return list(dict.fromkeys(templates_data)) -def get_all_restricted(project_path: pathlib.Path = None) -> list: - restricted_data = get_restricted() - restricted_data.extend(get_engine_restricted()) - if project_path: - restricted_data.extend(get_project_restricted(project_path)) - return list(dict.fromkeys(restricted_data)) - - # Template functions -def get_templates_for_project_creation(): +def get_templates_for_project_creation(project_path: pathlib.Path = None) -> list: project_templates = [] - for template_path in get_all_templates(): + for template_path in get_all_templates(project_path): template_path = pathlib.Path(template_path) - template_json_path = pathlib.Path(template_path) / 'template.json' + template_json_path = template_path / 'template.json' if not validation.valid_o3de_template_json(template_json_path): continue - project_json_path = template_path / 'Template' / 'project.json' if validation.valid_o3de_project_json(project_json_path): project_templates.append(template_path) + return project_templates -def get_templates_for_gem_creation(): +def get_templates_for_gem_creation(project_path: pathlib.Path = None) -> list: gem_templates = [] - for template_path in get_all_templates(): + for template_path in get_all_templates(project_path): template_path = pathlib.Path(template_path) - template_json_path = pathlib.Path(template_path) / 'template.json' + template_json_path = template_path / 'template.json' if not validation.valid_o3de_template_json(template_json_path): continue @@ -432,58 +410,20 @@ def get_templates_for_gem_creation(): return gem_templates -def get_templates_for_generic_creation(): # temporary until we have a better way to do this... maybe template_type element - def filter_project_and_gem_templates_out(template_path, - templates_for_project_creation = get_templates_for_project_creation(), - templates_for_gem_creation = get_templates_for_gem_creation()): +def get_templates_for_generic_creation(project_path: pathlib.Path = None) -> list: + generic_templates = [] + for template_path in get_all_templates(project_path): template_path = pathlib.Path(template_path) - return template_path not in templates_for_project_creation and template_path not in templates_for_gem_creation + template_json_path = template_path / 'template.json' + if not validation.valid_o3de_template_json(template_json_path): + continue + gem_json_path = template_path / 'Template' / 'gem.json' + project_json_path = template_path / 'Template' / 'project.json' + if not validation.valid_o3de_gem_json(gem_json_path) and\ + not validation.valid_o3de_project_json(project_json_path): + generic_templates.append(template_path) - return list(filter(filter_project_and_gem_templates_out, get_all_templates())) - - -def get_json_file_path(object_typename: str, - object_path: str or pathlib.Path) -> pathlib.Path: - if not object_typename or not object_path: - logger.error('Must specify an object typename and object path.') - return None - - object_path = pathlib.Path(object_path).resolve() - return object_path / f'{object_typename}.json' - - -def get_json_data_file(object_json: pathlib.Path, - object_typename: str, - object_validator: callable) -> dict or None: - if not object_typename: - logger.error('Missing object typename.') - return None - - if not object_json or not object_json.is_file(): - logger.error(f'Invalid {object_typename} json {object_json} supplied or file missing.') - return None - - if not object_validator or not object_validator(object_json): - logger.error(f'{object_typename} json {object_json} is not valid or could not be validated.') - return None - - with object_json.open('r') as f: - try: - object_json_data = json.load(f) - except json.JSONDecodeError as e: - logger.warning(f'{object_json} failed to load: {e}') - else: - return object_json_data - - return None - - -def get_json_data(object_typename: str, - object_path: str or pathlib.Path, - object_validator: callable) -> dict or None: - object_json = get_json_file_path(object_typename, object_path) - - return get_json_data_file(object_json, object_typename, object_validator) + return generic_templates def get_engine_json_data(engine_name: str = None, @@ -495,7 +435,28 @@ def get_engine_json_data(engine_name: str = None, if engine_name and not engine_path: engine_path = get_registered(engine_name=engine_name) - return get_json_data('engine', engine_path, validation.valid_o3de_engine_json) + if not engine_path: + logger.error(f'Engine Path {engine_path} has not been registered.') + return None + + engine_path = pathlib.Path(engine_path).resolve() + engine_json = engine_path / 'engine.json' + if not engine_json.is_file(): + logger.error(f'Engine json {engine_json} is not present.') + return None + if not validation.valid_o3de_engine_json(engine_json): + logger.error(f'Engine json {engine_json} is not valid.') + return None + + with engine_json.open('r') as f: + try: + engine_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{engine_json} failed to load: {str(e)}') + else: + return engine_json_data + + return None def get_project_json_data(project_name: str = None, @@ -507,7 +468,28 @@ def get_project_json_data(project_name: str = None, if project_name and not project_path: project_path = get_registered(project_name=project_name) - return get_json_data('project', project_path, validation.valid_o3de_project_json) + if not project_path: + logger.error(f'Project Path {project_path} has not been registered.') + return None + + project_path = pathlib.Path(project_path).resolve() + project_json = project_path / 'project.json' + if not project_json.is_file(): + logger.error(f'Project json {project_json} is not present.') + return None + if not validation.valid_o3de_project_json(project_json): + logger.error(f'Project json {project_json} is not valid.') + return None + + with project_json.open('r') as f: + try: + project_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{project_json} failed to load: {str(e)}') + else: + return project_json_data + + return None def get_gem_json_data(gem_name: str = None, gem_path: str or pathlib.Path = None, @@ -519,10 +501,28 @@ def get_gem_json_data(gem_name: str = None, gem_path: str or pathlib.Path = None if gem_name and not gem_path: gem_path = get_registered(gem_name=gem_name, project_path=project_path) - if pathlib.Path(gem_path).is_file(): - return get_json_data_file(gem_path, 'gem', validation.valid_o3de_gem_json) - else: - return get_json_data('gem', gem_path, validation.valid_o3de_gem_json) + if not gem_path: + logger.error(f'Gem Path {gem_path} has not been registered.') + return None + + gem_path = pathlib.Path(gem_path).resolve() + gem_json = gem_path / 'gem.json' + if not gem_json.is_file(): + logger.error(f'Gem json {gem_json} is not present.') + return None + if not validation.valid_o3de_gem_json(gem_json): + logger.error(f'Gem json {gem_json} is not valid.') + return None + + with gem_json.open('r') as f: + try: + gem_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{gem_json} failed to load: {str(e)}') + else: + return gem_json_data + + return None def get_template_json_data(template_name: str = None, template_path: str or pathlib.Path = None, @@ -534,7 +534,28 @@ def get_template_json_data(template_name: str = None, template_path: str or path if template_name and not template_path: template_path = get_registered(template_name=template_name, project_path=project_path) - return get_json_data('template', template_path, validation.valid_o3de_template_json) + if not template_path: + logger.error(f'Template Path {template_path} has not been registered.') + return None + + template_path = pathlib.Path(template_path).resolve() + template_json = template_path / 'template.json' + if not template_json.is_file(): + logger.error(f'Template json {template_json} is not present.') + return None + if not validation.valid_o3de_template_json(template_json): + logger.error(f'Template json {template_json} is not valid.') + return None + + with template_json.open('r') as f: + try: + template_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{template_json} failed to load: {str(e)}') + else: + return template_json_data + + return None def get_restricted_json_data(restricted_name: str = None, restricted_path: str or pathlib.Path = None, @@ -546,26 +567,28 @@ def get_restricted_json_data(restricted_name: str = None, restricted_path: str o if restricted_name and not restricted_path: restricted_path = get_registered(restricted_name=restricted_name, project_path=project_path) - return get_json_data('restricted', restricted_path, validation.valid_o3de_restricted_json) - - -def get_repo_json_data(repo_uri: str) -> dict or None: - if not repo_uri: - logger.error('Must specify a Repo Uri.') + if not restricted_path: + logger.error(f'Restricted Path {restricted_path} has not been registered.') return None - repo_json = get_repo_path(repo_uri=repo_uri) + restricted_path = pathlib.Path(restricted_path).resolve() + restricted_json = restricted_path / 'restricted.json' + if not restricted_json.is_file(): + logger.error(f'Restricted json {restricted_json} is not present.') + return None + if not validation.valid_o3de_restricted_json(restricted_json): + logger.error(f'Restricted json {restricted_json} is not valid.') + return None - return get_json_data_file(repo_json, "Repo", validation.valid_o3de_repo_json) + with restricted_json.open('r') as f: + try: + restricted_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{restricted_json} failed to load: {str(e)}') + else: + return restricted_json_data - -def get_repo_path(repo_uri: str, cache_folder: str or pathlib.Path = None) -> pathlib.Path: - if not cache_folder: - cache_folder = get_o3de_cache_folder() - - repo_manifest = f'{repo_uri}/repo.json' - repo_sha256 = hashlib.sha256(repo_manifest.encode()) - return cache_folder / str(repo_sha256.hexdigest() + '.json') + return None def get_registered(engine_name: str = None, @@ -604,7 +627,7 @@ def get_registered(engine_name: str = None, # check global first then this engine if isinstance(engine_name, str): - engines = get_engines() + engines = get_manifest_engines() for engine in engines: if isinstance(engine, dict): engine_path = pathlib.Path(engine['path']).resolve() @@ -633,72 +656,60 @@ def get_registered(engine_name: str = None, for project_path in projects: project_path = pathlib.Path(project_path).resolve() project_json = project_path / 'project.json' - if not pathlib.Path(project_json).is_file(): - logger.warning(f'{project_json} does not exist') - else: - with project_json.open('r') as f: - try: - project_json_data = json.load(f) - except json.JSONDecodeError as e: - logger.warning(f'{project_json} failed to load: {str(e)}') - else: - this_projects_name = project_json_data['project_name'] - if this_projects_name == project_name: - return project_path + with project_json.open('r') as f: + try: + project_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{project_json} failed to load: {str(e)}') + else: + this_projects_name = project_json_data['project_name'] + if this_projects_name == project_name: + return project_path elif isinstance(gem_name, str): gems = get_all_gems(project_path) for gem_path in gems: gem_path = pathlib.Path(gem_path).resolve() gem_json = gem_path / 'gem.json' - if not pathlib.Path(gem_json).is_file(): - logger.warning(f'{gem_json} does not exist') - else: - with gem_json.open('r') as f: - try: - gem_json_data = json.load(f) - except json.JSONDecodeError as e: - logger.warning(f'{gem_json} failed to load: {str(e)}') - else: - this_gems_name = gem_json_data['gem_name'] - if this_gems_name == gem_name: - return gem_path + with gem_json.open('r') as f: + try: + gem_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{gem_json} failed to load: {str(e)}') + else: + this_gems_name = gem_json_data['gem_name'] + if this_gems_name == gem_name: + return gem_path elif isinstance(template_name, str): templates = get_all_templates(project_path) for template_path in templates: template_path = pathlib.Path(template_path).resolve() template_json = template_path / 'template.json' - if not pathlib.Path(template_json).is_file(): - logger.warning(f'{template_json} does not exist') - else: - with template_json.open('r') as f: - try: - template_json_data = json.load(f) - except json.JSONDecodeError as e: - logger.warning(f'{template_path} failed to load: {str(e)}') - else: - this_templates_name = template_json_data['template_name'] - if this_templates_name == template_name: - return template_path + with template_json.open('r') as f: + try: + template_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{template_path} failed to load: {str(e)}') + else: + this_templates_name = template_json_data['template_name'] + if this_templates_name == template_name: + return template_path elif isinstance(restricted_name, str): - restricted = get_all_restricted(project_path) + restricted = get_manifest_restricted() for restricted_path in restricted: restricted_path = pathlib.Path(restricted_path).resolve() restricted_json = restricted_path / 'restricted.json' - if not pathlib.Path(restricted_json).is_file(): - logger.warning(f'{restricted_json} does not exist') - else: - with restricted_json.open('r') as f: - try: - restricted_json_data = json.load(f) - except json.JSONDecodeError as e: - logger.warning(f'{restricted_json} failed to load: {str(e)}') - else: - this_restricted_name = restricted_json_data['restricted_name'] - if this_restricted_name == restricted_name: - return restricted_path + with restricted_json.open('r') as f: + try: + restricted_json_data = json.load(f) + except json.JSONDecodeError as e: + logger.warning(f'{restricted_json} failed to load: {str(e)}') + else: + this_restricted_name = restricted_json_data['restricted_name'] + if this_restricted_name == restricted_name: + return restricted_path elif isinstance(default_folder, str): if default_folder == 'engines': @@ -720,7 +731,9 @@ def get_registered(engine_name: str = None, elif isinstance(repo_name, str): cache_folder = get_o3de_cache_folder() for repo_uri in json_data['repos']: - cache_file = get_repo_path(repo_uri=repo_uri, cache_folder=cache_folder) + repo_uri = pathlib.Path(repo_uri).resolve() + repo_sha256 = hashlib.sha256(repo_uri.encode()) + cache_file = cache_folder / str(repo_sha256.hexdigest() + '.json') if cache_file.is_file(): repo = pathlib.Path(cache_file).resolve() with repo.open('r') as f: diff --git a/scripts/o3de/o3de/print_registration.py b/scripts/o3de/o3de/print_registration.py index 77e098d0ba..2bd3202ca0 100644 --- a/scripts/o3de/o3de/print_registration.py +++ b/scripts/o3de/o3de/print_registration.py @@ -39,69 +39,68 @@ def get_project_path(project_path: pathlib.Path, project_name: str) -> pathlib.P return project_path -def print_this_engine(verbose: int) -> int: +def print_this_engine(verbose: int = 0) -> int: this_engine_path = manifest.get_this_engine_path() print(f'This Engine:\n{json.dumps(str(this_engine_path), indent=4)}') if verbose > 0: return print_manifest_json_data([this_engine_path], 'This Engine', - manifest.get_engine_json_data, 'engine_path') + manifest.get_engine_json_data, 'engine_path') return 0 -def print_engines(verbose: int) -> None: - engines_data = manifest.get_engines() +def print_engines(verbose: int = 0) -> int: + engines_data = manifest.get_manifest_engines() print(f'Engine Paths:\n{json.dumps(engines_data, indent=4)}') if verbose > 0: return print_manifest_json_data(engines_data, 'Engine Jsons', - manifest.get_engine_json_data, 'engine_path') + manifest.get_engine_json_data, 'engine_path') return 0 -def print_projects(verbose: int) -> int: - projects_data = manifest.get_projects() +def print_projects(verbose: int = 0) -> int: + projects_data = manifest.get_all_projects() print(f'Project Paths:\n{json.dumps(projects_data, indent=4)}') if verbose > 0: return print_manifest_json_data(projects_data, 'Project Jsons', - manifest.get_project_json_data, 'project_path') + manifest.get_project_json_data, 'project_path') return 0 -def print_gems(verbose: int) -> int: - gems_data = manifest.get_gems() +def print_gems(verbose: int = 0) -> int: + gems_data = manifest.get_all_gems() print(f'Gem Paths:\n{json.dumps(gems_data, indent=4)}') if verbose > 0: return print_manifest_json_data(gems_data, 'Gem Jsons', - manifest.get_gem_json_data, 'gem_path') + manifest.get_gem_json_data, 'gem_path') return 0 -def print_external_subdirectories(verbose: int) -> int: - external_subdirs_data = manifest.get_external_subdirectories() +def print_external_subdirectories(verbose: int = 0) -> int: + external_subdirs_data = manifest.get_all_external_subdirectories() print(f'External Subdirectories:\n{json.dumps(external_subdirs_data, indent=4)}') return 0 - def print_templates(verbose: int) -> int: - templates_data = manifest.get_templates() + templates_data = manifest.get_all_templates() print(f'Template Paths:\n{json.dumps(templates_data, indent=4)}') if verbose > 0: return print_manifest_json_data(templates_data, 'Template Jsons', - manifest.get_template_json_data, 'template_path') + manifest.get_template_json_data, 'template_path') return 0 def print_restricted(verbose: int) -> int: - restricted_data = manifest.get_restricted() + restricted_data = manifest.get_manifest_restricted() print(f'Restricted Paths:\n{json.dumps(restricted_data, indent=4)}') if verbose > 0: return print_manifest_json_data(restricted_data, 'Restricted Jsons', - manifest.get_restricted_json_data, 'restricted_path') + manifest.get_restricted_json_data, 'restricted_path') return 0 @@ -112,7 +111,7 @@ def print_engine_projects(verbose: int) -> int: if verbose > 0: return print_manifest_json_data(engine_projects_data, 'Project Jsons', - manifest.get_project_json_data, 'project_path') + manifest.get_project_json_data, 'project_path') return 0 @@ -122,7 +121,7 @@ def print_engine_gems(verbose: int) -> int: if verbose > 0: return print_manifest_json_data(engine_gems_data, 'Gem Jsons', - manifest.get_gem_json_data, 'gem_path') + manifest.get_gem_json_data, 'gem_path') return 0 @@ -132,17 +131,7 @@ def print_engine_templates(verbose: int) -> int: if verbose > 0: return print_manifest_json_data(engine_templates_data, 'Template Jsons', - manifest.get_template_json_data, 'template_path') - return 0 - - -def print_engine_restricted(verbose: int) -> int: - engine_restricted_data = manifest.get_engine_restricted() - print(f'Restricted Paths:\n{json.dumps(engine_restricted_data, indent=4)}') - - if verbose > 0: - return print_manifest_json_data(engine_restricted_data, 'Restricted Jsons', - manifest.get_restricted_json_data, 'restricted_path') + manifest.get_template_json_data, 'template_path') return 0 @@ -153,21 +142,6 @@ def print_engine_external_subdirectories(verbose: int) -> int: # Project output methods -def print_project_engine_name(verbose: int, project_path: pathlib.Path, project_name: str) -> int: - project_path = get_project_path(project_path, project_name) - if not project_path: - return 1 - - engine_name = manifest.get_project_engine_name(project_path) - if engine_name: - print(f'Project\'s engine name:\n{engine_name}') - return 0 - - if verbose > 0: - logger.info(f'project.json at path "{project_path}" contains no registered "engine" field') - return 1 - - def print_project_gems(verbose: int, project_path: pathlib.Path, project_name: str) -> int: project_path = get_project_path(project_path, project_name) if not project_path: @@ -178,7 +152,7 @@ def print_project_gems(verbose: int, project_path: pathlib.Path, project_name: s if verbose > 0: return print_manifest_json_data(project_gems_data, 'Gems Jsons', - manifest.get_gem_json_data, 'gem_path') + manifest.get_gem_json_data, 'gem_path') return 0 @@ -201,20 +175,7 @@ def print_project_templates(verbose: int, project_path: pathlib.Path, project_na print(f'Template Paths:\n{json.dumps(project_templates_data, indent=4)}') if verbose > 0: return print_manifest_json_data(project_templates_data, 'Template Jsons', - manifest.get_template_json_data, 'template_path') - return 0 - - -def print_project_restricted(verbose: int, project_path: pathlib.Path, project_name: str) -> int: - project_path = get_project_path(project_path, project_name) - if not project_path: - return 1 - - project_restricted_data = manifest.get_project_restricted(project_path) - print(f'Restricted Paths:\n{json.dumps(project_restricted_data, indent=4)}') - if verbose > 0: - return print_manifest_json_data(project_restricted_data, 'Restricted Jsons', - manifest.get_restricted_json_data, 'restricted_path') + manifest.get_template_json_data, 'template_path') return 0 @@ -224,12 +185,12 @@ def print_all_projects(verbose: int) -> int: if verbose > 0: return print_manifest_json_data(all_projects_data, 'Project Jsons', - manifest.get_project_json_data, 'project_path') + manifest.get_project_json_data, 'project_path') return 0 def print_all_gems(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: - all_gems = manifest.get_gems() + all_gems = manifest.get_manifest_gems() all_gems.extend(manifest.get_engine_gems()) # If a project path or project name is supplied query the gems from that project, otherwise query the gems from @@ -245,12 +206,12 @@ def print_all_gems(verbose: int, project_path: pathlib.Path = None, project_name if verbose > 0: return print_manifest_json_data(all_gems, 'Gem Jsons', - manifest.get_gem_json_data, 'gem_path') + manifest.get_gem_json_data, 'gem_path') return 0 def print_all_external_subdirectories(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: - all_external_subdirectories = manifest.get_external_subdirectories() + all_external_subdirectories = manifest.get_manifest_external_subdirectories() all_external_subdirectories.extend(manifest.get_engine_external_subdirectories()) # If a project path or project name is supplied query the external subdirectories from that project, @@ -267,7 +228,7 @@ def print_all_external_subdirectories(verbose: int, project_path: pathlib.Path = def print_all_templates(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: - all_templates = manifest.get_templates() + all_templates = manifest.get_manifest_templates() all_templates.extend(manifest.get_engine_templates()) # If a project path or project name is supplied query the templates from that project, @@ -283,31 +244,9 @@ def print_all_templates(verbose: int, project_path: pathlib.Path = None, project if verbose > 0: return print_manifest_json_data(all_templates, 'Template Jsons', - manifest.get_template_json_data, 'template_path') + manifest.get_template_json_data, 'template_path') return 0 - -def print_all_restricted(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: - all_restricted = manifest.get_restricted() - all_restricted.extend(manifest.get_engine_restricted()) - - # If a project path or project name is supplied query the restricted from that project, - # otherwise query the restricted from all projects - project_path = get_project_path(project_path, project_name) if project_path or project_name else None - projects = [project_path] if project_path else manifest.get_all_projects() - for project in projects: - all_restricted.extend(manifest.get_project_restricted(project)) - - # Filter out duplicates - all_restricted = list(dict.fromkeys(all_restricted)) - print(f'Restricted Paths:\n{json.dumps(all_restricted, indent=4)}') - - if verbose > 0: - return print_manifest_json_data(all_restricted, 'Restricted Jsons', - manifest.get_restricted_json_data, 'restricted_path') - return 0 - - def print_manifest_json_data(uri_json_data: list, print_prefix: str, get_json_func: callable, get_json_data_kw: str) -> int: print('\n') @@ -351,7 +290,7 @@ def print_repos_data(repos_data: dict) -> int: def print_repos(verbose: int) -> int: - repos_data = manifest.get_repos() + repos_data = manifest.get_manifest_repos() print(json.dumps(repos_data, indent=4)) if verbose > 0: @@ -370,16 +309,13 @@ def register_show(verbose: int, project_path: pathlib.Path = None, project_name: result = print_all_projects(verbose) or result result = print_all_gems(verbose, project_path, project_name) or result result = print_all_templates(verbose, project_path, project_name) or result - result = print_all_restricted(verbose, project_path, project_name) or result + result = print_restricted(verbose) or result result = print_repos(verbose) or result return result def _run_register_show(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - if args.this_engine: return print_this_engine(args.verbose) elif args.engines: @@ -393,7 +329,7 @@ def _run_register_show(args: argparse) -> int: elif args.templates: return print_templates(args.verbose) elif args.repos: - return register_show_repos(args.verbose) + return print_repos(args.verbose) elif args.restricted: return print_restricted(args.verbose) @@ -405,8 +341,6 @@ def _run_register_show(args: argparse) -> int: return print_engine_external_subdirectories(args.verbose) elif args.engine_templates: return print_engine_templates(args.verbose) - elif args.engine_restricted: - return print_engine_restricted(args.verbose) elif args.project_gems: return print_project_gems(args.verbose, args.project_path, args.project_name) @@ -414,8 +348,6 @@ def _run_register_show(args: argparse) -> int: return print_project_external_subdirectories(args.verbose, args.project_path, args.project_name) elif args.project_templates: return print_project_templates(args.verbose, args.project_path, args.project_name) - elif args.project_restricted: - return print_project_restricted(args.verbose, args.project_path, args.project_name) elif args.project_engine_name: return print_project_engine_name(args.verbose, args.project_path, args.project_name) @@ -427,8 +359,6 @@ def _run_register_show(args: argparse) -> int: return print_all_external_subdirectories(args.verbose, args.project_path, args.project_name) elif args.all_templates: return print_all_templates(args.verbose, args.project_path, args.project_name) - elif args.all_restricted: - return print_all_restricted(args.verbose, args.project_path, args.project_name) else: return register_show(args.verbose, args.project_path, args.project_name) @@ -538,9 +468,6 @@ def add_parser_args(parser): project_group.add_argument('-pn', '--project-name', type=str, help='The name of a project.') - parser.add_argument('-ohf', '--override-home-folder', type=str, required=False, - help='By default the home folder is the user folder, override it to this folder.') - parser.set_defaults(func=_run_register_show) diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index a175104997..926c413521 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -490,7 +490,7 @@ def register_repo(json_data: dict, repo_sha256 = hashlib.sha256(url.encode()) cache_file = manifest.get_o3de_cache_folder() / str(repo_sha256.hexdigest() + '.json') - result = utils.download_file(parsed_uri, cache_file, True) + result = utils.download_file(url, cache_file, True) if result == 0: json_data.setdefault('repos', []).insert(0, repo_uri) @@ -793,9 +793,6 @@ def register(engine_path: pathlib.Path = None, def _run_register(args: argparse) -> int: - if args.override_home_folder: - manifest.override_home_folder = args.override_home_folder - if args.update: remove_invalid_o3de_objects() return repo.refresh_repos() @@ -891,8 +888,6 @@ def add_parser_args(parser): default=False, help='Refresh the repo cache.') - parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False, - help='By default the home folder is the user folder, override it to this folder.') parser.add_argument('-r', '--remove', action='store_true', required=False, default=False, help='Remove entry.') diff --git a/scripts/o3de/tests/unit_test_enable_gem.py b/scripts/o3de/tests/unit_test_enable_gem.py index c765f74731..8067fc329d 100644 --- a/scripts/o3de/tests/unit_test_enable_gem.py +++ b/scripts/o3de/tests/unit_test_enable_gem.py @@ -42,8 +42,10 @@ TEST_GEM_JSON_PAYLOAD = ''' { "gem_name": "TestGem", "display_name": "TestGem", - "license": "What license TestGem uses goes here: i.e. https://opensource.org/licenses/MIT", - "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", + "license": "Apache-2.0 Or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/o3de", "type": "Code", "summary": "A short description of TestGem.", "canonical_tags": [ @@ -53,7 +55,10 @@ TEST_GEM_JSON_PAYLOAD = ''' "TestGem" ], "icon_path": "preview.png", - "requirements": "" + "requirements": "Any requirement goes here.", + "documentation_url": "The link to the documentation goes here.", + "dependencies": [ + ] } ''' diff --git a/scripts/o3de/tests/unit_test_engine_template.py b/scripts/o3de/tests/unit_test_engine_template.py index ed1c8258d3..da23ee11f1 100755 --- a/scripts/o3de/tests/unit_test_engine_template.py +++ b/scripts/o3de/tests/unit_test_engine_template.py @@ -93,37 +93,28 @@ TEST_TEMPLATE_JSON_CONTENTS = """\ "copyFiles": [ { "file": "Code/Include/${Name}/${Name}Bus.h", - "origin": "Code/Include/${Name}/${Name}Bus.h", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { - "file": "Code/Include/Platform/Salem/${Name}Bus.h", - "origin": "Code/Include/Platform/Salem/${Name}Bus.h", - "isTemplated": true, - "isOptional": false + "file": "Code/Include/Platform/Windows/${Name}Bus.h", + "isTemplated": true } ], "createDirectories": [ { - "dir": "Code", - "origin": "Code" + "dir": "Code" }, { - "dir": "Code/Include", - "origin": "Code/Include" + "dir": "Code/Include" }, { - "dir": "Code/Include/${Name}", - "origin": "Code/Include/${Name}" + "dir": "Code/Include/${Name}" }, { - "dir": "Code/Include/Platform", - "origin": "Code/Include/Platform" + "dir": "Code/Include/Platform" }, { - "dir": "Code/Include/Platform/Salem", - "origin": "Code/Include/Platform/Salem" + "dir": "Code/Include/Platform/Windows" } ] } @@ -174,10 +165,10 @@ def test_create_template(tmpdir, with gem_bus_file.open('w') as s: s.write(concrete_contents) - engine_gem_code_include_platform_salem = template_source_path / 'Code/Include/Platform/Salem' - engine_gem_code_include_platform_salem.mkdir(parents=True, exist_ok=True) + engine_gem_code_include_platform_windows = template_source_path / 'Code/Include/Platform/Windows' + engine_gem_code_include_platform_windows.mkdir(parents=True, exist_ok=True) - restricted_gem_bus_file = engine_gem_code_include_platform_salem / 'TestTemplateBus.h' + restricted_gem_bus_file = engine_gem_code_include_platform_windows / 'TestTemplateBus.h' with restricted_gem_bus_file.open('w') as s: s.write(concrete_contents) @@ -209,9 +200,9 @@ def test_create_template(tmpdir, else: assert s_data == templated_contents_without_license - platform_template_folder = engine_root / 'Salem/Templates' + platform_template_folder = engine_root / 'Windows/Templates' - new_platform_default_name_bus_file = template_content_folder / 'Code/Include/Platform/Salem/${Name}Bus.h' + new_platform_default_name_bus_file = template_content_folder / 'Code/Include/Platform/Windows/${Name}Bus.h' assert new_platform_default_name_bus_file.is_file() with new_platform_default_name_bus_file.open('r') as s: s_data = s.read() @@ -255,7 +246,7 @@ class TestCreateTemplate: s.write(templated_contents) template_content_folder = template_default_folder / 'Template' - platform_default_name_bus_dir = template_content_folder / 'Code/Include/Platform/Salem' + platform_default_name_bus_dir = template_content_folder / 'Code/Include/Platform/Windows' platform_default_name_bus_dir.mkdir(parents=True, exist_ok=True) platform_default_name_bus_file = platform_default_name_bus_dir / '${Name}Bus.h' @@ -263,10 +254,13 @@ class TestCreateTemplate: s.write(templated_contents) template_dest_path = engine_root / instantiated_name - # Skip registeration in test + # Skip registration in test with patch('uuid.uuid4', return_value=uuid.uuid5(uuid.NAMESPACE_DNS, instantiated_name)) as uuid4_mock: - result = create_from_template_func(template_dest_path, template_path=template_default_folder, force=True, - keep_license_text=keep_license_text, **create_from_template_kwargs) + result = create_from_template_func(template_dest_path, + template_path=template_default_folder, + keep_license_text=keep_license_text, + force=True, + **create_from_template_kwargs) if expect_failure: assert result != 0 else: @@ -281,7 +275,7 @@ class TestCreateTemplate: s_data = s.read() assert s_data == concrete_contents - platform_test_bus_folder = test_folder / 'Code/Include/Platform/Salem' + platform_test_bus_folder = test_folder / 'Code/Include/Platform/Windows' assert platform_test_bus_folder.is_dir() platform_default_name_bus_file = platform_test_bus_folder / f'{instantiated_name}Bus.h' @@ -338,9 +332,7 @@ class TestCreateTemplate: template_json_dict.setdefault('copyFiles', []).append( { "file": "project.json", - "origin": "project.json", - "isTemplated": True, - "isOptional": False + "isTemplated": True }) # Convert the python dictionary back into a json string template_json_contents = json.dumps(template_json_dict, indent=4) @@ -376,9 +368,7 @@ class TestCreateTemplate: template_json_dict.setdefault('copyFiles', []).append( { "file": "gem.json", - "origin": "gem.json", - "isTemplated": True, - "isOptional": False + "isTemplated": True }) #Convert dict back to string template_json_contents = json.dumps(template_json_dict, indent=4) diff --git a/scripts/o3de/tests/unit_test_gem_properties.py b/scripts/o3de/tests/unit_test_gem_properties.py index dee5811b65..6358917852 100644 --- a/scripts/o3de/tests/unit_test_gem_properties.py +++ b/scripts/o3de/tests/unit_test_gem_properties.py @@ -18,10 +18,9 @@ TEST_GEM_JSON_PAYLOAD = ''' { "gem_name": "TestGem", "display_name": "TestGem", - "license": "MIT", - "license_url": "https://opensource.org/licenses/MIT", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt", "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", - "type": "Code", "summary": "A short description of TestGem.", "canonical_tags": [ "Gem" @@ -31,7 +30,9 @@ TEST_GEM_JSON_PAYLOAD = ''' ], "icon_path": "preview.png", "requirements": "", - "documentation_url": "https://o3de.org/docs/" + "documentation_url": "https://o3de.org/docs/", + "dependencies": [ + ] } ''' diff --git a/scripts/o3de/tests/unit_test_manifest.py b/scripts/o3de/tests/unit_test_manifest.py index ad4809dc1d..c7d7a7573b 100644 --- a/scripts/o3de/tests/unit_test_manifest.py +++ b/scripts/o3de/tests/unit_test_manifest.py @@ -22,7 +22,7 @@ from o3de import manifest ]) class TestGetTemplatesForCreation: @staticmethod - def get_templates() -> list: + def get_manifest_templates() -> list: return [] @staticmethod @@ -40,20 +40,24 @@ class TestGetTemplatesForCreation: ) def test_get_templates_for_generic_creation(self, valid_project_json_paths, valid_gem_json_paths, expected_template_paths): - def validate_project_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_project_json_paths + def validate_project_json(project_json_path) -> bool: + return pathlib.Path(project_json_path) in valid_project_json_paths - def validate_gem_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_gem_json_paths + def validate_gem_json(gem_json_path) -> bool: + return pathlib.Path(gem_json_path) in valid_gem_json_paths - with patch('o3de.manifest.get_templates', side_effect=self.get_templates) as get_templates_patch, \ + with patch('o3de.manifest.get_manifest_templates', side_effect=self.get_manifest_templates)\ + as get_manifest_templates_patch, \ patch('o3de.manifest.get_project_templates', side_effect=self.get_project_templates)\ as get_project_templates_patch, \ patch('o3de.manifest.get_engine_templates', side_effect=self.get_engine_templates)\ as get_engine_templates_patch, \ - patch('o3de.validation.valid_o3de_template_json', return_value=True) as validate_template_json,\ - patch('o3de.validation.valid_o3de_project_json', side_effect=validate_project_json) as validate_project_json,\ - patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) as validate_gem_json: + patch('o3de.validation.valid_o3de_template_json', return_value=True) \ + as validate_template_json,\ + patch('o3de.validation.valid_o3de_project_json', side_effect=validate_project_json) \ + as validate_project_json,\ + patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) \ + as validate_gem_json: templates = manifest.get_templates_for_generic_creation() assert templates == expected_template_paths @@ -64,21 +68,24 @@ class TestGetTemplatesForCreation: ) def test_get_templates_for_gem_creation(self, valid_project_json_paths, valid_gem_json_paths, expected_template_paths): - def validate_project_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_project_json_paths + def validate_project_json(project_json_path) -> bool: + return pathlib.Path(project_json_path) in valid_project_json_paths - def validate_gem_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_gem_json_paths + def validate_gem_json(gem_json_path) -> bool: + return pathlib.Path(gem_json_path) in valid_gem_json_paths - with patch('o3de.manifest.get_templates', side_effect=self.get_templates) as get_templates_patch, \ + with patch('o3de.manifest.get_manifest_templates', side_effect=self.get_manifest_templates)\ + as get_manifest_templates_patch, \ patch('o3de.manifest.get_project_templates', side_effect=self.get_project_templates) \ as get_project_templates_patch, \ patch('o3de.manifest.get_engine_templates', side_effect=self.get_engine_templates) \ as get_engine_templates_patch, \ - patch('o3de.validation.valid_o3de_template_json', return_value=True) as validate_template_json, \ - patch('o3de.validation.valid_o3de_project_json', - side_effect=validate_project_json) as validate_project_json, \ - patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) as validate_gem_json: + patch('o3de.validation.valid_o3de_template_json', return_value=True) \ + as validate_template_json, \ + patch('o3de.validation.valid_o3de_project_json', side_effect=validate_project_json) \ + as validate_project_json, \ + patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) \ + as validate_gem_json: templates = manifest.get_templates_for_project_creation() assert templates == expected_template_paths @@ -89,20 +96,23 @@ class TestGetTemplatesForCreation: ) def test_get_templates_for_project_creation(self, valid_project_json_paths, valid_gem_json_paths, expected_template_paths): - def validate_project_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_project_json_paths + def validate_project_json(project_json_path) -> bool: + return pathlib.Path(project_json_path) in valid_project_json_paths - def validate_gem_json(template_path) -> bool: - return pathlib.Path(template_path) in valid_gem_json_paths + def validate_gem_json(gem_json_path) -> bool: + return pathlib.Path(gem_json_path) in valid_gem_json_paths - with patch('o3de.manifest.get_templates', side_effect=self.get_templates) as get_templates_patch, \ + with patch('o3de.manifest.get_manifest_templates', side_effect=self.get_manifest_templates) \ + as get_manifest_templates_patch, \ patch('o3de.manifest.get_project_templates', side_effect=self.get_project_templates) \ as get_project_templates_patch, \ patch('o3de.manifest.get_engine_templates', side_effect=self.get_engine_templates) \ as get_engine_templates_patch, \ - patch('o3de.validation.valid_o3de_template_json', return_value=True) as validate_template_json, \ - patch('o3de.validation.valid_o3de_project_json', - side_effect=validate_project_json) as validate_project_json, \ - patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) as validate_gem_json: + patch('o3de.validation.valid_o3de_template_json', return_value=True) \ + as validate_template_json, \ + patch('o3de.validation.valid_o3de_project_json', side_effect=validate_project_json) \ + as validate_project_json, \ + patch('o3de.validation.valid_o3de_gem_json', side_effect=validate_gem_json) \ + as validate_gem_json: templates = manifest.get_templates_for_gem_creation() assert templates == expected_template_paths \ No newline at end of file diff --git a/scripts/o3de/tests/unit_test_print_registration.py b/scripts/o3de/tests/unit_test_print_registration.py index 7e3e75edcd..d01434c99f 100644 --- a/scripts/o3de/tests/unit_test_print_registration.py +++ b/scripts/o3de/tests/unit_test_print_registration.py @@ -90,27 +90,20 @@ TEST_TEMPLATE_JSON_PAYLOAD = ''' "copyFiles": [ { "file": "CMakeLists.txt", - "origin": "CMakeLists.txt", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "gem.json", - "origin": "gem.json", - "isTemplated": true, - "isOptional": false + "isTemplated": true }, { "file": "preview.png", - "origin": "preview.png", - "isTemplated": false, - "isOptional": false + "isTemplated": false } ], "createDirectories": [ { - "dir": "Assets", - "origin": "Assets" + "dir": "Assets" } ] } @@ -277,13 +270,9 @@ class TestPrintRegistration: # Patch the manifest.py function to locate gem.json files in external subdirectories # to just return a fake path to a single test gem - def get_gems_from_subdirectories(external_subdirs: list) -> list: - return ["D:/TestGem"] - with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ patch('o3de.manifest.get_gem_json_data', side_effect=self.get_gem_json_data) as get_json_patch, \ patch('o3de.manifest.get_project_json_data', side_effect=self.get_project_json_data) as get_project_json_patch, \ - patch('o3de.manifest.get_gems_from_subdirectories', side_effect=get_gems_from_subdirectories) as get_gems_from_subdirs_patch, \ patch('o3de.print_registration.get_project_path', return_value=project_path) as get_project_path_patch: result = print_registration._run_register_show(test_args) assert result == 0 From 284ae60139eef1c69cd8981048dc77c4bd26631a Mon Sep 17 00:00:00 2001 From: moudgils <47460854+moudgils@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:34:57 -0800 Subject: [PATCH 190/272] Add missing 'precise' keyword for Vertex shaders (#6902) Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> --- .../Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl | 4 ++-- .../Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl | 2 +- Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl | 2 +- .../Types/StandardMultilayerPBR_DepthPass_WithPS.azsl | 4 ++-- .../Materials/Types/StandardMultilayerPBR_ForwardPass.azsl | 2 +- .../TestData/Materials/Types/AutoBrick_ForwardPass.azsl | 2 +- .../TestData/Materials/Types/MinimalPBR_ForwardPass.azsl | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl index f2564cf10c..08642decc0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl @@ -28,7 +28,7 @@ struct VSInput struct VSDepthOutput { - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float2 m_uv[UvSetCount] : UV1; // only used for parallax depth calculation @@ -62,7 +62,7 @@ VSDepthOutput MainVS(VSInput IN) struct PSDepthOutput { - float m_depth : SV_Depth; + precise float m_depth : SV_Depth; }; PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 0f9771e480..4b37f67930 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -67,7 +67,7 @@ struct VSInput struct VSOutput { // Base fields (required by the template azsli file)... - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float3 m_normal: NORMAL; float3 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index 523353f8fa..00dee50c93 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -86,7 +86,7 @@ struct VSInput struct VSOutput { // Base fields (required by the template azsli file)... - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float3 m_normal: NORMAL; float3 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl index 39597e2bdd..7875457489 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_DepthPass_WithPS.azsl @@ -41,7 +41,7 @@ struct VSInput struct VSDepthOutput { - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float2 m_uv[UvSetCount] : UV1; // only used for parallax depth calculation @@ -88,7 +88,7 @@ VSDepthOutput MainVS(VSInput IN) struct PSDepthOutput { - float m_depth : SV_Depth; + precise float m_depth : SV_Depth; }; PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 8f58c6dd33..5b05e48d3b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -80,7 +80,7 @@ struct VSInput struct VSOutput { // Base fields (required by the template azsli file)... - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float3 m_normal: NORMAL; float3 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; diff --git a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl index 2dbba46d8b..05ce5f4774 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/AutoBrick_ForwardPass.azsl @@ -28,7 +28,7 @@ struct VSInput struct VSOutput { - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float3 m_normal: NORMAL; float3 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; diff --git a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl index 2f6f038e4b..fe9e4099d0 100644 --- a/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl +++ b/Gems/Atom/TestData/TestData/Materials/Types/MinimalPBR_ForwardPass.azsl @@ -33,7 +33,7 @@ struct VSInput struct VSOutput { - float4 m_position : SV_Position; + precise linear centroid float4 m_position : SV_Position; float3 m_normal: NORMAL; float3 m_tangent : TANGENT; float3 m_bitangent : BITANGENT; From bbfe740cc9c9eb1772aa35f76a1ba0a98606f9c7 Mon Sep 17 00:00:00 2001 From: allisaurus <34254888+allisaurus@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:52:32 -0800 Subject: [PATCH 191/272] Disable flaky HttpRequestor test (#6866) Signed-off-by: allisaurus <34254888+allisaurus@users.noreply.github.com> --- Gems/HttpRequestor/Code/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/HttpRequestor/Code/CMakeLists.txt b/Gems/HttpRequestor/Code/CMakeLists.txt index 4ebca5518c..56d3527e24 100644 --- a/Gems/HttpRequestor/Code/CMakeLists.txt +++ b/Gems/HttpRequestor/Code/CMakeLists.txt @@ -71,5 +71,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::HttpRequestor.Tests + TEST_SUITE sandbox ) endif() From 7680d1f9d0ea0b2ac2a5f073ba5329f8b7080033 Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Fri, 14 Jan 2022 11:28:21 -0800 Subject: [PATCH 192/272] [development] fixed issue with dangling budget pointers if the budget tracker is torn down and rebuilt (#6801) Signed-off-by: AMZN-ScottR 24445312+AMZN-ScottR@users.noreply.github.com --- .../AzCore/Component/ComponentApplication.cpp | 10 +++++---- Code/Framework/AzCore/AzCore/Debug/Budget.h | 16 +++++++++----- .../AzCore/AzCore/Debug/BudgetTracker.cpp | 22 +++++++++++++------ .../AzCore/AzCore/Debug/BudgetTracker.h | 4 ++-- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index 693b2f1648..72b6e807d2 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -565,10 +565,6 @@ namespace AZ m_entityActivatedEvent.DisconnectAllHandlers(); m_entityDeactivatedEvent.DisconnectAllHandlers(); -#if !defined(_RELEASE) - m_budgetTracker.Reset(); -#endif - DestroyAllocator(); } @@ -758,6 +754,12 @@ namespace AZ static_cast(m_settingsRegistry.get())->ClearNotifiers(); static_cast(m_settingsRegistry.get())->ClearMergeEvents(); +#if !defined(_RELEASE) + // the budget tracker must be cleaned up prior to module unloading to ensure + // budgets initialized cross boundary are freed properly + m_budgetTracker.Reset(); +#endif + // Uninit and unload any dynamic modules. m_moduleManager->UnloadModules(); ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "GemsUnloaded", R"({})"); diff --git a/Code/Framework/AzCore/AzCore/Debug/Budget.h b/Code/Framework/AzCore/AzCore/Debug/Budget.h index 4646ef8b2c..c909302886 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Budget.h +++ b/Code/Framework/AzCore/AzCore/Debug/Budget.h @@ -62,12 +62,16 @@ namespace AZ::Debug // // Anywhere the budget is used, the budget must be declared (either in a header or in the source file itself) // AZ_DECLARE_BUDGET(AzCore); -#define AZ_DEFINE_BUDGET(name) \ - ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() \ - { \ - constexpr static uint32_t crc = AZ_CRC_CE(#name); \ - static ::AZ::Debug::Budget* budget = ::AZ::Debug::BudgetTracker::GetBudgetFromEnvironment(#name, crc); \ - return budget; \ +#define AZ_DEFINE_BUDGET(name) \ + ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() \ + { \ + static ::AZ::Debug::Budget* budget = nullptr; \ + if (budget == nullptr) \ + { \ + constexpr static uint32_t crc = AZ_CRC_CE(#name); \ + ::AZ::Debug::BudgetTracker::GetBudgetFromEnvironment(budget, #name, crc); \ + } \ + return budget; \ } #endif diff --git a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp index 2dac9a566e..faadbfc31a 100644 --- a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp @@ -13,23 +13,24 @@ #include #include #include +#include #include namespace AZ::Debug { struct BudgetTracker::BudgetTrackerImpl { - AZStd::unordered_map m_budgets; + AZStd::unordered_map m_budgets; + AZStd::unordered_set m_externalBudgetRefs; }; - Budget* BudgetTracker::GetBudgetFromEnvironment(const char* budgetName, uint32_t crc) + void BudgetTracker::GetBudgetFromEnvironment(Budget*& extBudgetRef, const char* budgetName, uint32_t crc) { BudgetTracker* tracker = Interface::Get(); if (tracker) { - return &tracker->GetBudget(budgetName, crc); + tracker->GetBudget(extBudgetRef, budgetName, crc); } - return nullptr; } BudgetTracker::~BudgetTracker() @@ -54,17 +55,24 @@ namespace AZ::Debug if (m_impl) { Interface::Unregister(this); + + for (auto budgetRef : m_impl->m_externalBudgetRefs) + { + *budgetRef = nullptr; + } + delete m_impl; m_impl = nullptr; } } - Budget& BudgetTracker::GetBudget(const char* budgetName, uint32_t crc) + void BudgetTracker::GetBudget(Budget*& extBudgetRef, const char* budgetName, uint32_t crc) { AZStd::scoped_lock lock{ m_mutex }; - auto it = m_impl->m_budgets.try_emplace(budgetName, budgetName, crc).first; + m_impl->m_externalBudgetRefs.insert(&extBudgetRef); - return it->second; + auto iter = m_impl->m_budgets.try_emplace(budgetName, budgetName, crc).first; + extBudgetRef = &iter->second; } } // namespace AZ::Debug diff --git a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h index 34d8510349..69e8185746 100644 --- a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h +++ b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h @@ -20,7 +20,7 @@ namespace AZ::Debug { public: AZ_TYPE_INFO(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}"); - static Budget* GetBudgetFromEnvironment(const char* budgetName, uint32_t crc); + static void GetBudgetFromEnvironment(Budget*& extBudgetRef, const char* budgetName, uint32_t crc); ~BudgetTracker(); @@ -28,7 +28,7 @@ namespace AZ::Debug bool Init(); void Reset(); - Budget& GetBudget(const char* budgetName, uint32_t crc); + void GetBudget(Budget*& extBudgetRef, const char* budgetName, uint32_t crc); private: struct BudgetTrackerImpl; From c403fa3db6d3dc8653c8f5908b6cbb908636c2c7 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Fri, 14 Jan 2022 13:30:45 -0600 Subject: [PATCH 193/272] More GetValues() overrides (#6896) * Benchmarks and tests for Image and Constant GetValues Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Verify GetValues for Perlin and Random Gradients Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Standardized the assert format for GetValues(). Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * More GetValues unit tests and test cleanup Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed typos Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * GetValues() unit tests for surface gradients. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Benchmarks for ShapeAreaFalloff Gradient Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for all remaining gradients and cleaned up the helper methods. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Renamed class for better report formatting. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added missing Mocks dependencies for the Editor tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * First batch of specific GetValues() overrides. Each one is measurably faster than the generic version. Also, in ShapeAreaFalloffGradient, I optimized and simplified the logic a bit, so GetValue() is marginally faster too. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Change GetValues() to use span and add more overrides. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Convert GetValues() to use AZStd::span and added more overrides. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add missing include. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * PR feedback - switch to fill Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed the logic and added unit tests and comments. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../AzCore/AzCore/std/containers/span.h | 2 +- .../AzCore/AzCore/std/containers/span.inl | 2 +- Gems/GradientSignal/Code/CMakeLists.txt | 5 - .../Components/ConstantGradientComponent.h | 2 +- .../Components/DitherGradientComponent.h | 8 + .../Components/ImageGradientComponent.h | 2 +- .../Components/InvertGradientComponent.h | 1 + .../Components/LevelsGradientComponent.h | 1 + .../Components/PerlinGradientComponent.h | 2 +- .../Components/RandomGradientComponent.h | 2 +- .../ShapeAreaFalloffGradientComponent.h | 2 +- .../Ebuses/GradientRequestBus.h | 11 +- .../Include/GradientSignal/GradientSampler.h | 20 +-- .../Code/Include/GradientSignal/Util.h | 60 ++++++-- .../Components/ConstantGradientComponent.cpp | 8 +- .../Components/DitherGradientComponent.cpp | 140 +++++++++++------- .../Components/ImageGradientComponent.cpp | 10 +- .../Components/InvertGradientComponent.cpp | 15 ++ .../Components/LevelsGradientComponent.cpp | 17 ++- .../Components/PerlinGradientComponent.cpp | 10 +- .../Components/RandomGradientComponent.cpp | 10 +- .../ShapeAreaFalloffGradientComponent.cpp | 13 +- .../Tests/GradientSignalGetValuesTests.cpp | 6 +- .../Tests/GradientSignalServicesTests.cpp | 126 ++++++++++++++++ 24 files changed, 331 insertions(+), 144 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.h b/Code/Framework/AzCore/AzCore/std/containers/span.h index 8f68e921d8..5bb51bf481 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/span.h +++ b/Code/Framework/AzCore/AzCore/std/containers/span.h @@ -59,7 +59,7 @@ namespace AZStd constexpr span(pointer s, size_type length); - constexpr span(pointer first, const_pointer last); + constexpr span(pointer first, pointer last); // We explicitly delete this constructor because it's too easy to accidentally // create a span to just the first element instead of an entire array. diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.inl b/Code/Framework/AzCore/AzCore/std/containers/span.inl index c33e4a7227..01bab9a5a4 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/span.inl +++ b/Code/Framework/AzCore/AzCore/std/containers/span.inl @@ -24,7 +24,7 @@ namespace AZStd } template - inline constexpr span::span(pointer first, const_pointer last) + inline constexpr span::span(pointer first, pointer last) : m_begin(first) , m_end(last) { } diff --git a/Gems/GradientSignal/Code/CMakeLists.txt b/Gems/GradientSignal/Code/CMakeLists.txt index d4cf666630..d2d8f8c696 100644 --- a/Gems/GradientSignal/Code/CMakeLists.txt +++ b/Gems/GradientSignal/Code/CMakeLists.txt @@ -19,7 +19,6 @@ ly_add_target( BUILD_DEPENDENCIES PUBLIC AZ::AzCore - AZ::AtomCore AZ::AzFramework Gem::SurfaceData Gem::ImageProcessingAtom.Headers @@ -41,7 +40,6 @@ ly_add_target( Gem::LmbrCentral PUBLIC AZ::AzCore - AZ::AtomCore Gem::GradientSignal.Static Gem::ImageProcessingAtom.Headers # Atom/ImageProcessing/PixelFormats.h is part of a header in Includes RUNTIME_DEPENDENCIES @@ -73,7 +71,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) PUBLIC 3rdParty::Qt::Widgets AZ::AzCore - AZ::AtomCore AZ::AzFramework AZ::AzToolsFramework AZ::AssetBuilderSDK @@ -97,8 +94,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) PRIVATE Gem::GradientSignal.Editor.Static Gem::LmbrCentral.Editor - PUBLIC - AZ::AtomCore RUNTIME_DEPENDENCIES Gem::LmbrCentral.Editor ) diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h index af896f0933..1ed06a976a 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h @@ -62,7 +62,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h index ed12ec2ff7..add6de06cf 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h @@ -77,6 +77,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; ////////////////////////////////////////////////////////////////////////// @@ -102,6 +103,13 @@ namespace GradientSignal GradientSampler& GetGradientSampler() override; private: + static int ScaledPositionToPatternIndex(const AZ::Vector3& scaledPosition, int patternSize); + static float GetDitherValue4x4(const AZ::Vector3& scaledPosition); + static float GetDitherValue8x8(const AZ::Vector3& scaledPosition); + + float GetCalculatedPointsPerUnit() const; + float GetDitherValue(const AZ::Vector3& scaledPosition, float value) const; + DitherGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; }; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h index 9fc98124cb..79d42ec478 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h @@ -69,7 +69,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; // AZ::Data::AssetBus overrides... void OnAssetReady(AZ::Data::Asset asset) override; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h index 79dbea975b..a370286b0b 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h @@ -64,6 +64,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h index 5e70adfe32..093f84ef3a 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h @@ -69,6 +69,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h index 1b39f7f17b..19f3fe7294 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h @@ -70,7 +70,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; private: PerlinGradientConfig m_configuration; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h index 274442a2c0..328fed5118 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h @@ -61,7 +61,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; private: RandomGradientConfig m_configuration; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h index df86c38069..27b2da58a3 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h @@ -69,7 +69,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h index 3a215c5b5d..45b5a173a3 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h @@ -10,8 +10,7 @@ #include #include #include - -#include +#include namespace GradientSignal { @@ -57,7 +56,7 @@ namespace GradientSignal * \param positions The input list of positions to query. * \param outValues The output list of values. This list is expected to be the same size as the positions list. */ - virtual void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + virtual void GetValues(AZStd::span positions, AZStd::span outValues) const { // Reference implementation of GetValues for any gradients that don't have their own optimized implementations. // This is 10%-60% faster than calling GetValue via EBus many times due to the per-call EBus overhead. @@ -72,11 +71,7 @@ namespace GradientSignal for (size_t index = 0; index < positions.size(); index++) { sampleParams.m_position = positions[index]; - - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - outValue = GetValue(sampleParams); + outValues[index] = GetValue(sampleParams); } } diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h index a2e1849590..c9aa7f680c 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h @@ -33,7 +33,7 @@ namespace GradientSignal static void Reflect(AZ::ReflectContext* context); inline float GetValue(const GradientSampleParams& sampleParams) const; - inline void GetValues(AZStd::array_view positions, AZStd::array_view outValues) const; + inline void GetValues(AZStd::span positions, AZStd::span outValues) const; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const; @@ -147,18 +147,12 @@ namespace GradientSignal return output * m_opacity; } - inline void GradientSampler::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + inline void GradientSampler::GetValues(AZStd::span positions, AZStd::span outValues) const { - auto ClearOutputValues = [](AZStd::array_view outValues) + auto ClearOutputValues = [](AZStd::span outValues) { // If we don't have a valid gradient (or it is fully transparent), clear out all the output values. - for (size_t index = 0; index < outValues.size(); index++) - { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - outValue = 0.0f; - } + memset(outValues.data(), 0, outValues.size() * sizeof(float)); }; if (m_opacity <= 0.0f || !m_gradientId.IsValid()) @@ -214,12 +208,8 @@ namespace GradientSignal } // Perform any post-fetch transformations on the gradient values (invert, levels, opacity). - for (size_t index = 0; index < outValues.size(); index++) + for (auto& outValue : outValues) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - if (m_invertInput) { outValue = 1.0f - outValue; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Util.h b/Gems/GradientSignal/Code/Include/GradientSignal/Util.h index fa1791c053..f91c5d54f1 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Util.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Util.h @@ -7,11 +7,12 @@ */ #pragma once +#include #include #include -#include #include #include +#include #include #include @@ -53,28 +54,61 @@ namespace GradientSignal inline float GetLevels(float input, float inputMid, float inputMin, float inputMax, float outputMin, float outputMax) { - input = AZ::GetClamp(input, 0.0f, 1.0f); - inputMid = AZ::GetClamp(inputMid, 0.01f, 10.0f); // Clamp the midpoint to a non-zero value so that it's always safe to divide by it. + inputMid = AZ::GetClamp(inputMid, 0.01f, 10.0f); // Clamp the midpoint to a non-zero value so that it's always safe to divide by it. inputMin = AZ::GetClamp(inputMin, 0.0f, 1.0f); inputMax = AZ::GetClamp(inputMax, 0.0f, 1.0f); outputMin = AZ::GetClamp(outputMin, 0.0f, 1.0f); outputMax = AZ::GetClamp(outputMax, 0.0f, 1.0f); - float inputCorrected = 0.0f; if (inputMin == inputMax) { - inputCorrected = (input <= inputMin) ? 0.0f : 1.0f; - } - else - { - const float inputRemapped = AZ::GetMin(AZ::GetMax(input - inputMin, 0.0f) / (inputMax - inputMin), 1.0f); - // Note: Some paint programs map the midpoint using 1/mid where low values are dark and high values are light, - // others do the reverse and use mid directly, so low values are light and high values are dark. We've chosen to - // align with 1/mid since it appears to be the more prevalent of the two approaches. - inputCorrected = powf(inputRemapped, 1.0f / inputMid); + return (AZ::GetClamp(input, 0.0f, 1.0f) <= inputMin) ? outputMin : outputMax; } + const float inputMidReciprocal = 1.0f / inputMid; + const float inputExtentsReciprocal = 1.0f / (inputMax - inputMin); + + const float inputRemapped = + AZ::GetMin(AZ::GetMax(AZ::GetClamp(input, 0.0f, 1.0f) - inputMin, 0.0f) * inputExtentsReciprocal, 1.0f); + + // Note: Some paint programs map the midpoint using 1/mid where low values are dark and high values are light, + // others do the reverse and use mid directly, so low values are light and high values are dark. We've chosen to + // align with 1/mid since it appears to be the more prevalent of the two approaches. + const float inputCorrected = powf(inputRemapped, inputMidReciprocal); + return AZ::Lerp(outputMin, outputMax, inputCorrected); } + inline void GetLevels(AZStd::span inOutValues, float inputMid, float inputMin, float inputMax, float outputMin, float outputMax) + { + inputMid = AZ::GetClamp(inputMid, 0.01f, 10.0f); // Clamp the midpoint to a non-zero value so that it's always safe to divide by it. + inputMin = AZ::GetClamp(inputMin, 0.0f, 1.0f); + inputMax = AZ::GetClamp(inputMax, 0.0f, 1.0f); + outputMin = AZ::GetClamp(outputMin, 0.0f, 1.0f); + outputMax = AZ::GetClamp(outputMax, 0.0f, 1.0f); + + if (inputMin == inputMax) + { + for (auto& inOutValue : inOutValues) + { + inOutValue = (AZ::GetClamp(inOutValue, 0.0f, 1.0f) <= inputMin) ? outputMin : outputMax; + } + } + + const float inputMidReciprocal = 1.0f / inputMid; + const float inputExtentsReciprocal = 1.0f / (inputMax - inputMin); + + for (auto& inOutValue : inOutValues) + { + const float inputRemapped = + AZ::GetMin(AZ::GetMax(AZ::GetClamp(inOutValue, 0.0f, 1.0f) - inputMin, 0.0f) * inputExtentsReciprocal, 1.0f); + + // Note: Some paint programs map the midpoint using 1/mid where low values are dark and high values are light, + // others do the reverse and use mid directly, so low values are light and high values are dark. We've chosen to + // align with 1/mid since it appears to be the more prevalent of the two approaches. + const float inputCorrected = powf(inputRemapped, inputMidReciprocal); + + inOutValue = AZ::Lerp(outputMin, outputMax, inputCorrected); + } + } } // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp index 2b1487f75e..ac81f616c6 100644 --- a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp @@ -135,7 +135,7 @@ namespace GradientSignal } void ConstantGradientComponent::GetValues( - [[maybe_unused]] AZStd::array_view positions, AZStd::array_view outValues) const + [[maybe_unused]] AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { @@ -143,11 +143,7 @@ namespace GradientSignal return; } - for (auto& outValue : outValues) - { - float& writableOutValue = const_cast(outValue); - writableOutValue = m_configuration.m_value; - } + AZStd::fill(outValues.begin(), outValues.end(), m_configuration.m_value); } float ConstantGradientComponent::GetConstantValue() const diff --git a/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp index c7845a41a6..1b320afeb9 100644 --- a/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp @@ -174,90 +174,122 @@ namespace GradientSignal return false; } - int PositionToMatrixIndex(float position, int patternSize) + int DitherGradientComponent::ScaledPositionToPatternIndex(const AZ::Vector3& scaledPosition, int patternSize) { - int result = static_cast(std::floor(fmod(position, static_cast(patternSize)))); + // The input position is expected to be scaled up so that each integer value is a unique point in our dither pattern, and + // the fractional value is just the amount within the point. The output is the specific index into an NxN pattern to use + // for the dither comparison value. - if (result < 0) - { - result += patternSize; - } + // Get the floor before casting to int because we want fractional negative values to go "down" to the next negative value. + AZ::Vector3 flooredScaledPosition = scaledPosition.GetFloor(); - return result; + // For a pattern of 4, we want our indices to go 0, 1, 2, 3, 0, 1, 2, 3, etc. However, we want it continuous across + // negative and positive positions so we can't just use mod with abs(). Instead, we use a double-mod which gives us + // a result that's continuous across all coordinate space. + const int x = ((static_cast(flooredScaledPosition.GetX()) % patternSize) + patternSize) % patternSize; + const int y = ((static_cast(flooredScaledPosition.GetY()) % patternSize) + patternSize) % patternSize; + + return (patternSize * y + x); } - float GetDitherValue4x4(const AZ::Vector3& position) + float DitherGradientComponent::GetDitherValue4x4(const AZ::Vector3& scaledPosition) { - const int patternSize = 4; - const int patternSizeSq = patternSize * patternSize; - const int indexMatrix[patternSizeSq] = { - 0, 8, 2, 10, - 12, 4, 14, 6, - 3, 11, 1, 9, - 15, 7, 13, 5 }; + constexpr int patternSize = 4; + constexpr float indexMatrix[] = { + 0.0f / 16.0f, 8.0f / 16.0f, 2.0f / 16.0f, 10.0f / 16.0f, + 12.0f / 16.0f, 4.0f / 16.0f, 14.0f / 16.0f, 6.0f / 16.0f, + 3.0f / 16.0f, 11.0f / 16.0f, 1.0f / 16.0f, 9.0f / 16.0f, + 15.0f / 16.0f, 7.0f / 16.0f, 13.0f / 16.0f, 5.0f / 16.0f }; - const int x = PositionToMatrixIndex(position.GetX(), patternSize); - const int y = PositionToMatrixIndex(position.GetY(), patternSize); - - return indexMatrix[patternSize * y + x] / static_cast(patternSizeSq); + return indexMatrix[ScaledPositionToPatternIndex(scaledPosition, patternSize)]; } - float GetDitherValue8x8(const AZ::Vector3& position) + float DitherGradientComponent::GetDitherValue8x8(const AZ::Vector3& scaledPosition) { - const int patternSize = 8; - const int patternSizeSq = patternSize * patternSize; - const int indexMatrix[patternSizeSq] = { - 0, 32, 8, 40, 2, 34, 10, 42, - 48, 16, 56, 24, 50, 18, 58, 26, - 12, 44, 4, 36, 14, 46, 6, 38, - 60, 28, 52, 20, 62, 30, 54, 22, - 3, 35, 11, 43, 1, 33, 9, 41, - 51, 19, 59, 27, 49, 17, 57, 25, - 15, 47, 7, 39, 13, 45, 5, 37, - 63, 31, 55, 23, 61, 29, 53, 21 }; + constexpr int patternSize = 8; + constexpr float indexMatrix[] = { + 0.0f / 64.0f, 32.0f / 64.0f, 8.0f / 64.0f, 40.0f / 64.0f, 2.0f / 64.0f, 34.0f / 64.0f, 10.0f / 64.0f, 42.0f / 64.0f, + 48.0f / 64.0f, 16.0f / 64.0f, 56.0f / 64.0f, 24.0f / 64.0f, 50.0f / 64.0f, 18.0f / 64.0f, 58.0f / 64.0f, 26.0f / 64.0f, + 12.0f / 64.0f, 44.0f / 64.0f, 4.0f / 64.0f, 36.0f / 64.0f, 14.0f / 64.0f, 46.0f / 64.0f, 6.0f / 64.0f, 38.0f / 64.0f, + 60.0f / 64.0f, 28.0f / 64.0f, 52.0f / 64.0f, 20.0f / 64.0f, 62.0f / 64.0f, 30.0f / 64.0f, 54.0f / 64.0f, 22.0f / 64.0f, + 3.0f / 64.0f, 35.0f / 64.0f, 11.0f / 64.0f, 43.0f / 64.0f, 1.0f / 64.0f, 33.0f / 64.0f, 9.0f / 64.0f, 41.0f / 64.0f, + 51.0f / 64.0f, 19.0f / 64.0f, 59.0f / 64.0f, 27.0f / 64.0f, 49.0f / 64.0f, 17.0f / 64.0f, 57.0f / 64.0f, 25.0f / 64.0f, + 15.0f / 64.0f, 47.0f / 64.0f, 7.0f / 64.0f, 39.0f / 64.0f, 13.0f / 64.0f, 45.0f / 64.0f, 5.0f / 64.0f, 37.0f / 64.0f, + 63.0f / 64.0f, 31.0f / 64.0f, 55.0f / 64.0f, 23.0f / 64.0f, 61.0f / 64.0f, 29.0f / 64.0f, 53.0f / 64.0f, 21.0f / 64.0f + }; - const int x = PositionToMatrixIndex(position.GetX(), patternSize); - const int y = PositionToMatrixIndex(position.GetY(), patternSize); - - return indexMatrix[patternSize * y + x] / static_cast(patternSizeSq); + return indexMatrix[ScaledPositionToPatternIndex(scaledPosition, patternSize)]; } - float DitherGradientComponent::GetValue(const GradientSampleParams& sampleParams) const + float DitherGradientComponent::GetCalculatedPointsPerUnit() const { - AZ_PROFILE_FUNCTION(Entity); - - const AZ::Vector3& coordinate = sampleParams.m_position; - float pointsPerUnit = m_configuration.m_pointsPerUnit; if (m_configuration.m_useSystemPointsPerUnit) { SectorDataRequestBus::Broadcast(&SectorDataRequestBus::Events::GetPointsPerMeter, pointsPerUnit); } - pointsPerUnit = AZ::GetMax(pointsPerUnit, 0.0001f); - - auto scaledCoordinate = coordinate * pointsPerUnit; - auto x = std::floor(scaledCoordinate.GetX()) / pointsPerUnit; - auto y = std::floor(scaledCoordinate.GetY()) / pointsPerUnit; - auto z = std::floor(scaledCoordinate.GetZ()) / pointsPerUnit; - AZ::Vector3 flooredCoordinate(x, y, z); - - GradientSampleParams adjustedSampleParams = sampleParams; - adjustedSampleParams.m_position = flooredCoordinate; - float value = m_configuration.m_gradientSampler.GetValue(adjustedSampleParams); + return AZ::GetMax(pointsPerUnit, 0.0001f); + } + float DitherGradientComponent::GetDitherValue(const AZ::Vector3& scaledPosition, float value) const + { float d = 0.0f; switch (m_configuration.m_patternType) { default: case DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4: - d = GetDitherValue4x4((scaledCoordinate) + m_configuration.m_patternOffset); + d = GetDitherValue4x4(scaledPosition + m_configuration.m_patternOffset); break; case DitherGradientConfig::BayerPatternType::PATTERN_SIZE_8x8: - d = GetDitherValue8x8((scaledCoordinate) + m_configuration.m_patternOffset); + d = GetDitherValue8x8(scaledPosition + m_configuration.m_patternOffset); break; } - return value > d ? 1.0f : 0.0f; + return (value > d) ? 1.0f : 0.0f; + } + + float DitherGradientComponent::GetValue(const GradientSampleParams& sampleParams) const + { + const AZ::Vector3& coordinate = sampleParams.m_position; + + const float pointsPerUnit = GetCalculatedPointsPerUnit(); + + AZ::Vector3 scaledCoordinate = coordinate * pointsPerUnit; + AZ::Vector3 flooredCoordinate = scaledCoordinate.GetFloor() / pointsPerUnit; + + GradientSampleParams adjustedSampleParams = sampleParams; + adjustedSampleParams.m_position = flooredCoordinate; + float value = m_configuration.m_gradientSampler.GetValue(adjustedSampleParams); + + return GetDitherValue(scaledCoordinate, value); + } + + void DitherGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + const float pointsPerUnit = GetCalculatedPointsPerUnit(); + + // Create the entire set of floored coordinates to use in the gradient value lookups. + AZStd::vector flooredCoordinates(positions.size()); + for (size_t index = 0; index < positions.size(); index++) + { + AZ::Vector3 scaledCoordinate = positions[index] * pointsPerUnit; + flooredCoordinates[index] = scaledCoordinate.GetFloor() / pointsPerUnit; + } + + m_configuration.m_gradientSampler.GetValues(flooredCoordinates, outValues); + + // For each gradient value, turn it into a 0 or 1 based on the location and the dither pattern. + for (size_t index = 0; index < positions.size(); index++) + { + AZ::Vector3 scaledCoordinate = positions[index] * pointsPerUnit; + outValues[index] = GetDitherValue(scaledCoordinate, outValues[index]); + } } bool DitherGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const diff --git a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp index 06a3674188..d948f6269e 100644 --- a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp @@ -219,7 +219,7 @@ namespace GradientSignal return 0.0f; } - void ImageGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + void ImageGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { @@ -234,20 +234,16 @@ namespace GradientSignal for (size_t index = 0; index < positions.size(); index++) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - m_gradientTransform.TransformPositionToUVWNormalized(positions[index], uvw, wasPointRejected); if (!wasPointRejected) { - outValue = GetValueFromImageAsset( + outValues[index] = GetValueFromImageAsset( m_configuration.m_imageAsset, uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f); } else { - outValue = 0.0f; + outValues[index] = 0.0f; } } } diff --git a/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp index 678f3b363c..aef5cc7a52 100644 --- a/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp @@ -137,6 +137,21 @@ namespace GradientSignal return output; } + void InvertGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + m_configuration.m_gradientSampler.GetValues(positions, outValues); + for (auto& outValue : outValues) + { + outValue = 1.0f - AZ::GetClamp(outValue, 0.0f, 1.0f); + } + } + bool InvertGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const { return m_configuration.m_gradientSampler.IsEntityInHierarchy(entityId); diff --git a/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp index b2958c590c..25f6a34614 100644 --- a/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp @@ -172,8 +172,6 @@ namespace GradientSignal float LevelsGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - AZ_PROFILE_FUNCTION(Entity); - float output = 0.0f; output = GetLevels( @@ -187,6 +185,21 @@ namespace GradientSignal return output; } + void LevelsGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + m_configuration.m_gradientSampler.GetValues(positions, outValues); + + GetLevels(outValues, + m_configuration.m_inputMid, m_configuration.m_inputMin, m_configuration.m_inputMax, + m_configuration.m_outputMin, m_configuration.m_outputMax); + } + bool LevelsGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const { return m_configuration.m_gradientSampler.IsEntityInHierarchy(entityId); diff --git a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp index 667d8c30a7..e3dfaf2161 100644 --- a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp @@ -203,7 +203,7 @@ namespace GradientSignal return 0.0f; } - void PerlinGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + void PerlinGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { @@ -218,21 +218,17 @@ namespace GradientSignal for (size_t index = 0; index < positions.size(); index++) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected); if (!wasPointRejected) { - outValue = m_perlinImprovedNoise->GenerateOctaveNoise( + outValues[index] = m_perlinImprovedNoise->GenerateOctaveNoise( uvw.GetX(), uvw.GetY(), uvw.GetZ(), m_configuration.m_octave, m_configuration.m_amplitude, m_configuration.m_frequency); } else { - outValue = 0.0f; + outValues[index] = 0.0f; } } } diff --git a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp index ae51bdd4ac..0f4ece38a1 100644 --- a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp @@ -183,7 +183,7 @@ namespace GradientSignal return 0.0f; } - void RandomGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + void RandomGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { @@ -200,19 +200,15 @@ namespace GradientSignal for (size_t index = 0; index < positions.size(); index++) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected); if (!wasPointRejected) { - outValue = GetRandomValue(uvw, seed); + outValues[index] = GetRandomValue(uvw, seed); } else { - outValue = 0.0f; + outValues[index] = 0.0f; } } } diff --git a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp index f2416f4fb6..77b7f1a428 100644 --- a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp @@ -168,7 +168,7 @@ namespace GradientSignal return (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / m_configuration.m_falloffWidth), 0.0f); } - void ShapeAreaFalloffGradientComponent::GetValues(AZStd::array_view positions, AZStd::array_view outValues) const + void ShapeAreaFalloffGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { @@ -187,10 +187,6 @@ namespace GradientSignal for (size_t index = 0; index < positions.size(); index++) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); - float distance = shapeRequests->DistanceFromPoint(positions[index]); // Since this is outer falloff, distance should give us values from 1.0 at the minimum distance to 0.0 at the maximum @@ -198,18 +194,15 @@ namespace GradientSignal // inside the shape (0 distance) return 1.0, and all points outside the shape return 0. This works because division by 0 // gives infinity, which gets clamped by the GetMax() to 0. However, if distance == 0, it would give us NaN, so we have // the separate conditional check to handle that case and clamp to 1.0. - outValue = (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / falloffWidth), 0.0f); + outValues[index] = (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / falloffWidth), 0.0f); } }); // If there's no shape, there's no falloff. if (!shapeConnected) { - for (size_t index = 0; index < positions.size(); index++) + for (auto& outValue : outValues) { - // The const_cast is necessary for now since array_view currently only supports const entries. - // If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed. - auto& outValue = const_cast(outValues[index]); outValue = 1.0f; } } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp index 5504fa5b45..6c4ebcc4c0 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp @@ -56,9 +56,9 @@ namespace UnitTest params.m_position = positions[positionIndex]; float value = gradientSampler.GetValue(params); - // We use ASSERT_EQ instead of EXPECT_EQ because if one value doesn't match, they probably all won't, so there's no reason - // to keep running and printing failures for every value. - ASSERT_EQ(value, results[positionIndex]); + // We use ASSERT_NEAR instead of EXPECT_NEAR because if one value doesn't match, they probably all won't, so there's no + // reason to keep running and printing failures for every value. + ASSERT_NEAR(value, results[positionIndex], 0.000001f); } } }; diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp index 449719af67..830c578b9b 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalServicesTests.cpp @@ -10,6 +10,8 @@ #include +#include + #include #include #include @@ -81,6 +83,130 @@ namespace UnitTest TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); } + TEST_F(GradientSignalServicesTestsFixture, DitherGradientComponent_4x4At50Pct_CrossingZero) + { + // With a 4x4 gradient filled with 8/16 (0.5), verify that the resulting dithered output + // is an expected checkerboard pattern with 8 of 16 pixels filled. The pattern offset is + // shifted -2 in the X direction so that the lookups go from [-2, 2) to verify that the + // pattern remains consistent across negative and positive coordinates. + + constexpr int dataSize = 4; + + AZStd::vector inputData(dataSize * dataSize, 8.0f / 16.0f); + AZStd::vector expectedOutput = { + 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + }; + + auto entityMock = CreateEntity(); + const AZ::EntityId id = entityMock->GetId(); + UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); + + GradientSignal::DitherGradientConfig config; + config.m_useSystemPointsPerUnit = false; + config.m_pointsPerUnit = 1.0f; + config.m_patternOffset = AZ::Vector3(-2.0f, 0.0f, 0.0f); + config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4; + config.m_gradientSampler.m_gradientId = entityMock->GetId(); + + auto entity = CreateEntity(); + entity->CreateComponent(config); + ActivateEntity(entity.get()); + + TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); + } + + TEST_F(GradientSignalServicesTestsFixture, DitherGradientComponent_4x4At50Pct_MorePointsPerUnit) + { + // With a 4x4 gradient filled with 8/16 (0.5), and 1/2 point per unit, if we query a 4x4 region, + // we should get a checkerboard in 2x2 blocks of the same value because it takes 2 units before the value changes. + + constexpr int dataSize = 4; + + AZStd::vector inputData(dataSize * dataSize, 8.0f / 16.0f); + AZStd::vector expectedOutput = { + 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + }; + + auto entityMock = CreateEntity(); + const AZ::EntityId id = entityMock->GetId(); + UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize); + + GradientSignal::DitherGradientConfig config; + config.m_useSystemPointsPerUnit = false; + config.m_pointsPerUnit = 0.5f; + config.m_patternOffset = AZ::Vector3::CreateZero(); + config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4; + config.m_gradientSampler.m_gradientId = entityMock->GetId(); + + auto entity = CreateEntity(); + entity->CreateComponent(config); + ActivateEntity(entity.get()); + + TestFixedDataSampler(expectedOutput, dataSize, entity->GetId()); + } + + TEST_F(GradientSignalServicesTestsFixture, DitherGradientComponent_4x4At50Pct_MorePointsAndCrossingZero) + { + // With a 4x4 gradient filled with 8/16 (0.5), and 2 points per unit, verify that querying + // from -1 to 1 produces a constant checkerboard pattern of results as it crosses the 0 boundary. + // Our expected results are a consistent checkerboard pattern, but with 2x2 blocks of the same value because we're + // querying at 2x the point density (i.e. querying 4 points per unit) to ensure that fractional position lookups work too. + + float expectedValues[] = { + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + }; + + // Create a 50% constant gradient. + GradientSignal::ConstantGradientConfig constantConfig; + constantConfig.m_value = 8.0f / 16.0f; + auto constantGradientEntity = CreateEntity(); + constantGradientEntity->CreateComponent(constantConfig); + ActivateEntity(constantGradientEntity.get()); + + GradientSignal::DitherGradientConfig config; + config.m_useSystemPointsPerUnit = false; + config.m_pointsPerUnit = 2.0f; + config.m_patternOffset = AZ::Vector3::CreateZero(); + config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4; + config.m_gradientSampler.m_gradientId = constantGradientEntity->GetId(); + + auto entity = CreateEntity(); + entity->CreateComponent(config); + ActivateEntity(entity.get()); + + // Run through [-1, 1) at 1/4 intervals and make sure we get our expected checkerboard. This is testing both that + // we have a consistent pattern across the 0 boundary and that fractional position lookups work correctly + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = entity->GetId(); + int expectedValueIndex = 0; + for (float y = -1.0f; y < 1.0f; y += 0.25f) + { + for (float x = -1.0f; x < 1.0f; x += 0.25f) + { + GradientSignal::GradientSampleParams params; + params.m_position = AZ::Vector3(x, y, 0.0f); + + float actualValue = gradientSampler.GetValue(params); + float expectedValue = expectedValues[expectedValueIndex++]; + + EXPECT_NEAR(actualValue, expectedValue, 0.01f); + } + } + } + TEST_F(GradientSignalServicesTestsFixture, DitherGradientComponent_4x4At31Pct) { // With a 4x4 gradient filled with 5/16 (0.3125), verify that the resulting dithered output From d95e157f480c92086ac38a79f6ae764ae0f1f3d8 Mon Sep 17 00:00:00 2001 From: moudgils <47460854+moudgils@users.noreply.github.com> Date: Fri, 14 Jan 2022 12:24:58 -0800 Subject: [PATCH 194/272] Different Pso cache per vendor/driver (#6893) * Support to add a different PSO cache per vendor/driver version. Also added support to have a differnt cache for Warp Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> * Added a way to reset PSO cache for everyone Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> * Fix tabbing for one line which is failing validation Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> --- .../Atom/RHI.Reflect/PhysicalDeviceDescriptor.h | 3 ++- Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h | 12 ++++++++---- Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h | 3 +++ .../RHI/Code/Include/Atom/RHI/RHISystemInterface.h | 3 +++ Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp | 6 ++++++ .../Source/Platform/Windows/RHI/Device_Windows.cpp | 5 ++++- .../RHI/DX12/Code/Source/RHI/PipelineLibrary.cpp | 10 ++++------ .../RPI/Code/Source/RPI.Public/Shader/Shader.cpp | 12 ++++++++++-- 8 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PhysicalDeviceDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PhysicalDeviceDescriptor.h index ac79ff0521..4d78d24ca8 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PhysicalDeviceDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PhysicalDeviceDescriptor.h @@ -28,7 +28,8 @@ namespace AZ (AMD, 0x1002), (Qualcomm, 0x5143), (Samsung, 0x1099), - (ARM, 0x13B5) + (ARM, 0x13B5), + (Warp, 0x1414) ); void ReflectVendorIdEnums(ReflectContext* context); diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h index eb2b0b5b0c..47cf7709db 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameScheduler.h @@ -164,23 +164,27 @@ namespace AZ //! it will defer to the platform for parallel dispatch support. void Execute(JobPolicy jobPolicy); - /// Returns the timing statistics for the previous frame. + //! Returns the timing statistics for the previous frame. const TransientAttachmentStatistics* GetTransientAttachmentStatistics() const; - /// Returns current CPU frame to frame time in milliseconds. + //! Returns current CPU frame to frame time in milliseconds. double GetCpuFrameTime() const; - /// Returns memory statistics for the previous frame. + //! Returns memory statistics for the previous frame. const MemoryStatistics* GetMemoryStatistics() const; - /// Returns the implicit root scope id. + //! Returns the implicit root scope id. ScopeId GetRootScopeId() const; + //! Returns the descriptor which has information on the properties of a TransientAttachmentPool. const TransientAttachmentPoolDescriptor* GetTransientAttachmentPoolDescriptor() const; //! Adds a RayTracingShaderTable to be built this frame void QueueRayTracingShaderTableForBuild(RayTracingShaderTable* rayTracingShaderTable); + //! Returns PhysicalDeviceDescriptor which can be used to extract vendor/driver information + const PhysicalDeviceDescriptor& GetPhysicalDeviceDescriptor(); + private: const ScopeId m_rootScopeId{"Root"}; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h index 6d416b77fc..c2a3162025 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystem.h @@ -53,6 +53,7 @@ namespace AZ const RHI::TransientAttachmentPoolDescriptor* GetTransientAttachmentPoolDescriptor() const override; ConstPtr GetPlatformLimitsDescriptor() const override; void QueueRayTracingShaderTableForBuild(RayTracingShaderTable* rayTracingShaderTable) override; + const PhysicalDeviceDescriptor& GetPhysicalDeviceDescriptor() override; ////////////////////////////////////////////////////////////////////////// private: @@ -65,6 +66,8 @@ namespace AZ RHI::Ptr m_pipelineStateCache; RHI::FrameScheduler m_frameScheduler; RHI::FrameSchedulerCompileRequest m_compileRequest; + PhysicalDeviceDescriptor m_physicalDeviceDescriptor; + }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h index 19ba1cb762..66f6b2bcde 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/RHISystemInterface.h @@ -26,6 +26,7 @@ namespace AZ class PipelineState; class PipelineStateCache; class PlatformLimitsDescriptor; + class PhysicalDeviceDescriptor; class RayTracingShaderTable; struct FrameSchedulerCompileRequest; struct TransientAttachmentStatistics; @@ -65,6 +66,8 @@ namespace AZ virtual ConstPtr GetPlatformLimitsDescriptor() const = 0; virtual void QueueRayTracingShaderTableForBuild(RayTracingShaderTable* rayTracingShaderTable) = 0; + + virtual const PhysicalDeviceDescriptor& GetPhysicalDeviceDescriptor() = 0; }; //! This bus exists to give RHI samples the ability to slot in scopes manually diff --git a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp index e7515bbf6e..3ec0cfeb93 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp @@ -165,6 +165,7 @@ namespace AZ RHI::Ptr device = RHI::Factory::Get().CreateDevice(); if (device->Init(*physicalDeviceFound) == RHI::ResultCode::Success) { + m_physicalDeviceDescriptor = physicalDeviceFound->GetDescriptor(); PlatformLimitsDescriptor::Create(); return device; } @@ -279,5 +280,10 @@ namespace AZ { m_frameScheduler.QueueRayTracingShaderTableForBuild(rayTracingShaderTable); } + + const PhysicalDeviceDescriptor& RHISystem::GetPhysicalDeviceDescriptor() + { + return m_physicalDeviceDescriptor; + } } //namespace RPI } //namespace AZ diff --git a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/Device_Windows.cpp b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/Device_Windows.cpp index f6ed3be692..a2ed31ff84 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/Device_Windows.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/Device_Windows.cpp @@ -157,7 +157,10 @@ namespace AZ disabledMessages.push_back(D3D12_MESSAGE_ID_COPY_DESCRIPTORS_INVALID_RANGES); } - // [GFX TODO][ATOM-4712] - Fix PipelineLibrary Loading. These warnings were silenced for a release and need to be fixed properly. + // We disable these warnings as the our current implementation of Pipeline Library will trigger these warnings unknowingly. For example + // it will always first try to load a pso from pipelinelibrary triggering D3D12_MESSAGE_ID_LOADPIPELINE_NAMENOTFOUND (for the first time) before storing the PSO in a library. + // Similarly when we merge multiple pipeline libraries (in multiple threads) we may trigger D3D12_MESSAGE_ID_STOREPIPELINE_DUPLICATENAME as it is possible to save + // a PSO already saved in the main library. #if defined (AZ_DX12_USE_PIPELINE_LIBRARY) disabledMessages.push_back(D3D12_MESSAGE_ID_LOADPIPELINE_NAMENOTFOUND); disabledMessages.push_back(D3D12_MESSAGE_ID_STOREPIPELINE_DUPLICATENAME); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/PipelineLibrary.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/PipelineLibrary.cpp index 63625fde72..ae3053f446 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/PipelineLibrary.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/PipelineLibrary.cpp @@ -50,10 +50,9 @@ namespace AZ bool shouldCreateLibFromSerializedData = true; if (RHI::Factory::Get().IsRenderDocModuleLoaded() || - RHI::Factory::Get().IsPixModuleLoaded() || - RHI::Factory::Get().UsingWarpDevice()) + RHI::Factory::Get().IsPixModuleLoaded()) { - // CreatePipelineLibrary api does not function properly if Renderdoc, Pix or Warp is enabled + // CreatePipelineLibrary api does not function properly if Renderdoc or Pix is enabled shouldCreateLibFromSerializedData = false; } @@ -218,10 +217,9 @@ namespace AZ RHI::ResultCode PipelineLibrary::MergeIntoInternal([[maybe_unused]] AZStd::array_view pipelineLibraries) { if (RHI::Factory::Get().IsRenderDocModuleLoaded() || - RHI::Factory::Get().IsPixModuleLoaded() || - RHI::Factory::Get().UsingWarpDevice()) + RHI::Factory::Get().IsPixModuleLoaded()) { - // StorePipeline api does not function properly if RenderDoc, Pix or Warp is enabled + // StorePipeline api does not function properly if RenderDoc or Pix is enabled return RHI::ResultCode::Fail; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp index b1ae460af6..92c2e30594 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp @@ -17,6 +17,7 @@ #include +#define PSOCacheVersion 0 // Bump this if you want to reset PSO cache for everyone namespace AZ { @@ -85,10 +86,17 @@ namespace AZ AZStd::string uuidString; assetId.m_guid.ToString(uuidString, false, false); + RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get(); + RHI::PhysicalDeviceDescriptor physicalDeviceDesc = rhiSystem->GetPhysicalDeviceDescriptor(); + char pipelineLibraryPathTemp[AZ_MAX_PATH_LEN]; azsnprintf( - pipelineLibraryPathTemp, AZ_MAX_PATH_LEN, "@user@/Atom/PipelineStateCache/%s/%s_%s_%d.bin", platformName.GetCStr(), - shaderName.GetCStr(), uuidString.data(), assetId.m_subId); + pipelineLibraryPathTemp, AZ_MAX_PATH_LEN, "@user@/Atom/PipelineStateCache_%s_%i_%i _Ver_%i/%s/%s_%s_%d.bin", + ToString(physicalDeviceDesc.m_vendorId).data(), physicalDeviceDesc.m_deviceId, physicalDeviceDesc.m_driverVersion, PSOCacheVersion, + platformName.GetCStr(), + shaderName.GetCStr(), + uuidString.data(), + assetId.m_subId); fileIOBase->ResolvePath(pipelineLibraryPathTemp, pipelineLibraryPath, pipelineLibraryPathLength); return true; From aa18deef5d70f2468a67df535de4e64fcd799ff3 Mon Sep 17 00:00:00 2001 From: Adi Bar-Lev <82479970+Adi-Amazon@users.noreply.github.com> Date: Fri, 14 Jan 2022 15:26:41 -0500 Subject: [PATCH 195/272] AtomTressFX - fixing crash bug for prefab (#6892) - The crash happens due to attempt to get an instance of the hair dynamic data before it was initialized. Signed-off-by: Adi Bar-Lev <82479970+Adi-Amazon@users.noreply.github.com> --- .../Code/Rendering/HairRenderObject.cpp | 16 +++++++++++++--- .../Code/Rendering/HairRenderObject.h | 10 ++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Gems/AtomTressFX/Code/Rendering/HairRenderObject.cpp b/Gems/AtomTressFX/Code/Rendering/HairRenderObject.cpp index fe167cae8b..472a610016 100644 --- a/Gems/AtomTressFX/Code/Rendering/HairRenderObject.cpp +++ b/Gems/AtomTressFX/Code/Rendering/HairRenderObject.cpp @@ -213,6 +213,8 @@ namespace AZ Data::Instance rasterShader, uint32_t vertexCount, uint32_t strandsCount ) { + m_initialized = false; + AZ_Assert(vertexCount <= std::numeric_limits().max(), "Hair vertex count exceeds uint32_t size."); // Create the dynamic shared buffers Srg. @@ -608,8 +610,16 @@ namespace AZ // First, Directly loading from the asset stored in the render settings. if (pRenderSettings) { - m_baseAlbedo = RPI::StreamingImage::FindOrCreate(pRenderSettings->m_baseAlbedoAsset); - m_strandAlbedo = RPI::StreamingImage::FindOrCreate(pRenderSettings->m_strandAlbedoAsset); + if (pRenderSettings->m_baseAlbedoAsset) + { + pRenderSettings->m_baseAlbedoAsset.BlockUntilLoadComplete(); + m_baseAlbedo = RPI::StreamingImage::FindOrCreate(pRenderSettings->m_baseAlbedoAsset); + } + if (pRenderSettings->m_strandAlbedoAsset) + { + pRenderSettings->m_strandAlbedoAsset.BlockUntilLoadComplete(); + m_strandAlbedo = RPI::StreamingImage::FindOrCreate(pRenderSettings->m_strandAlbedoAsset); + } } // Fallback using the texture name stored in the render settings. @@ -1142,7 +1152,7 @@ namespace AZ if (!renderMaterialSrg || !simSrg) { - AZ_Error("Hair Gem", false, "Failed to get thre hair material Srg for the raster pass."); + AZ_Error("Hair Gem", false, "Failed to get the hair material Srg for the raster pass."); return false; } // No need to compile the simSrg since it was compiled already by the Compute pass this frame diff --git a/Gems/AtomTressFX/Code/Rendering/HairRenderObject.h b/Gems/AtomTressFX/Code/Rendering/HairRenderObject.h index 817ebd89fa..564272e6f0 100644 --- a/Gems/AtomTressFX/Code/Rendering/HairRenderObject.h +++ b/Gems/AtomTressFX/Code/Rendering/HairRenderObject.h @@ -110,8 +110,14 @@ namespace AZ PrepareSrgDescriptors(m_dynamicBuffersDescriptors, vertexCount, strandsCount); } - Data::Instance GetSimSrgForCompute() { return m_simSrgForCompute; } - Data::Instance GetSimSrgForRaster() { return m_simSrgForRaster; } + Data::Instance GetSimSrgForCompute() + { + return m_initialized ? m_simSrgForCompute : nullptr; + } + + Data::Instance GetSimSrgForRaster() + { + return m_initialized ? m_simSrgForRaster : nullptr; } bool IsInitialized() { return m_initialized; } From 295c836ed81839cc13695df1e2c6b6bf13b06adb Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Fri, 14 Jan 2022 12:46:08 -0800 Subject: [PATCH 196/272] clean up comments, add set type action in disabled form Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../Source/Components/Slots/Data/DataSlotComponent.cpp | 1 - Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp | 3 --- Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 8 ++++++-- Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp | 1 - .../Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp | 6 +++--- .../Variable/GraphVariableManagerComponent.cpp | 1 - 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp index 7eb9187123..c053c37fbc 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp +++ b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotComponent.cpp @@ -328,7 +328,6 @@ namespace GraphCanvas bool DataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot) const { - // #sc_user_slot_variable_ux make sure this can be converted to reference, or created as one bool canToggleReference = false; if (m_canConvertSlotTypes && DataSlotUtils::IsValueDataSlotType(m_dataSlotType) && !HasConnections()) diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 92045b505f..510962cf4b 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -667,7 +667,6 @@ namespace ScriptCanvasEditor } // Now that the slot has a valid type/name, we can actually promote it to a variable - // #sc_user_slot_variable_ux add a value indicating that the slot is new if (PromoteToVariableAction(endpoint, true)) { ScriptCanvas::GraphVariable* variable = slot->GetVariable(); @@ -2191,7 +2190,6 @@ namespace ScriptCanvasEditor bool Graph::PromoteToVariableAction(const GraphCanvas::Endpoint& endpoint, bool isNewSlot) { - // #sc_user_slot_variable_ux make the fix here...rework is user added or something ScriptCanvas::Endpoint scriptCanvasEndpoint = ConvertToScriptCanvasEndpoint(endpoint); auto activeNode = FindNode(scriptCanvasEndpoint.GetNodeId()); @@ -2283,7 +2281,6 @@ namespace ScriptCanvasEditor AZ::Outcome addOutcome; - // #sc_user_slot_variable_ux re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion) ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum, true); if (addOutcome.IsSuccess()) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 573a3f6e57..b5b4fc7787 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -3874,8 +3874,12 @@ namespace ScriptCanvasEditor contextMenu.AddMenuAction(aznew ExposeSlotMenuAction(&contextMenu)); contextMenu.AddMenuAction(aznew CreateAzEventHandlerSlotMenuAction(&contextMenu)); - // disabling until references can be changed - // contextMenu.AddMenuAction(aznew SetDataSlotTypeMenuAction(&contextMenu)); + auto setSlotTypeAction = aznew SetDataSlotTypeMenuAction(&contextMenu); + // Changing slot type is disabled temporarily because now that that user data slots are correctly coordinated with their reference + // variables, their type cannot be changed. The next change will allow all variables to change their type post creation, and then + // that will allow this action to be enabled. + setSlotTypeAction->setEnabled(false); + contextMenu.AddMenuAction(setSlotTypeAction); return HandleContextMenu(contextMenu, slotId, screenPoint, scenePoint); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp index 6aef61b12f..4bdd0daae6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp @@ -462,7 +462,6 @@ namespace ScriptCanvas bool Slot::CanConvertToReference(bool isNewSlot) const { - // #sc_user_slot_variable_ux make sure this can be converted to reference, or created as one return (!m_isUserAdded || isNewSlot) && CanConvertTypes() && !m_isVariableReference && !m_node->HasConnectedNodes((*this)); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index b2194e1bd0..345dc1ebda 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -237,7 +237,7 @@ namespace ScriptCanvas if (auto datum = variablePair.second.GetDatum()) { - // #sc_user_slot_variable_ux consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering + // #functions2 slot<->variable consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering m_sourceVariableByDatum.insert(AZStd::make_pair(datum, &variablePair.second)); } } @@ -247,7 +247,7 @@ namespace ScriptCanvas auto datum = sourceVariable->GetDatum(); AZ_Assert(datum != nullptr, "the datum must be valid"); - // #sc_user_slot_variable_ux check to verify if it is a member variable + // #functions2 slot<->variable check to verify if it is a member variable auto variable = sourceVariable->GetScope() == VariableFlags::Scope::Graph ? AddMemberVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId()) : AddVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId()); @@ -1670,7 +1670,7 @@ namespace ScriptCanvas if (returnValue.second->m_source->m_sourceSlotId == slot->GetId()) { - // #sc_user_slot_variable_ux determine if the root or the function call should be passed in here...the slot/node lead to the user call on the thread, but it may not even be created yet + // #functions2 slot<->variable determine if the root or the function call should be passed in here...the slot/node lead to the user call on the thread, but it may not even be created yet return AZStd::make_pair(root, returnValue.second->m_source); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp index 81383bf747..0bd1b2c5a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp @@ -220,7 +220,6 @@ namespace ScriptCanvas return AZ::Success(newId); } - // #sc_user_slot_variable_ux add this to the graph, using the old datum AZ::Outcome GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value, bool functionScope) { if (FindVariable(name)) From c9ee1f7871b5875de19b943df05d7a705f0ce7ef Mon Sep 17 00:00:00 2001 From: Qing Tao <55564570+VickyAtAZ@users.noreply.github.com> Date: Fri, 14 Jan 2022 13:31:13 -0800 Subject: [PATCH 197/272] ATOM-17132 Image builder failed to build some images after preset was fixed (#6900) The issue was because the preset reload was only happened in CreateJobs but not ProcessJobs. But these two functions might be called from different AssetBuilder. The fix is to add preset reload for Processjobs too. There was another change to add debug device name for streaming image. Signed-off-by: Qing Tao <55564570+VickyAtAZ@users.noreply.github.com> --- .../BuilderSettings/TextureSettings.cpp | 8 +++++ .../Code/Source/ImageBuilderComponent.cpp | 34 +++++++++++++++++-- .../RPI.Public/Image/StreamingImage.cpp | 12 ++++--- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/TextureSettings.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/TextureSettings.cpp index 29d9b21775..4772a94ffa 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/TextureSettings.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/TextureSettings.cpp @@ -226,6 +226,14 @@ namespace ImageProcessingAtom MultiplatformTextureSettings settings; PlatformNameList platformsList = BuilderSettingManager::Instance()->GetPlatformList(); PresetName suggestedPreset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilepath); + + // If the suggested preset doesn't exist (or was failed to be loaded), return empty texture settings + if (BuilderSettingManager::Instance()->GetPreset(suggestedPreset) == nullptr) + { + AZ_Error("Image Processing", false, "Failed to find suggested preset [%s]", suggestedPreset.GetCStr()); + return settings; + } + for (PlatformName& platform : platformsList) { TextureSettings textureSettings; diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp index 5e021a3fdd..55a6c1ea8f 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp @@ -241,8 +241,7 @@ namespace ImageProcessingAtom // Reload preset if it was changed ImageProcessingAtom::BuilderSettingManager::Instance()->ReloadPreset(presetName); - AZStd::string_view filePath; - auto presetSettings = BuilderSettingManager::Instance()->GetPreset(presetName, /*default platform*/"", &filePath); + auto presetSettings = BuilderSettingManager::Instance()->GetPreset(presetName, /*default platform*/""); AssetBuilderSDK::SourceFileDependency sourceFileDependency; sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute; @@ -274,6 +273,32 @@ namespace ImageProcessingAtom } } + void ReloadPresetIfNeeded(PresetName presetName) + { + // Reload preset if it was changed + ImageProcessingAtom::BuilderSettingManager::Instance()->ReloadPreset(presetName); + + auto presetSettings = BuilderSettingManager::Instance()->GetPreset(presetName, /*default platform*/""); + + if (presetSettings) + { + // handle special case here + // Cubemap setting may reference some other presets + if (presetSettings->m_cubemapSetting) + { + if (presetSettings->m_cubemapSetting->m_generateIBLDiffuse && !presetSettings->m_cubemapSetting->m_iblDiffusePreset.IsEmpty()) + { + ImageProcessingAtom::BuilderSettingManager::Instance()->ReloadPreset(presetSettings->m_cubemapSetting->m_iblDiffusePreset); + } + + if (presetSettings->m_cubemapSetting->m_generateIBLSpecular && !presetSettings->m_cubemapSetting->m_iblSpecularPreset.IsEmpty()) + { + ImageProcessingAtom::BuilderSettingManager::Instance()->ReloadPreset(presetSettings->m_cubemapSetting->m_iblSpecularPreset); + } + } + } + } + // this happens early on in the file scanning pass // this function should consistently always create the same jobs, and should do no checking whether the job is up to date or not - just be consistent. void ImageBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) @@ -336,6 +361,11 @@ namespace ImageProcessingAtom // Do conversion and get exported file's path if (needConversion) { + + // Handles preset changes + auto presetName = GetImagePreset(request.m_fullPath); + ReloadPresetIfNeeded(presetName); + AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Performing image conversion: %s\n", request.m_fullPath.c_str()); ImageConvertProcess* process = CreateImageConvertProcess(request.m_fullPath, request.m_tempDirPath, request.m_jobDescription.GetPlatformIdentifier(), response.m_outputProducts); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/StreamingImage.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/StreamingImage.cpp index fb03d109a2..49cd52f212 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/StreamingImage.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/StreamingImage.cpp @@ -143,11 +143,6 @@ namespace AZ RHI::ResultCode resultCode = RHI::ResultCode::Success; const ImageMipChainAsset& mipChainTailAsset = imageAsset.GetTailMipChain(); - -#ifdef AZ_RPI_STREAMING_IMAGE_DEBUG_LOG - m_image->SetName(Name(imageAsset.GetHint().c_str())); - AZ_TracePrintf("StreamingImage", "Init image [%s]\n", m_image->GetName().data()); -#endif { RHI::StreamingImageInitRequest initRequest; @@ -193,6 +188,13 @@ namespace AZ m_rhiPool = rhiPool; m_pool = pool; m_pool->AttachImage(this); + + // Set rhi image name + m_image->SetName(Name(m_imageAsset.GetHint())); + +#ifdef AZ_RPI_STREAMING_IMAGE_DEBUG_LOG + AZ_TracePrintf("StreamingImage", "Init image [%s]\n", m_image->GetName().data()); +#endif #if defined (AZ_RPI_STREAMING_IMAGE_HOT_RELOADING) BusConnect(imageAsset.GetId()); From 3d17f9648f1b9f0431cf390f003cc64cace2003a Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Fri, 14 Jan 2022 14:08:29 -0800 Subject: [PATCH 198/272] removes the old log lines test for the Light component, test will be re-added as a return codes test in the p1 test tasks Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/TestSuite_Sandbox.py | 69 +----- ...dra_AtomEditorComponents_LightComponent.py | 213 ------------------ 2 files changed, 1 insertion(+), 281 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index c9182070f6..bd0477a1db 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -9,87 +9,20 @@ import os import pytest -import ly_test_tools.environment.file_system as file_system -import editor_python_test_tools.hydra_test_utils as hydra from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite -from Atom.atom_utils.atom_constants import LIGHT_TYPES logger = logging.getLogger(__name__) TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("level", ["auto_test"]) -class TestAtomEditorComponentsMain(object): - """Holds tests for Atom components.""" - - @pytest.mark.test_case_id("C34525095") - def test_AtomEditorComponents_LightComponent( - self, request, editor, workspace, project, launcher_platform, level): - """ - Please review the hydra script run by this test for more specific test info. - Tests that the Light component has the expected property options available to it. - """ - cfg_args = [level] - - expected_lines = [ - "light_entity Entity successfully created", - "Entity has a Light component", - "light_entity_test: Component added to the entity: True", - f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}", - "Controller|Configuration|Shadows|Enable shadow set to True", - "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS", - "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF - "Controller|Configuration|Shadows|Filtering sample count set to 4", - "Controller|Configuration|Shadows|Filtering sample count set to 64", - "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM - "Controller|Configuration|Shadows|ESM exponent set to 50.0", - "Controller|Configuration|Shadows|ESM exponent set to 5000.0", - "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF - f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}", - f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}", - f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}", - "light_entity Controller|Configuration|Fast approximation: SUCCESS", - "light_entity Controller|Configuration|Both directions: SUCCESS", - f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} " - f"which matches {LIGHT_TYPES['simple_point']}", - "Controller|Configuration|Attenuation radius|Mode set to 0", - "Controller|Configuration|Attenuation radius|Radius set to 100.0", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} " - f"which matches {LIGHT_TYPES['simple_spot']}", - "Controller|Configuration|Shutters|Outer angle set to 45.0", - "Controller|Configuration|Shutters|Outer angle set to 90.0", - "light_entity_test: Component added to the entity: True", - "Light component test (non-GPU) completed.", - ] - - unexpected_lines = ["Traceback (most recent call last):"] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_LightComponent.py", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - enable_prefab_system=False, - ) - - @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): enable_prefab_system = False - #this test is intermittently timing out without ever having executed. sandboxing while we investigate cause. + # this test is intermittently timing out without ever having executed. sandboxing while we investigate cause. @pytest.mark.test_case_id("C36525660") class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py deleted file mode 100644 index 7ecdc6859b..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py +++ /dev/null @@ -1,213 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import os -import sys - -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.math as math -import azlmbr.paths -import azlmbr.legacy.general as general - -sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests")) - -import editor_python_test_tools.hydra_editor_utils as hydra -from Atom.atom_utils.atom_constants import LIGHT_TYPES - -LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' -SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Shadows|Enable shadow", True), - ("Controller|Configuration|Shadows|Shadowmap size", 0), # 256 - ("Controller|Configuration|Shadows|Shadowmap size", 1), # 512 - ("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024 - ("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048 - ("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF - ("Controller|Configuration|Shadows|Filtering sample count", 4.0), - ("Controller|Configuration|Shadows|Filtering sample count", 64.0), - ("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM - ("Controller|Configuration|Shadows|ESM exponent", 50), - ("Controller|Configuration|Shadows|ESM exponent", 5000), - ("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF -] -QUAD_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Both directions", True), - ("Controller|Configuration|Fast approximation", True), -] -SIMPLE_POINT_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Attenuation radius|Mode", 0), - ("Controller|Configuration|Attenuation radius|Radius", 100.0), -] -SIMPLE_SPOT_LIGHT_PROPERTIES = [ - ("Controller|Configuration|Shutters|Inner angle", 45.0), - ("Controller|Configuration|Shutters|Outer angle", 90.0), -] - - -def verify_required_component_property_value(entity_name, component, property_path, expected_property_value): - """ - Compares the property value of component against the expected_property_value. - :param entity_name: name of the entity to use (for test verification purposes). - :param component: component to check on a given entity for its current property value. - :param property_path: the path to the property inside the component. - :param expected_property_value: The value expected from the value inside property_path. - :return: None, but prints to general.log() which the test uses to verify against. - """ - property_value = editor.EditorComponentAPIBus( - bus.Broadcast, "GetComponentProperty", component, property_path).GetValue() - general.log(f"{entity_name}_test: Property value is {property_value} " - f"which matches {expected_property_value}") - - -def run(): - """ - Test Case - Light Component - 1. Creates a "light_entity" Entity and attaches a "Light" component to it. - 2. Updates the Light component to each light type option from the LIGHT_TYPES constant. - 3. The test will check the Editor log to ensure each light type was selected. - 4. Prints the string "Light component test (non-GPU) completed" after completion. - - Tests will fail immediately if any of these log lines are found: - 1. Trace::Assert - 2. Trace::Error - 3. Traceback (most recent call last): - - :return: None - """ - # Create a "light_entity" entity with "Light" component. - light_entity_name = "light_entity" - light_component = "Light" - light_entity = hydra.Entity(light_entity_name) - light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component]) - general.log( - f"{light_entity_name}_test: Component added to the entity: " - f"{hydra.has_components(light_entity.id, [light_component])}") - - # Populate the light_component_id_pair value so that it can be used to select all Light component options. - light_component_id_pair = None - component_type_id_list = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0) - if len(component_type_id_list) < 1: - general.log(f"ERROR: A component class with name {light_component} doesn't exist") - light_component_id_pair = None - elif len(component_type_id_list) > 1: - general.log(f"ERROR: Found more than one component classes with same name: {light_component}") - light_component_id_pair = None - entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0]) - if entity_component_id_pair.IsSuccess(): - light_component_id_pair = entity_component_id_pair.GetValue() - - # Test each Light component option can be selected and it's properties updated. - # Point (sphere) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['sphere'], - light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Spot (disk) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['spot_disk'], - light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Capsule light type checks. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - LIGHT_TYPES['capsule'] - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=LIGHT_TYPES['capsule'] - ) - - # Quad light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['quad'], - light_properties=QUAD_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Polygon light type checks. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - LIGHT_TYPES['polygon'] - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=LIGHT_TYPES['polygon'] - ) - - # Point (simple punctual) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['simple_point'], - light_properties=SIMPLE_POINT_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - # Spot (simple punctual) light type checks. - light_type_property_test( - light_type=LIGHT_TYPES['simple_spot'], - light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES, - light_component_id_pair=light_component_id_pair, - light_entity_name=light_entity_name, - light_entity=light_entity - ) - - general.log("Light component test (non-GPU) completed.") - - -def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity): - """ - Updates the current light type and modifies its properties, then verifies they are accurate to what was set. - :param light_type: The type of light to update, must match a value in LIGHT_TYPES - :param light_properties: List of tuples detailing properties to modify with update values. - :param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity. - :param light_entity_name: the name of the Entity holding the light component. - :param light_entity: the Entity object containing the light component. - :return: None - """ - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - light_type - ) - verify_required_component_property_value( - entity_name=light_entity_name, - component=light_entity.components[0], - property_path=LIGHT_TYPE_PROPERTY, - expected_property_value=light_type - ) - - for light_property in light_properties: - light_entity.get_set_test(0, light_property[0], light_property[1]) - - -if __name__ == "__main__": - run() From 588527064019a15f81c8626a80db7ada0b472e49 Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Fri, 14 Jan 2022 14:36:15 -0800 Subject: [PATCH 199/272] [iOS] Update to use AWSNativeSDK 1.9.50 (#6890) Signed-off-by: onecent1101 --- Gems/AWSCore/Code/Platform/iOS/AWSCore_Traits_iOS.h | 2 +- cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/AWSCore/Code/Platform/iOS/AWSCore_Traits_iOS.h b/Gems/AWSCore/Code/Platform/iOS/AWSCore_Traits_iOS.h index d7b1f32461..2cacfb0d34 100644 --- a/Gems/AWSCore/Code/Platform/iOS/AWSCore_Traits_iOS.h +++ b/Gems/AWSCore/Code/Platform/iOS/AWSCore_Traits_iOS.h @@ -7,4 +7,4 @@ */ #pragma once -#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 0 +#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 1 diff --git a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake index d8dd7e8134..4b99efc9d0 100644 --- a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake +++ b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake @@ -18,7 +18,7 @@ ly_associate_package(PACKAGE_NAME glad-2.0.0-beta-rev2-multiplatform TARGETS gla # platform-specific: ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-ios TARGETS TIFF PACKAGE_HASH e9067e88649fb6e93a926d9ed38621a9fae360a2e6f6eb24ebca63c1bc7761ea) ly_associate_package(PACKAGE_NAME freetype-2.10.4.16-ios TARGETS freetype PACKAGE_HASH 3ac3c35e056ae4baec2e40caa023d76a7a3320895ef172b6655e9261b0dc2e29) -ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev4-ios TARGETS AWSNativeSDK PACKAGE_HASH d10e7496ca705577032821011beaf9f2507689f23817bfa0ed4d2a2758afcd02) +ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.9.50-rev1-ios TARGETS AWSNativeSDK PACKAGE_HASH c3c9478c259ecb569fb2ce6fcfa733647adc3b6bd2854e8eff9de64bcd18c745) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-ios TARGETS Lua PACKAGE_HASH c2d3c4e67046c293049292317a7d60fdb8f23effeea7136aefaef667163e5ffe) ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev5-ios TARGETS PhysX PACKAGE_HASH 4a5e38b385837248590018eb133444b4e440190414e6756191200a10c8fa5615) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-ios TARGETS mikkelsen PACKAGE_HASH 976aaa3ccd8582346132a10af253822ccc5d5bcc9ea5ba44d27848f65ee88a8a) From a6feef3563a6731c15ecb4090855027a0aae26b8 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Fri, 14 Jan 2022 16:51:46 -0600 Subject: [PATCH 200/272] Atom Tools: Created base class for document-based applications Moving some duplicated code to a common base class Signed-off-by: Guthrie Adams --- .../Document/AtomToolsDocumentApplication.h | 28 ++++++++++++++++ .../Document/AtomToolsDocumentApplication.cpp | 33 +++++++++++++++++++ .../Code/atomtoolsframework_files.cmake | 2 ++ .../Code/Source/MaterialEditorApplication.cpp | 18 +--------- .../Code/Source/MaterialEditorApplication.h | 13 +++----- .../ShaderManagementConsoleApplication.cpp | 19 +---------- .../ShaderManagementConsoleApplication.h | 13 +++----- 7 files changed, 75 insertions(+), 51 deletions(-) create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h new file mode 100644 index 0000000000..7b9327337c --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +namespace AtomToolsFramework +{ + class AtomToolsDocumentApplication + : public AtomToolsApplication + { + public: + AZ_TYPE_INFO(AtomToolsDocumentApplication, "{F4B43677-EB95-4CBB-8B8E-9EF4247E6F0D}"); + + using Base = AtomToolsApplication; + + AtomToolsDocumentApplication(int* argc, char*** argv); + + // AtomToolsApplication overrides... + void ProcessCommandLine(const AZ::CommandLine& commandLine) override; + }; +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp new file mode 100644 index 0000000000..beb414bb6c --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +namespace AtomToolsFramework +{ + AtomToolsDocumentApplication::AtomToolsDocumentApplication(int* argc, char*** argv) + : Base(argc, argv) + { + } + + void AtomToolsDocumentApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) + { + // Process command line options for opening documents on startup + size_t openDocumentCount = commandLine.GetNumMiscValues(); + for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) + { + const AZStd::string openDocumentPath = commandLine.GetMiscValue(openDocumentIndex); + + AZ_Printf(GetBuildTargetName().c_str(), "Opening document: %s", openDocumentPath.c_str()); + AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); + } + + Base::ProcessCommandLine(commandLine); + } +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index 3ddcc05245..4f0e0d34e7 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -12,6 +12,7 @@ set(FILES Include/AtomToolsFramework/Communication/LocalSocket.h Include/AtomToolsFramework/Debug/TraceRecorder.h Include/AtomToolsFramework/Document/AtomToolsDocument.h + Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h Include/AtomToolsFramework/Document/AtomToolsDocumentMainWindow.h Include/AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h @@ -40,6 +41,7 @@ set(FILES Source/Communication/LocalSocket.cpp Source/Debug/TraceRecorder.cpp Source/Document/AtomToolsDocument.cpp + Source/Document/AtomToolsDocumentApplication.cpp Source/Document/AtomToolsDocumentMainWindow.cpp Source/Document/AtomToolsDocumentSystemSettings.cpp Source/Document/AtomToolsDocumentSystemComponent.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index cec882cabb..15a5ff1715 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,7 @@ namespace MaterialEditor } MaterialEditorApplication::MaterialEditorApplication(int* argc, char*** argv) - : AtomToolsApplication(argc, argv) + : Base(argc, argv) { QApplication::setApplicationName("O3DE Material Editor"); @@ -58,19 +57,4 @@ namespace MaterialEditor { return AZStd::vector({ "passes/", "config/", "MaterialEditor/" }); } - - void MaterialEditorApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) - { - // Process command line options for opening one or more material documents on startup - size_t openDocumentCount = commandLine.GetNumMiscValues(); - for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) - { - const AZStd::string openDocumentPath = commandLine.GetMiscValue(openDocumentIndex); - - AZ_Printf(GetBuildTargetName().c_str(), "Opening document: %s", openDocumentPath.c_str()); - AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); - } - - Base::ProcessCommandLine(commandLine); - } } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index e91bce48f0..bf2e6f6ca1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -8,30 +8,27 @@ #pragma once -#include -#include +#include namespace MaterialEditor { class MaterialThumbnailRenderer; class MaterialEditorApplication - : public AtomToolsFramework::AtomToolsApplication + : public AtomToolsFramework::AtomToolsDocumentApplication { public: AZ_TYPE_INFO(MaterialEditor::MaterialEditorApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); - using Base = AtomToolsFramework::AtomToolsApplication; + using Base = AtomToolsFramework::AtomToolsDocumentApplication; MaterialEditorApplication(int* argc, char*** argv); - ////////////////////////////////////////////////////////////////////////// - // AzFramework::Application + // AzFramework::Application overrides... void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; - private: - void ProcessCommandLine(const AZ::CommandLine& commandLine) override; + // AtomToolsFramework::AtomToolsApplication overrides... AZStd::string GetBuildTargetName() const override; AZStd::vector GetCriticalAssetFilters() const override; }; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 3d07a0de15..a242716b52 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -36,7 +35,7 @@ namespace ShaderManagementConsole } ShaderManagementConsoleApplication::ShaderManagementConsoleApplication(int* argc, char*** argv) - : AtomToolsApplication(argc, argv) + : Base(argc, argv) { QApplication::setApplicationName("O3DE Shader Management Console"); @@ -56,20 +55,4 @@ namespace ShaderManagementConsole { return AZStd::vector({ "passes/", "config/" }); } - - void ShaderManagementConsoleApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) - { - // Process command line options for opening one or more documents on startup - size_t openDocumentCount = commandLine.GetNumMiscValues(); - for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) - { - const AZStd::string openDocumentPath = commandLine.GetMiscValue(openDocumentIndex); - - AZ_Printf(GetBuildTargetName().c_str(), "Opening document: %s", openDocumentPath.c_str()); - AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( - &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); - } - - Base::ProcessCommandLine(commandLine); - } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 6596429577..6b0365e6bd 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -8,28 +8,25 @@ #pragma once -#include -#include +#include namespace ShaderManagementConsole { class ShaderManagementConsoleApplication - : public AtomToolsFramework::AtomToolsApplication + : public AtomToolsFramework::AtomToolsDocumentApplication { public: AZ_TYPE_INFO(ShaderManagementConsole::ShaderManagementConsoleApplication, "{A31B1AEB-4DA3-49CD-884A-CC998FF7546F}"); - using Base = AtomToolsFramework::AtomToolsApplication; + using Base = AtomToolsFramework::AtomToolsDocumentApplication; ShaderManagementConsoleApplication(int* argc, char*** argv); - ////////////////////////////////////////////////////////////////////////// - // AzFramework::Application + // AzFramework::Application overrides... void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; - private: - void ProcessCommandLine(const AZ::CommandLine& commandLine); + // AtomToolsFramework::AtomToolsApplication overrides... AZStd::string GetBuildTargetName() const override; AZStd::vector GetCriticalAssetFilters() const override; }; From c15d3f35bf37fb4fd5f49f33350d34557f1a9c49 Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Fri, 14 Jan 2022 14:57:35 -0800 Subject: [PATCH 201/272] fix release build errors Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp | 4 ++-- .../Source/AutomationActions/DynamicSlotFullCreation.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp b/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp index 525386a1a3..5face707c3 100644 --- a/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp +++ b/Gems/GraphModel/Code/Tests/MockGraphCanvas.cpp @@ -94,12 +94,12 @@ namespace MockGraphCanvasServices GraphCanvas::DataSlotRequestBus::Handler::BusDisconnect(); } - bool MockDataSlotComponent::ConvertToReference([[maybe_unused]] bool isNewSlot = false) + bool MockDataSlotComponent::ConvertToReference([[maybe_unused]] bool isNewSlot) { return false; } - bool MockDataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot = false) const + bool MockDataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot) const { return false; } diff --git a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/DynamicSlotFullCreation.cpp b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/DynamicSlotFullCreation.cpp index 090622646a..c71219cc8c 100644 --- a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/DynamicSlotFullCreation.cpp +++ b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/DynamicSlotFullCreation.cpp @@ -295,11 +295,11 @@ namespace ScriptCanvasDeveloperEditor GraphCanvas::Endpoint endpoint = ConvertToGraphCanvasEndpoint(slot->GetEndpoint()); bool canConvertToReference = false; - GraphCanvas::DataSlotRequestBus::EventResult(canConvertToReference, endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::CanConvertToReference); + GraphCanvas::DataSlotRequestBus::EventResult(canConvertToReference, endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::CanConvertToReference, false); if (canConvertToReference) { - GraphCanvas::DataSlotRequestBus::Event(endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference); + GraphCanvas::DataSlotRequestBus::Event(endpoint.GetSlotId(), &GraphCanvas::DataSlotRequests::ConvertToReference, false); } } From 75a582972c7d2263dd4cac1ef684de12b7be575e Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Fri, 14 Jan 2022 18:27:11 -0600 Subject: [PATCH 202/272] Atom Tools: added function to get the number of active documents Signed-off-by: Guthrie Adams --- .../Document/AtomToolsDocumentSystemRequestBus.h | 3 +++ .../Source/Document/AtomToolsDocumentSystemComponent.cpp | 6 ++++++ .../Code/Source/Document/AtomToolsDocumentSystemComponent.h | 1 + 3 files changed, 10 insertions(+) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h index f751915a9a..b12cf5e580 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h @@ -71,6 +71,9 @@ namespace AtomToolsFramework //! Save all documents virtual bool SaveAllDocuments() = 0; + + //! Get number of allocated documents + virtual AZ::u32 GetDocumentCount() const = 0; }; using AtomToolsDocumentSystemRequestBus = AZ::EBus; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp index 3b27c9cd0f..d554c68451 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.cpp @@ -69,6 +69,7 @@ namespace AtomToolsFramework ->Event("SaveDocumentAsCopy", &AtomToolsDocumentSystemRequestBus::Events::SaveDocumentAsCopy) ->Event("SaveDocumentAsChild", &AtomToolsDocumentSystemRequestBus::Events::SaveDocumentAsChild) ->Event("SaveAllDocuments", &AtomToolsDocumentSystemRequestBus::Events::SaveAllDocuments) + ->Event("GetDocumentCount", &AtomToolsDocumentSystemRequestBus::Events::GetDocumentCount) ; behaviorContext->EBus("AtomToolsDocumentRequestBus") @@ -457,6 +458,11 @@ namespace AtomToolsFramework return result; } + AZ::u32 AtomToolsDocumentSystemComponent::GetDocumentCount() const + { + return aznumeric_cast(m_documentMap.size()); + } + AZ::Uuid AtomToolsDocumentSystemComponent::OpenDocumentImpl(AZStd::string_view sourcePath, bool checkIfAlreadyOpen) { AZStd::string requestedPath = sourcePath; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h index 532271974c..58470e3582 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentSystemComponent.h @@ -74,6 +74,7 @@ namespace AtomToolsFramework bool SaveDocumentAsCopy(const AZ::Uuid& documentId, AZStd::string_view targetPath) override; bool SaveDocumentAsChild(const AZ::Uuid& documentId, AZStd::string_view targetPath) override; bool SaveAllDocuments() override; + AZ::u32 GetDocumentCount() const override; //////////////////////////////////////////////////////////////////////// AZ::Uuid OpenDocumentImpl(AZStd::string_view sourcePath, bool checkIfAlreadyOpen); From 1ef868437a67ec87057df8b87cedb16907df84ee Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Fri, 14 Jan 2022 17:28:14 -0700 Subject: [PATCH 203/272] Added supervariantIndex check in Shader::OnShaderVariantAssetReady Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../Include/Atom/RPI.Reflect/Shader/ShaderVariantAsset.h | 1 + Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp | 6 ++++++ .../Code/Source/RPI.Reflect/Shader/ShaderVariantAsset.cpp | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderVariantAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderVariantAsset.h index 5146ae370a..b65d9837f7 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderVariantAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderVariantAsset.h @@ -50,6 +50,7 @@ namespace AZ RPI::ShaderVariantStableId GetStableId() const { return m_stableId; } const ShaderVariantId& GetShaderVariantId() const { return m_shaderVariantId; } + uint32_t GetSupervariantIndex() const; //! Returns the shader stage function associated with the provided stage enum value. const RHI::ShaderStageFunction* GetShaderStageFunction(RHI::ShaderStage shaderStage) const; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp index 3830d8ee42..ed9d3430d9 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp @@ -253,6 +253,12 @@ namespace AZ AZ_Assert(shaderVariantAsset, "Reloaded ShaderVariantAsset is null"); const ShaderVariantStableId stableId = shaderVariantAsset->GetStableId(); + // check the supervariantIndex of the ShaderVariantAsset to make sure it matches the supervariantIndex of this shader instance + if (shaderVariantAsset->GetSupervariantIndex() != m_supervariantIndex.GetIndex()) + { + return; + } + // We make a copy of the updated variant because OnShaderVariantReinitialized must not be called inside // m_variantCacheMutex or deadlocks may occur. // Or if there is an error, we leave this object in its default state to indicate there was an error. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantAsset.cpp index ec1a65a6d5..f9f046ac8a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantAsset.cpp @@ -65,6 +65,11 @@ namespace AZ return m_buildTimestamp; } + uint32_t ShaderVariantAsset::GetSupervariantIndex() const + { + return (m_assetId.m_subId >> SupervariantIndexBitPosition) & SupervariantIndexMaxValue; + } + const RHI::ShaderStageFunction* ShaderVariantAsset::GetShaderStageFunction(RHI::ShaderStage shaderStage) const { return m_functionsByStage[static_cast(shaderStage)].get(); From 6ac1211ae92889e0d8c8c72a2bdc18df1c2bfd24 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 14 Jan 2022 16:40:08 -0800 Subject: [PATCH 204/272] Add unit tests for ProcessSurfaceWeightsFromRegion and ProcessSurfacePointsFromRegion. Signed-off-by: amzn-sj --- Gems/Terrain/Code/Tests/TerrainSystemTest.cpp | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp index a5798a3dad..2eebc1b824 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp @@ -902,4 +902,168 @@ namespace UnitTest terrainSystem->ProcessNormalsFromRegion(testRegionBox, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); } + + TEST_F(TerrainSystemTest, TerrainProcessSurfaceWeightsFromRegion) + { + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [](AZ::Vector3& position, bool& terrainExists) + { + position.SetZ(1.0f); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(1.0f); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-3.0f, -3.0f, -1.0f, 3.0f, 3.0f, 1.0f); + const AZ::Vector2 stepSize(1.0f); + + const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1"); + const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2"); + const SurfaceData::SurfaceTag tag3 = SurfaceData::SurfaceTag("tag3"); + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight1; + tagWeight1.m_surfaceType = tag1; + tagWeight1.m_weight = 1.0f; + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight2; + tagWeight2.m_surfaceType = tag2; + tagWeight2.m_weight = 0.7f; + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight3; + tagWeight3.m_surfaceType = tag3; + tagWeight3.m_weight = 0.3f; + + NiceMock mockSurfaceRequests(entity->GetId()); + ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault( + [&tagWeight1, &tagWeight2, &tagWeight3](const AZ::Vector3& position, AzFramework::SurfaceData::SurfaceTagWeightList& surfaceWeights) + { + surfaceWeights.clear(); + float absYPos = fabsf(position.GetY()); + if (absYPos < 1.0f) + { + surfaceWeights.push_back(tagWeight1); + } + else if(absYPos < 2.0f) + { + surfaceWeights.push_back(tagWeight2); + } + else + { + surfaceWeights.push_back(tagWeight3); + } + } + ); + + auto perPositionCallback = [&tagWeight1, &tagWeight2, &tagWeight3](size_t xIndex, size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + constexpr float epsilon = 0.0001f; + float absYPos = fabsf(surfacePoint.m_position.GetY()); + if (absYPos < 1.0f) + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight1.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight1.m_weight, epsilon); + } + else if(absYPos < 2.0f) + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight2.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight2.m_weight, epsilon); + } + else + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight3.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight3.m_weight, epsilon); + } + }; + + terrainSystem->ProcessSurfaceWeightsFromRegion(testRegionBox, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR); + } + + TEST_F(TerrainSystemTest, TerrainProcessSurfacePointsFromRegion) + { + const AZ::Aabb spawnerBox = AZ::Aabb::CreateFromMinMaxValues(-10.0f, -10.0f, -5.0f, 10.0f, 10.0f, 15.0f); + auto entity = CreateAndActivateMockTerrainLayerSpawner( + spawnerBox, + [](AZ::Vector3& position, bool& terrainExists) + { + position.SetZ(position.GetX() + position.GetY()); + terrainExists = true; + }); + + // Create and activate the terrain system with our testing defaults for world bounds, and a query resolution at 1 meter intervals. + const AZ::Vector2 queryResolution(1.0f); + auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution); + + const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-3.0f, -3.0f, -1.0f, 3.0f, 3.0f, 1.0f); + const AZ::Vector2 stepSize(1.0f); + + const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1"); + const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2"); + const SurfaceData::SurfaceTag tag3 = SurfaceData::SurfaceTag("tag3"); + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight1; + tagWeight1.m_surfaceType = tag1; + tagWeight1.m_weight = 1.0f; + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight2; + tagWeight2.m_surfaceType = tag2; + tagWeight2.m_weight = 0.7f; + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight3; + tagWeight3.m_surfaceType = tag3; + tagWeight3.m_weight = 0.3f; + + NiceMock mockSurfaceRequests(entity->GetId()); + ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault( + [&tagWeight1, &tagWeight2, &tagWeight3](const AZ::Vector3& position, AzFramework::SurfaceData::SurfaceTagWeightList& surfaceWeights) + { + surfaceWeights.clear(); + float absYPos = fabsf(position.GetY()); + if (absYPos < 1.0f) + { + surfaceWeights.push_back(tagWeight1); + } + else if(absYPos < 2.0f) + { + surfaceWeights.push_back(tagWeight2); + } + else + { + surfaceWeights.push_back(tagWeight3); + } + } + ); + + auto perPositionCallback = [&tagWeight1, &tagWeight2, &tagWeight3](size_t xIndex, size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + { + constexpr float epsilon = 0.0001f; + float expectedHeight = surfacePoint.m_position.GetX() + surfacePoint.m_position.GetY(); + + EXPECT_NEAR(surfacePoint.m_position.GetZ(), expectedHeight, epsilon); + + float absYPos = fabsf(surfacePoint.m_position.GetY()); + if (absYPos < 1.0f) + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight1.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight1.m_weight, epsilon); + } + else if(absYPos < 2.0f) + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight2.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight2.m_weight, epsilon); + } + else + { + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight3.m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight3.m_weight, epsilon); + } + }; + + terrainSystem->ProcessSurfacePointsFromRegion(testRegionBox, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); + } } // namespace UnitTest From b87e6896e6784e35220365f9441313c3c4304a8b Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Fri, 14 Jan 2022 16:43:01 -0800 Subject: [PATCH 205/272] ScreenToWorld and WorldToScreen Camera functionality (#6903) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../AzFramework/Components/CameraBus.h | 26 ++++ .../Component/DebugCamera/CameraComponent.h | 4 + .../Code/Source/CameraComponent.cpp | 26 +++- Gems/Camera/Code/Source/CameraComponent.cpp | 4 + .../Code/Source/CameraComponentController.cpp | 63 ++++++++ .../Code/Source/CameraComponentController.h | 7 + .../EBus/Senders/CameraRequestBus.names | 134 +++++++++++++++++- ...hysXWorld_RayCastFromScreenWithGroup.names | 88 ++++++++++++ .../Code/Source/WorldNodes.h | 39 +++++ 9 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 Gems/ScriptCanvas/Assets/TranslationAssets/Nodes/PhysXWorld_RayCastFromScreenWithGroup.names diff --git a/Code/Framework/AzFramework/AzFramework/Components/CameraBus.h b/Code/Framework/AzFramework/AzFramework/Components/CameraBus.h index e20578e939..964bf664a0 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/CameraBus.h +++ b/Code/Framework/AzFramework/AzFramework/Components/CameraBus.h @@ -129,6 +129,32 @@ namespace Camera GetFrustumHeight() }; } + + //! Unprojects a position in screen space pixel coordinates to world space. + //! With a depth of zero, the position returned will be on the near clip plane of the camera + //! in world space. + //! @param screenPosition The absolute screen position + //! @param depth The depth offset into the world relative to the near clip plane of the camera + //! @return the position in world space + virtual AZ::Vector3 ScreenToWorld(const AZ::Vector2& screenPosition, float depth) = 0; + + //! Unprojects a position in screen space normalized device coordinates to world space. + //! With a depth of zero, the position returned will be on the near clip plane of the camera + //! in world space. + //! @param screenNdcPosition The normalized device coordinates in the range [0,1] + //! @param depth The depth offset into the world relative to the near clip plane of the camera + //! @return the position in world space + virtual AZ::Vector3 ScreenNdcToWorld(const AZ::Vector2& screenNdcPosition, float depth) = 0; + + //! Projects a position in world space to screen space for the given camera. + //! @param worldPosition The world position + //! @return The absolute screen position + virtual AZ::Vector2 WorldToScreen(const AZ::Vector3& worldPosition) = 0; + + //! Projects a position in world space to screen space normalized device coordinates. + //! @param worldPosition The world position + //! @return The normalized device coordinates in the range [0,1] + virtual AZ::Vector2 WorldToScreenNdc(const AZ::Vector3& worldPosition) = 0; }; using CameraRequestBus = AZ::EBus; diff --git a/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraComponent.h b/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraComponent.h index fb9c543bca..47254bcdc5 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraComponent.h +++ b/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraComponent.h @@ -104,6 +104,10 @@ namespace AZ void SetOrthographicHalfWidth(float halfWidth) override; void MakeActiveView() override; bool IsActiveView() override; + AZ::Vector3 ScreenToWorld(const AZ::Vector2& screenPosition, float depth) override; + AZ::Vector3 ScreenNdcToWorld(const AZ::Vector2& screenPosition, float depth) override; + AZ::Vector2 WorldToScreen(const AZ::Vector3& worldPosition) override; + AZ::Vector2 WorldToScreenNdc(const AZ::Vector3& worldPosition) override; // RPI::WindowContextNotificationBus overrides... void OnViewportResized(uint32_t width, uint32_t height) override; diff --git a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp index f3123e2b38..c4420dc417 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp +++ b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp @@ -245,7 +245,7 @@ namespace AZ AZ_Assert(false, "DebugCamera does not support orthographic projection"); } - void CameraComponent::MakeActiveView() + void CameraComponent::MakeActiveView() { // do nothing } @@ -255,6 +255,30 @@ namespace AZ return false; } + AZ::Vector3 CameraComponent::ScreenToWorld([[maybe_unused]] const AZ::Vector2& screenPosition, [[maybe_unused]] float depth) + { + // not implemented + return AZ::Vector3::CreateZero(); + } + + AZ::Vector3 CameraComponent::ScreenNdcToWorld([[maybe_unused]] const AZ::Vector2& screenPosition, [[maybe_unused]] float depth) + { + // not implemented + return AZ::Vector3::CreateZero(); + } + + AZ::Vector2 CameraComponent::WorldToScreen([[maybe_unused]] const AZ::Vector3& worldPosition) + { + // not implemented + return AZ::Vector2::CreateZero(); + } + + AZ::Vector2 CameraComponent::WorldToScreenNdc([[maybe_unused]] const AZ::Vector3& worldPosition) + { + // not implemented + return AZ::Vector2::CreateZero(); + } + void CameraComponent::OnViewportResized(uint32_t width, uint32_t height) { AZ_UNUSED(width); diff --git a/Gems/Camera/Code/Source/CameraComponent.cpp b/Gems/Camera/Code/Source/CameraComponent.cpp index 960f13a082..290691bbbe 100644 --- a/Gems/Camera/Code/Source/CameraComponent.cpp +++ b/Gems/Camera/Code/Source/CameraComponent.cpp @@ -106,6 +106,10 @@ namespace Camera ->Event("SetOrthographic", &CameraRequestBus::Events::SetOrthographic) ->Event("GetOrthographicHalfWidth", &CameraRequestBus::Events::GetOrthographicHalfWidth) ->Event("SetOrthographicHalfWidth", &CameraRequestBus::Events::SetOrthographicHalfWidth) + ->Event("ScreenToWorld", &CameraRequestBus::Events::ScreenToWorld) + ->Event("ScreenNdcToWorld", &CameraRequestBus::Events::ScreenNdcToWorld) + ->Event("WorldToScreen", &CameraRequestBus::Events::WorldToScreen) + ->Event("WorldToScreenNdc", &CameraRequestBus::Events::WorldToScreenNdc) ->VirtualProperty("FieldOfView","GetFovDegrees","SetFovDegrees") ->VirtualProperty("NearClipDistance", "GetNearClipDistance", "SetNearClipDistance") ->VirtualProperty("FarClipDistance", "GetFarClipDistance", "SetFarClipDistance") diff --git a/Gems/Camera/Code/Source/CameraComponentController.cpp b/Gems/Camera/Code/Source/CameraComponentController.cpp index 5b2e26b897..dfb2810fe2 100644 --- a/Gems/Camera/Code/Source/CameraComponentController.cpp +++ b/Gems/Camera/Code/Source/CameraComponentController.cpp @@ -10,12 +10,15 @@ #include "CameraViewRegistrationBus.h" #include +#include #include #include #include #include +#include + namespace Camera { void CameraComponentConfig::Reflect(AZ::ReflectContext* context) @@ -412,6 +415,66 @@ namespace Camera return m_isActiveView; } + namespace Util + { + AZ::Vector3 GetWorldPosition(const AZ::Vector3& origin, float depth, const AzFramework::CameraState& cameraState) + { + if (depth == 0.f) + { + return origin; + } + else + { + const AZ::Vector3 rayDirection = cameraState.m_orthographic ? cameraState.m_forward : (origin - cameraState.m_position); + return origin + (rayDirection.GetNormalized() * depth); + } + } + } + + AZ::Vector3 CameraComponentController::ScreenToWorld(const AZ::Vector2& screenPosition, float depth) + { + const AzFramework::ScreenPoint point{ static_cast(screenPosition.GetX()), static_cast(screenPosition.GetY()) }; + const AzFramework::CameraState& cameraState = GetCameraState(); + const AZ::Vector3 origin = AzFramework::ScreenToWorld(point, cameraState); + return Util::GetWorldPosition(origin, depth, cameraState); + } + + AZ::Vector3 CameraComponentController::ScreenNdcToWorld(const AZ::Vector2& screenNdcPosition, float depth) + { + const AzFramework::CameraState& cameraState = GetCameraState(); + const AZ::Vector3 origin = AzFramework::ScreenNdcToWorld(screenNdcPosition, AzFramework::InverseCameraView(cameraState), AzFramework::InverseCameraProjection(cameraState)); + return Util::GetWorldPosition(origin, depth, cameraState); + } + + AZ::Vector2 CameraComponentController::WorldToScreenNdc(const AZ::Vector3& worldPosition) + { + const AzFramework::CameraState& cameraState = GetCameraState(); + const AZ::Vector3 screenPosition = AzFramework::WorldToScreenNdc(worldPosition, AzFramework::CameraView(cameraState), AzFramework::CameraProjection(cameraState)); + return AZ::Vector3ToVector2(screenPosition); + } + + AZ::Vector2 CameraComponentController::WorldToScreen(const AZ::Vector3& worldPosition) + { + const AzFramework::ScreenPoint& point = AzFramework::WorldToScreen(worldPosition, GetCameraState()); + return AZ::Vector2(static_cast(point.m_x), static_cast(point.m_y)); + } + + AzFramework::CameraState CameraComponentController::GetCameraState() + { + auto viewportContext = GetViewportContext(); + if (!m_atomCamera || ! viewportContext) + { + return AzFramework::CameraState(); + } + + auto windowSize = viewportContext->GetViewportSize(); + auto viewportSize = AzFramework::Vector2FromScreenSize(AzFramework::ScreenSize(windowSize.m_width, windowSize.m_height)); + + AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(m_atomCamera->GetCameraTransform(), viewportSize); + AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, m_atomCamera->GetViewToClipMatrix()); + return cameraState; + } + void CameraComponentController::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, const AZ::Transform& world) { if (m_updatingTransformFromEntity) diff --git a/Gems/Camera/Code/Source/CameraComponentController.h b/Gems/Camera/Code/Source/CameraComponentController.h index 09af7529dc..265ffaa0e9 100644 --- a/Gems/Camera/Code/Source/CameraComponentController.h +++ b/Gems/Camera/Code/Source/CameraComponentController.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,11 @@ namespace Camera void MakeActiveView() override; bool IsActiveView() override; + AZ::Vector3 ScreenToWorld(const AZ::Vector2& screenPosition, float depth) override; + AZ::Vector3 ScreenNdcToWorld(const AZ::Vector2& screenNdcPosition, float depth) override; + AZ::Vector2 WorldToScreen(const AZ::Vector3& worldPosition) override; + AZ::Vector2 WorldToScreenNdc(const AZ::Vector3& worldPosition) override; + // AZ::TransformNotificationBus::Handler interface void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; @@ -127,6 +133,7 @@ namespace Camera void DeactivateAtomView(); void UpdateCamera(); void SetupAtomAuxGeom(AZ::RPI::ViewportContextPtr viewportContext); + AzFramework::CameraState GetCameraState(); CameraComponentConfig m_config; AZ::EntityId m_entityId; diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/CameraRequestBus.names b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/CameraRequestBus.names index 6c0112bfc2..ad2127c2a1 100644 --- a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/CameraRequestBus.names +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/CameraRequestBus.names @@ -31,6 +31,66 @@ } ] }, + { + "base": "WorldToScreen", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke World To Screen" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after World To Screen is invoked" + }, + "details": { + "name": "World To Screen" + }, + "params": [ + { + "typeid": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "details": { + "name": "World Position" + } + } + ], + "results": [ + { + "typeid": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "details": { + "name": "Screen Position" + } + } + ] + }, + { + "base": "WorldToScreenNdc", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke World To Screen Ndc" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after World To Screen Ndc is invoked" + }, + "details": { + "name": "World To Screen NDC" + }, + "params": [ + { + "typeid": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "details": { + "name": "World Position" + } + } + ], + "results": [ + { + "typeid": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "details": { + "name": "Screen NDC Position" + } + } + ] + }, { "base": "GetFov", "entry": { @@ -53,6 +113,78 @@ } ] }, + { + "base": "ScreenToWorld", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Screen To World" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Screen To World is invoked" + }, + "details": { + "name": "Screen To World" + }, + "params": [ + { + "typeid": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "details": { + "name": "Screen Position" + } + }, + { + "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", + "details": { + "name": "Depth" + } + } + ], + "results": [ + { + "typeid": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "details": { + "name": "World Position" + } + } + ] + }, + { + "base": "ScreenNdcToWorld", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Screen Ndc To World" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Screen Ndc To World is invoked" + }, + "details": { + "name": "Screen NDC To World" + }, + "params": [ + { + "typeid": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "details": { + "name": "Screen NDC Position" + } + }, + { + "typeid": "{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}", + "details": { + "name": "Depth" + } + } + ], + "results": [ + { + "typeid": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "details": { + "name": "World Position" + } + } + ] + }, { "base": "SetFovRadians", "entry": { @@ -356,4 +488,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/Nodes/PhysXWorld_RayCastFromScreenWithGroup.names b/Gems/ScriptCanvas/Assets/TranslationAssets/Nodes/PhysXWorld_RayCastFromScreenWithGroup.names new file mode 100644 index 0000000000..447866ae44 --- /dev/null +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/Nodes/PhysXWorld_RayCastFromScreenWithGroup.names @@ -0,0 +1,88 @@ +{ + "entries": [ + { + "base": "{B164D87F-6620-5A1D-A2BC-CC09BA18C9B1}", + "context": "ScriptCanvas::Node", + "variant": "", + "details": { + "name": "Ray Cast From Screen With Group", + "category": "PhysX/World", + "tooltip": "Returns the first entity hit by a ray cast from the provided absolute 2D screen position." + }, + "slots": [ + { + "base": "Input_In_0", + "details": { + "name": "In" + } + }, + { + "base": "Output_Out_0", + "details": { + "name": "Out" + } + }, + { + "base": "DataInput_Screen Position_0", + "details": { + "name": "Screen Position" + } + }, + { + "base": "DataInput_Distance_1", + "details": { + "name": "Distance" + } + }, + { + "base": "DataInput_Collision group_2", + "details": { + "name": "Collision group" + } + }, + { + "base": "DataInput_Ignore_3", + "details": { + "name": "Ignore" + } + }, + { + "base": "DataOutput_Object hit_0", + "details": { + "name": "Object hit" + } + }, + { + "base": "DataOutput_Position_1", + "details": { + "name": "Position" + } + }, + { + "base": "DataOutput_Normal_2", + "details": { + "name": "Normal" + } + }, + { + "base": "DataOutput_Distance_3", + "details": { + "name": "Distance" + } + }, + { + "base": "DataOutput_EntityId_4", + "details": { + "name": "EntityId" + } + }, + { + "base": "DataOutput_Surface_5", + "details": { + "name": "Surface" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvasPhysics/Code/Source/WorldNodes.h b/Gems/ScriptCanvasPhysics/Code/Source/WorldNodes.h index 96a15a9d29..1b03bd1851 100644 --- a/Gems/ScriptCanvasPhysics/Code/Source/WorldNodes.h +++ b/Gems/ScriptCanvasPhysics/Code/Source/WorldNodes.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -120,6 +121,43 @@ namespace ScriptCanvasPhysics "EntityId", "Surface"); + AZ_INLINE Result RayCastFromScreenWithGroup( + const AZ::Vector2& screenPosition, + float distance, + const AZStd::string& collisionGroup, + AZ::EntityId ignore) + { + AZ::EntityId camera; + Camera::CameraSystemRequestBus::BroadcastResult(camera, &Camera::CameraSystemRequestBus::Events::GetActiveCamera); + if (camera.IsValid()) + { + AZ::Vector3 origin = AZ::Vector3::CreateZero(); + Camera::CameraRequestBus::EventResult(origin, camera, &Camera::CameraRequestBus::Events::ScreenToWorld, screenPosition, 0.f); + AZ::Vector3 offset = AZ::Vector3::CreateZero(); + Camera::CameraRequestBus::EventResult(offset, camera, &Camera::CameraRequestBus::Events::ScreenToWorld, screenPosition, 1.f); + const AZ::Vector3 direction = (offset - origin).GetNormalized(); + return RayCastWorldSpaceWithGroup(origin, direction, distance, collisionGroup, ignore); + } + + // fallback in the rare case there is no active camera + return AZStd::make_tuple(false, AZ::Vector3::CreateZero(), AZ::Vector3::CreateZero(), 0.0f, AZ::EntityId(), AZ::Crc32()); + } + + SCRIPT_CANVAS_GENERIC_FUNCTION_NODE(RayCastFromScreenWithGroup, + k_categoryName, + "{8F98A766-A93F-4DA7-B281-482C3DB20649}", + "Returns the first entity hit by a ray cast from the provided absolute 2D screen position.", + "Screen Position", + "Distance", + "Collision group", + "Ignore", + "Object hit", + "Position", + "Normal", + "Distance", + "EntityId", + "Surface"); + AZ_INLINE Result RayCastLocalSpaceWithGroup(const AZ::EntityId& fromEntityId, const AZ::Vector3& direction, float distance, @@ -389,6 +427,7 @@ namespace ScriptCanvasPhysics Date: Fri, 14 Jan 2022 16:59:26 -0800 Subject: [PATCH 206/272] Update TerrainPhysicsColliderTests to add mocks for the ProcessRegion functions since the TerrainPhysicsColliderComponent now uses the ProcessRegion functions Signed-off-by: amzn-sj --- .../Tests/TerrainPhysicsColliderTests.cpp | 96 ++++++++++++++++--- 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp index 340acfbaac..859e618983 100644 --- a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp +++ b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp @@ -238,6 +238,33 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsRetu AZ::Vector2 mockHeightResolution = AZ::Vector2(1.0f); NiceMock terrainListener; ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); + ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( + [](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + { + if (!perPositionCallback) + { + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, 0.0f); + perPositionCallback(x, y, surfacePoint, terrainExists); + } + } + } + ); int32_t cols, rows; Physics::HeightfieldProviderRequestsBus::Event( @@ -271,8 +298,34 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsRelativ AZ::Vector2 mockHeightResolution = AZ::Vector2(1.0f); NiceMock terrainListener; - ON_CALL(terrainListener, GetHeightFromFloats).WillByDefault(Return(mockHeight)); ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); + ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( + [mockHeight](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + { + if (!perPositionCallback) + { + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, mockHeight); + perPositionCallback(x, y, surfacePoint, terrainExists); + } + } + } + ); // Just return the bounds as setup. This is equivalent to the box being at the origin. NiceMock boxShape(m_entity->GetId()); @@ -416,20 +469,39 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM NiceMock terrainListener; ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); - ON_CALL(terrainListener, GetHeightFromFloats).WillByDefault(Return(mockHeight)); - ON_CALL(terrainListener, GetMaxSurfaceWeightFromFloats) - .WillByDefault( - [return1, return2]( - [[maybe_unused]] float x, [[maybe_unused]] float y, - [[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) + ON_CALL(terrainListener, ProcessSurfacePointsFromRegion).WillByDefault( + [mockHeight, return1, return2](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + { + if (!perPositionCallback) { - // return tag1 for the first half of the rows, tag2 for the rest. - if (y < 128.0) + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) { - return return1; + surfacePoint.m_surfaceTags.clear(); + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, mockHeight); + if (fy < 128.0) + { + surfacePoint.m_surfaceTags.push_back(return1); + } + surfacePoint.m_surfaceTags.push_back(return2); + perPositionCallback(x, y, surfacePoint, terrainExists); } - return return2; - }); + } + } + ); AZStd::vector heightsAndMaterials; From 76ff7aec29ad67f11f0dc84e47702cc8757dcdd2 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 14 Jan 2022 17:41:18 -0800 Subject: [PATCH 207/272] Fix type (#6919) Signed-off-by: amzn-sj --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index c27bf1fde4..fff816cb3e 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -216,7 +216,7 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") # fixup bundle ends up removing the rpath of dxc (despite we exclude it) if(EXISTS "${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7") - execute_process(COMMAND $"{LY_INSTALL_NAME_TOOL}" -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) + execute_process(COMMAND "${LY_INSTALL_NAME_TOOL}" -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) endif() # misplaced .DS_Store files can cause signing to fail From 646443cfe56c2dde2d466aa8bc38743fa09c506b Mon Sep 17 00:00:00 2001 From: Roddie Kieley Date: Sat, 15 Jan 2022 14:15:27 -0330 Subject: [PATCH 208/272] issue5299: Resolved via change to not disable custom window decorations. Signed-off-by: Roddie Kieley --- .../Platform/Linux/source/utils/GUIApplicationManager_Linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/AssetBundler/Platform/Linux/source/utils/GUIApplicationManager_Linux.cpp b/Code/Tools/AssetBundler/Platform/Linux/source/utils/GUIApplicationManager_Linux.cpp index 04f579cc66..5c2ac13d0e 100644 --- a/Code/Tools/AssetBundler/Platform/Linux/source/utils/GUIApplicationManager_Linux.cpp +++ b/Code/Tools/AssetBundler/Platform/Linux/source/utils/GUIApplicationManager_Linux.cpp @@ -12,6 +12,6 @@ namespace Platform { AzQtComponents::WindowDecorationWrapper::Option GetWindowDecorationWrapperOption() { - return AzQtComponents::WindowDecorationWrapper::OptionDisabled; + return AzQtComponents::WindowDecorationWrapper::OptionNone; } } \ No newline at end of file From f05ca0897e0a180123ebb172a5d7bf23ad8eeda1 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Sat, 15 Jan 2022 14:26:58 -0800 Subject: [PATCH 209/272] Fix some warnings and remove an unused function parameter Signed-off-by: amzn-sj --- .../Source/Components/TerrainPhysicsColliderComponent.cpp | 2 +- .../Source/Components/TerrainWorldDebuggerComponent.cpp | 6 +++--- .../Code/Source/Components/TerrainWorldDebuggerComponent.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index 4a8b4680b3..c74a478dad 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -344,7 +344,7 @@ namespace Terrain AZStd::vector materialList = GetMaterialList(); auto perPositionCallback = [&heightMaterials, &materialList, this, worldCenterZ, worldHeightBoundsMin, worldHeightBoundsMax] - (size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists) + ([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists) { float height = surfacePoint.m_position.GetZ(); diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp index 46be621307..f684727d33 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -297,7 +297,7 @@ namespace Terrain { if (sector.m_isDirty) { - RebuildSectorWireframe(sector, heightDataResolution, worldMinZ); + RebuildSectorWireframe(sector, heightDataResolution); } if (!sector.m_lineVertices.empty()) @@ -317,7 +317,7 @@ namespace Terrain } - void TerrainWorldDebuggerComponent::RebuildSectorWireframe(WireframeSector& sector, const AZ::Vector2& gridResolution, float worldMinZ) + void TerrainWorldDebuggerComponent::RebuildSectorWireframe(WireframeSector& sector, const AZ::Vector2& gridResolution) { if (!sector.m_isDirty) { @@ -354,7 +354,7 @@ namespace Terrain // For each terrain height value in the region, create the _| grid lines for that point and cache off the height value // for use with subsequent grid line calculations. auto ProcessHeightValue = [gridResolution, &previousHeight, &rowHeights, §or] - (uint32_t xIndex, uint32_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) + (size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { // Don't add any vertices for the first column or first row. These grid lines will be handled by an adjacent sector, if // there is one. diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h index f3bcead8c3..cb308effe6 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h @@ -93,7 +93,7 @@ namespace Terrain bool m_isDirty{ true }; }; - void RebuildSectorWireframe(WireframeSector& sector, const AZ::Vector2& gridResolution, float worldMinZ); + void RebuildSectorWireframe(WireframeSector& sector, const AZ::Vector2& gridResolution); void MarkDirtySectors(const AZ::Aabb& dirtyRegion); void DrawWorldBounds(AzFramework::DebugDisplayRequests& debugDisplay); void DrawWireframe(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay); From ced7d1ef542f1e1fe58c7c0577151db7aea0461e Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Mon, 17 Jan 2022 01:29:23 -0600 Subject: [PATCH 210/272] Atom Tools: Bind exit function for python tests Signed-off-by: Guthrie Adams --- .../Application/AtomToolsApplication.h | 1 + .../Code/Source/Application/AtomToolsApplication.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 9eaacbfa4f..35d8302b49 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -111,6 +111,7 @@ namespace AtomToolsFramework virtual void ProcessCommandLine(const AZ::CommandLine& commandLine); static void PyIdleWaitFrames(uint32_t frames); + static void PyExit(); AzToolsFramework::TraceLogger m_traceLogger; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 02248fffd4..5d17e758f9 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -130,10 +130,13 @@ namespace AtomToolsFramework ->Attribute(AZ::Script::Attributes::Category, "Editor") ->Attribute(AZ::Script::Attributes::Module, "atomtools.general"); }; - // The reflection here is based on patterns in CryEditPythonHandler::Reflect + addGeneral(behaviorContext->Method( "idle_wait_frames", &AtomToolsApplication::PyIdleWaitFrames, nullptr, "Waits idling for a frames. Primarily used for auto-testing.")); + addGeneral(behaviorContext->Method( + "exit", &AtomToolsApplication::PyExit, nullptr, + "Exit application. Primarily used for auto-testing.")); } } @@ -564,4 +567,9 @@ namespace AtomToolsFramework Ticker ticker(&loop, frames); loop.exec(); } + + void AtomToolsApplication::PyExit() + { + AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop); + } } // namespace AtomToolsFramework From 1cfa4a9bd5677bd65d39353d0e69f23edfb5eb22 Mon Sep 17 00:00:00 2001 From: windbagjacket Date: Mon, 17 Jan 2022 10:00:07 +0000 Subject: [PATCH 211/272] Removed tab usage. Signed-off-by: windbagjacket --- .../EMotionFXAtom/Code/Source/AtomActorInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index bb467b2259..742031c84f 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -376,7 +376,7 @@ namespace AZ::Render bool AtomActorInstance::GetVisibility() const { - return IsVisible(); + return IsVisible(); } void AtomActorInstance::SetRayTracingEnabled(bool enabled) From aac28f73aaf9ff72232aafeaa589fcb0437a7cc8 Mon Sep 17 00:00:00 2001 From: Bindless-Chicken <1039134+Bindless-Chicken@users.noreply.github.com> Date: Mon, 17 Jan 2022 14:25:50 +0000 Subject: [PATCH 212/272] Fix missing ImGui::End in multiplayer windows Signed-off-by: Bindless-Chicken <1039134+Bindless-Chicken@users.noreply.github.com> --- .../Code/Source/Debug/MultiplayerDebugSystemComponent.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp index 4ff78d3815..4266072d20 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp @@ -386,7 +386,6 @@ namespace Multiplayer } ImGui::NewLine(); } - ImGui::End(); } void DrawMultiplayerStats() @@ -437,7 +436,6 @@ namespace Multiplayer ImGui::EndTable(); ImGui::NewLine(); } - ImGui::End(); } void MultiplayerDebugSystemComponent::OnImGuiUpdate() @@ -448,6 +446,7 @@ namespace Multiplayer { DrawNetworkingStats(); } + ImGui::End(); } if (m_displayMultiplayerStats) @@ -456,6 +455,7 @@ namespace Multiplayer { DrawMultiplayerStats(); } + ImGui::End(); } if (m_displayPerEntityStats) @@ -473,6 +473,7 @@ namespace Multiplayer m_reporter->OnImGuiUpdate(); } } + ImGui::End(); } if (m_displayHierarchyDebugger) @@ -489,6 +490,7 @@ namespace Multiplayer m_hierarchyDebugger->OnImGuiUpdate(); } } + ImGui::End(); } else { From 0b9dc78d67d1ddea29b4fae29bd75c0335dee9ae Mon Sep 17 00:00:00 2001 From: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> Date: Mon, 17 Jan 2022 17:58:19 +0000 Subject: [PATCH 213/272] Fixed problem with inputting numbers in sliders (#6859) * Fixed problem with inputting numbers in sliders Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> * Changes from PR Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> * Missed removing pragma optimize Signed-off-by: John Jones-Steele <82226755+jjjoness@users.noreply.github.com> --- .../AzQtComponents/Components/Widgets/Slider.cpp | 3 +-- .../AzQtComponents/Components/Widgets/SliderCombo.cpp | 10 +++++----- .../AzQtComponents/Components/Widgets/SliderCombo.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/Slider.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/Slider.cpp index 14ac2010bc..f50b9c36ec 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/Slider.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/Slider.cpp @@ -870,8 +870,7 @@ void SliderDouble::setCurveMidpoint(double midpoint) QString SliderDouble::hoverValueText(int sliderValue) const { - // maybe format this, max number of digits? - QString valueText = locale().toString(calculateRealSliderValue(sliderValue), 'f', m_decimals); + QString valueText = toString(calculateRealSliderValue(sliderValue), m_decimals, locale(), false, true); return QStringLiteral("%1").arg(valueText); } diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.cpp index 6333d28365..9d289e5d44 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.cpp @@ -14,6 +14,7 @@ #include #include +#include namespace AzQtComponents { @@ -254,11 +255,12 @@ SliderDoubleCombo::~SliderDoubleCombo() { } +bool m_fromSlider{ false }; + void SliderDoubleCombo::setValueSlider(double value) { const bool doEmit = m_value != value; m_value = value; - updateSpinBox(); updateSlider(); @@ -267,6 +269,8 @@ void SliderDoubleCombo::setValueSlider(double value) // We don't want to update the slider from setValue as this // causes rounding errors in the tooltip hint. m_fromSlider = true; + QTimer::singleShot( 10, []() { m_fromSlider = false; }); + Q_EMIT valueChanged(); } } @@ -286,10 +290,6 @@ void SliderDoubleCombo::setValue(double value) Q_EMIT valueChanged(); } } - else - { - m_fromSlider = false; - } } SliderDouble* SliderDoubleCombo::slider() const diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.h index 05d0f7b51b..be6c86b520 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.h +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/SliderCombo.h @@ -237,6 +237,5 @@ namespace AzQtComponents double m_softMinimum = 0.0; double m_softMaximum = 100.0; double m_value = 0.0; - bool m_fromSlider{ false }; }; } // namespace AzQtComponents From 2b103ce445fb09ad955af4a44128132d58e5a48b Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Mon, 17 Jan 2022 16:52:30 -0700 Subject: [PATCH 214/272] Added support for supervariants to the PrecompiledShaderBuilder Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../AzslShaderBuilderSystemComponent.cpp | 2 +- .../Editor/PrecompiledShaderBuilder.cpp | 65 +++++++++-------- ...seProbeGridBlendDistance.precompiledshader | 31 ++++---- ...ProbeGridBlendIrradiance.precompiledshader | 31 ++++---- ...beGridBorderUpdateColumn.precompiledshader | 33 +++++---- ...ProbeGridBorderUpdateRow.precompiledshader | 37 +++++----- ...eProbeGridClassification.precompiledshader | 31 ++++---- ...ffuseProbeGridRayTracing.precompiledshader | 38 +++++----- ...GridRayTracingClosestHit.precompiledshader | 35 +++++---- ...eProbeGridRayTracingMiss.precompiledshader | 33 +++++---- ...ffuseProbeGridRelocation.precompiledshader | 35 +++++---- .../DiffuseProbeGridRender.precompiledshader | 35 +++++---- .../Shader/PrecompiledShaderAssetSourceData.h | 27 +++++-- .../RPI.Reflect/Shader/ShaderAssetCreator.h | 15 +++- .../PrecompiledShaderAssetSourceData.cpp | 28 ++++++-- .../RPI.Reflect/Shader/ShaderAssetCreator.cpp | 72 ++++++++++++------- 16 files changed, 341 insertions(+), 207 deletions(-) diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp index cc80b38b85..eae4e804e0 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp @@ -120,7 +120,7 @@ namespace AZ // Register Precompiled Shader Builder AssetBuilderSDK::AssetBuilderDesc precompiledShaderBuilderDescriptor; precompiledShaderBuilderDescriptor.m_name = "Precompiled Shader Builder"; - precompiledShaderBuilderDescriptor.m_version = 10; // ATOM-15472 + precompiledShaderBuilderDescriptor.m_version = 11; // ATOM-15740 precompiledShaderBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", AZ::PrecompiledShaderBuilder::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); precompiledShaderBuilderDescriptor.m_busId = azrtti_typeid(); precompiledShaderBuilderDescriptor.m_createJobFunction = AZStd::bind(&PrecompiledShaderBuilder::CreateJobs, &m_precompiledShaderBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp index 2abee4d297..05b4ff309b 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp @@ -68,20 +68,23 @@ namespace AZ { AZStd::vector jobDependencyList; - // setup dependencies on the root azshadervariant asset file names - for (const auto& rootShaderVariantAsset : precompiledShaderAsset.m_rootShaderVariantAssets) + // setup dependencies on the root azshadervariant asset file names, for each supervariant + for (const auto& supervariant : precompiledShaderAsset.m_supervariants) { - AZStd::string rootShaderVariantAssetPath = RPI::AssetUtils::ResolvePathReference(request.m_sourceFile.c_str(), rootShaderVariantAsset->m_rootShaderVariantAssetFileName); - AssetBuilderSDK::SourceFileDependency sourceDependency; - sourceDependency.m_sourceFileDependencyPath = rootShaderVariantAssetPath; - response.m_sourceFileDependencyList.push_back(sourceDependency); + for (const auto& rootShaderVariantAsset : supervariant->m_rootShaderVariantAssets) + { + AZStd::string rootShaderVariantAssetPath = RPI::AssetUtils::ResolvePathReference(request.m_sourceFile.c_str(), rootShaderVariantAsset->m_rootShaderVariantAssetFileName); + AssetBuilderSDK::SourceFileDependency sourceDependency; + sourceDependency.m_sourceFileDependencyPath = rootShaderVariantAssetPath; + response.m_sourceFileDependencyList.push_back(sourceDependency); - AssetBuilderSDK::JobDependency jobDependency; - jobDependency.m_jobKey = "azshadervariant"; - jobDependency.m_platformIdentifier = platformInfo.m_identifier; - jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order; - jobDependency.m_sourceFile = sourceDependency; - jobDependencyList.push_back(jobDependency); + AssetBuilderSDK::JobDependency jobDependency; + jobDependency.m_jobKey = "azshadervariant"; + jobDependency.m_platformIdentifier = platformInfo.m_identifier; + jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order; + jobDependency.m_sourceFile = sourceDependency; + jobDependencyList.push_back(jobDependency); + } } AssetBuilderSDK::JobDescriptor job; @@ -137,33 +140,37 @@ namespace AZ AssetBuilderSDK::JobProduct jobProduct; - // load the variant product assets + // load the variant product assets, for each supervariant // these are the dependency root variant asset products that were processed prior to running this job - RPI::ShaderAssetCreator::ShaderRootVariantAssets rootVariantProductAssets; - for (AZStd::unique_ptr& rootShaderVariantAsset : precompiledShaderAsset.m_rootShaderVariantAssets) + RPI::ShaderAssetCreator::ShaderSupervariants supervariants; + for (const auto& supervariant : precompiledShaderAsset.m_supervariants) { - // retrieve the variant asset - auto assetOutcome = RPI::AssetUtils::LoadAsset(request.m_fullPath, rootShaderVariantAsset->m_rootShaderVariantAssetFileName, 0); - if (!assetOutcome) + RPI::ShaderAssetCreator::ShaderRootVariantAssets rootVariantProductAssets; + for (const auto& rootShaderVariantAsset : supervariant->m_rootShaderVariantAssets) { - AZ_Error(PrecompiledShaderBuilderName, false, "Failed to retrieve Variant asset for file [%s]", rootShaderVariantAsset->m_rootShaderVariantAssetFileName.c_str()); - return; + // retrieve the variant asset + auto assetOutcome = RPI::AssetUtils::LoadAsset(request.m_fullPath, rootShaderVariantAsset->m_rootShaderVariantAssetFileName, 0); + if (!assetOutcome) + { + AZ_Error(PrecompiledShaderBuilderName, false, "Failed to retrieve Variant asset for file [%s]", rootShaderVariantAsset->m_rootShaderVariantAssetFileName.c_str()); + return; + } + + rootVariantProductAssets.push_back(AZStd::make_pair(RHI::APIType{ rootShaderVariantAsset->m_apiName.GetCStr() }, assetOutcome.GetValue())); + + AssetBuilderSDK::ProductDependency productDependency; + productDependency.m_dependencyId = assetOutcome.GetValue().GetId(); + productDependency.m_flags = AZ::Data::ProductDependencyInfo::CreateFlags(AZ::Data::AssetLoadBehavior::PreLoad); + jobProduct.m_dependencies.push_back(productDependency); } - rootVariantProductAssets.push_back(AZStd::make_pair(RHI::APIType{ rootShaderVariantAsset->m_apiName.GetCStr() }, assetOutcome.GetValue())); - - AssetBuilderSDK::ProductDependency productDependency; - productDependency.m_dependencyId = assetOutcome.GetValue().GetId(); - productDependency.m_flags = AZ::Data::ProductDependencyInfo::CreateFlags(AZ::Data::AssetLoadBehavior::PreLoad); - jobProduct.m_dependencies.push_back(productDependency); + supervariants.push_back({ supervariant->m_name, rootVariantProductAssets }); } // use the ShaderAssetCreator to clone the shader asset, which will update the embedded Srg and Variant asset UUIDs // Note that the Srg and Variant assets do not have embedded asset references and are processed with the RC Copy functionality RPI::ShaderAssetCreator shaderAssetCreator; - shaderAssetCreator.Clone(Uuid::CreateRandom(), - *shaderAsset, - rootVariantProductAssets); + shaderAssetCreator.Clone(Uuid::CreateRandom(), *shaderAsset, supervariants); Data::Asset outputShaderAsset; if (!shaderAssetCreator.End(outputShaderAsset)) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistance.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistance.precompiledshader index be1d87ff3e..81d6bde5f0 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistance.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistance.precompiledshader @@ -7,21 +7,28 @@ "ShaderAssetFileName": "diffuseprobegridblenddistance.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridblenddistance_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiance.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiance.precompiledshader index 92fb12d5cc..9fa8e27461 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiance.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiance.precompiledshader @@ -7,21 +7,28 @@ "ShaderAssetFileName": "diffuseprobegridblendirradiance.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridblendirradiance_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateColumn.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateColumn.precompiledshader index 8de77320f0..f2363bd5ee 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateColumn.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateColumn.precompiledshader @@ -5,23 +5,30 @@ "ClassData": { "ShaderAssetFileName": "diffuseprobegridborderupdatecolumn.azshader", - "PlatformIdentifiers": + "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdatecolumn_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateRow.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateRow.precompiledshader index 274dae91af..d87cc47a38 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateRow.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdateRow.precompiledshader @@ -2,26 +2,31 @@ "Type": "JsonSerialization", "Version": 1, "ClassName": "PrecompiledShaderAssetSourceData", - "ClassData": - { + "ClassData": { "ShaderAssetFileName": "diffuseprobegridborderupdaterow.azshader", - "PlatformIdentifiers": - [ - "pc", "linux" + "PlatformIdentifiers": [ + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridborderupdaterow_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridClassification.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridClassification.precompiledshader index 85f75e6364..66671fd7bc 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridClassification.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridClassification.precompiledshader @@ -7,21 +7,28 @@ "ShaderAssetFileName": "diffuseprobegridclassification.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridclassification_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridclassification_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridclassification_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridclassification_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridclassification_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridclassification_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracing.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracing.precompiledshader index 88aa115b63..7b156ca7e5 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracing.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracing.precompiledshader @@ -2,27 +2,33 @@ "Type": "JsonSerialization", "Version": 1, "ClassName": "PrecompiledShaderAssetSourceData", - "ClassData": + "ClassData": { "ShaderAssetFileName": "diffuseprobegridraytracing.azshader", - "PlatformIdentifiers": - [ - "pc", "linux" + "PlatformIdentifiers": [ + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracing_null_0.azshadervariant" + } + ] } ] } -} +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingClosestHit.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingClosestHit.precompiledshader index 948fc793ab..d19eb4baf1 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingClosestHit.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingClosestHit.precompiledshader @@ -2,27 +2,34 @@ "Type": "JsonSerialization", "Version": 1, "ClassName": "PrecompiledShaderAssetSourceData", - "ClassData": + "ClassData": { "ShaderAssetFileName": "diffuseprobegridraytracingclosesthit.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingclosesthit_null_0.azshadervariant" + } + ] } ] } -} +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingMiss.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingMiss.precompiledshader index dec0e244b1..d30783db14 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingMiss.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingMiss.precompiledshader @@ -2,26 +2,33 @@ "Type": "JsonSerialization", "Version": 1, "ClassName": "PrecompiledShaderAssetSourceData", - "ClassData": + "ClassData": { "ShaderAssetFileName": "diffuseprobegridraytracingmiss.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridraytracingmiss_null_0.azshadervariant" + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRelocation.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRelocation.precompiledshader index e09a29a7e8..56b487ceb6 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRelocation.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRelocation.precompiledshader @@ -2,27 +2,34 @@ "Type": "JsonSerialization", "Version": 1, "ClassName": "PrecompiledShaderAssetSourceData", - "ClassData": + "ClassData": { "ShaderAssetFileName": "diffuseprobegridrelocation.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_null_0.azshadervariant" + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridrelocation_null_0.azshadervariant" + } + ] } ] } -} +} \ No newline at end of file diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRender.precompiledshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRender.precompiledshader index 279deaaa29..97c58091a2 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRender.precompiledshader +++ b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRender.precompiledshader @@ -7,22 +7,29 @@ "ShaderAssetFileName": "diffuseprobegridrender.azshader", "PlatformIdentifiers": [ - "pc", "linux" + "pc", + "linux" ], - "RootShaderVariantAssets": + "Supervariants": [ { - "APIName": "dx12", - "RootShaderVariantAssetFileName": "diffuseprobegridrender_dx12_0.azshadervariant" - }, - { - "APIName": "vulkan", - "RootShaderVariantAssetFileName": "diffuseprobegridrender_vulkan_0.azshadervariant" - }, - { - "APIName": "null", - "RootShaderVariantAssetFileName": "diffuseprobegridrender_null_0.azshadervariant" - } + "Name": "", + "RootShaderVariantAssets": + [ + { + "APIName": "dx12", + "RootShaderVariantAssetFileName": "diffuseprobegridrender_dx12_0.azshadervariant" + }, + { + "APIName": "vulkan", + "RootShaderVariantAssetFileName": "diffuseprobegridrender_vulkan_0.azshadervariant" + }, + { + "APIName": "null", + "RootShaderVariantAssetFileName": "diffuseprobegridrender_null_0.azshadervariant" + } + ] + } ] } -} +} \ No newline at end of file diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.h index ce5a4c8a7a..956367c126 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.h @@ -17,14 +17,14 @@ namespace AZ namespace RPI { - //! This asset contains is loaded from a Json file and contains information about + //! This asset is loaded from a Json file and contains information about //! precompiled shader variants and their associated API name. - struct RootShaderVariantAssetSourceData final + struct PrecompiledRootShaderVariantAssetSourceData final : public Data::AssetData { public: - AZ_RTTI(RootShaderVariantAssetSourceData, "{661EF8A7-7BAC-41B6-AD5C-C7249B2390AD}"); - AZ_CLASS_ALLOCATOR(RootShaderVariantAssetSourceData, SystemAllocator, 0); + AZ_RTTI(PrecompiledRootShaderVariantAssetSourceData, "{661EF8A7-7BAC-41B6-AD5C-C7249B2390AD}"); + AZ_CLASS_ALLOCATOR(PrecompiledRootShaderVariantAssetSourceData, SystemAllocator, 0); static void Reflect(ReflectContext* context); @@ -32,7 +32,22 @@ namespace AZ AZStd::string m_rootShaderVariantAssetFileName; }; - //! This asset contains is loaded from a Json file and contains information about + //! This asset is loaded from a Json file and contains information about + //! precompiled shader supervariants + struct PrecompiledSupervariantSourceData final + : public Data::AssetData + { + public: + AZ_RTTI(PrecompiledSupervariantSourceData, "{630BDF15-CE7C-4E2C-882E-4F7AF09C8BB6}"); + AZ_CLASS_ALLOCATOR(PrecompiledSupervariantSourceData, SystemAllocator, 0); + + static void Reflect(ReflectContext* context); + + AZ::Name m_name; + AZStd::vector> m_rootShaderVariantAssets; + }; + + //! This asset is loaded from a Json file and contains information about //! precompiled shader assets. struct PrecompiledShaderAssetSourceData final : public Data::AssetData @@ -45,7 +60,7 @@ namespace AZ AZStd::string m_shaderAssetFileName; AZStd::vector m_platformIdentifiers; - AZStd::vector> m_rootShaderVariantAssets; + AZStd::vector> m_supervariants; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderAssetCreator.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderAssetCreator.h index 22854a4559..d0c9729948 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderAssetCreator.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Shader/ShaderAssetCreator.h @@ -75,11 +75,20 @@ namespace AZ bool End(Data::Asset& shaderAsset); - //! Clones an existing ShaderAsset nd replaces the referenced Srg and Variant assets - using ShaderRootVariantAssets = AZStd::vector>>; + //! Clones an existing ShaderAsset and replaces the ShaderVariant assets + using ShaderRootVariantAssetPair = AZStd::pair>; + using ShaderRootVariantAssets = AZStd::vector; + + struct ShaderSupervariant + { + AZ::Name m_name; + ShaderRootVariantAssets m_rootVariantAssets; + }; + using ShaderSupervariants = AZStd::vector; + void Clone(const Data::AssetId& assetId, const ShaderAsset& sourceShaderAsset, - const ShaderRootVariantAssets& rootVariantAssets); + const ShaderSupervariants& supervariants); private: diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.cpp index a7a9344d6e..62fb904b37 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/PrecompiledShaderAssetSourceData.cpp @@ -14,29 +14,43 @@ namespace AZ { namespace RPI { - void RootShaderVariantAssetSourceData::Reflect(ReflectContext* context) + void PrecompiledRootShaderVariantAssetSourceData::Reflect(ReflectContext* context) { if (auto* serializeContext = azrtti_cast(context)) { - serializeContext->Class() + serializeContext->Class() ->Version(0) - ->Field("APIName", &RootShaderVariantAssetSourceData::m_apiName) - ->Field("RootShaderVariantAssetFileName", &RootShaderVariantAssetSourceData::m_rootShaderVariantAssetFileName) + ->Field("APIName", &PrecompiledRootShaderVariantAssetSourceData::m_apiName) + ->Field("RootShaderVariantAssetFileName", &PrecompiledRootShaderVariantAssetSourceData::m_rootShaderVariantAssetFileName) + ; + } + } + + void PrecompiledSupervariantSourceData::Reflect(ReflectContext* context) + { + PrecompiledRootShaderVariantAssetSourceData::Reflect(context); + + if (auto* serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("Name", &PrecompiledSupervariantSourceData::m_name) + ->Field("RootShaderVariantAssets", &PrecompiledSupervariantSourceData::m_rootShaderVariantAssets) ; } } void PrecompiledShaderAssetSourceData::Reflect(ReflectContext* context) { - RootShaderVariantAssetSourceData::Reflect(context); + PrecompiledSupervariantSourceData::Reflect(context); if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(1) // ATOM-15472 + ->Version(2) // ATOM-15740 ->Field("ShaderAssetFileName", &PrecompiledShaderAssetSourceData::m_shaderAssetFileName) ->Field("PlatformIdentifiers", &PrecompiledShaderAssetSourceData::m_platformIdentifiers) - ->Field("RootShaderVariantAssets", &PrecompiledShaderAssetSourceData::m_rootShaderVariantAssets) + ->Field("Supervariants", &PrecompiledShaderAssetSourceData::m_supervariants) ; } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAssetCreator.cpp index 5df37aa211..e56561b400 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAssetCreator.cpp @@ -382,7 +382,7 @@ namespace AZ return EndCommon(shaderAsset); } - void ShaderAssetCreator::Clone(const Data::AssetId& assetId, const ShaderAsset& sourceShaderAsset, [[maybe_unused]] const ShaderRootVariantAssets& rootVariantAssets) + void ShaderAssetCreator::Clone(const Data::AssetId& assetId, const ShaderAsset& sourceShaderAsset, [[maybe_unused]] const ShaderSupervariants& supervariants) { BeginCommon(assetId); @@ -392,38 +392,60 @@ namespace AZ m_asset->m_shaderOptionGroupLayout = sourceShaderAsset.m_shaderOptionGroupLayout; m_asset->m_buildTimestamp = sourceShaderAsset.m_buildTimestamp; - // copy root variant assets + // copy the perAPIShaderData for (auto& perAPIShaderData : sourceShaderAsset.m_perAPIShaderData) { - // find the matching ShaderVariantAsset - AZ::Data::Asset foundVariantAsset; - for (const auto& variantAsset : rootVariantAssets) - { - if (variantAsset.first == perAPIShaderData.m_APIType) - { - foundVariantAsset = variantAsset.second; - break; - } - } - - if (!foundVariantAsset) - { - ReportWarning("Failed to find variant asset for API [%d]", perAPIShaderData.m_APIType); - } - - m_asset->m_perAPIShaderData.push_back(perAPIShaderData); - if (m_asset->m_perAPIShaderData.back().m_supervariants.empty()) + if (perAPIShaderData.m_supervariants.empty()) { ReportWarning("Attempting to clone a shader asset that has no supervariants for API [%d]", perAPIShaderData.m_APIType); + continue; } - else + + if (perAPIShaderData.m_supervariants.size() != supervariants.size()) { - // currently we only support one supervariant when cloning - // [GFX TODO][ATOM-15740] Support multiple supervariants in ShaderAssetCreator::Clone - m_asset->m_perAPIShaderData.back().m_supervariants[0].m_rootShaderVariantAsset = foundVariantAsset; + ReportError("Incorrect number of supervariants provided to ShaderAssetCreator::Clone"); + return; + } + + m_asset->m_perAPIShaderData.push_back(perAPIShaderData); + + // set the supervariants for this API + for (auto& supervariant : m_asset->m_perAPIShaderData.back().m_supervariants) + { + // find the matching Supervariant by name from the incoming list + ShaderSupervariants::const_iterator itFoundSuperVariant = AZStd::find_if( + supervariants.begin(), + supervariants.end(), + [&supervariant](const ShaderSupervariant& shaderSupervariant) + { + return supervariant.m_name == shaderSupervariant.m_name; + }); + + if (itFoundSuperVariant == supervariants.end()) + { + ReportError("Failed to find supervariant [%s]", supervariant.m_name.GetCStr()); + return; + } + + // find the matching ShaderVariantAsset for this API + ShaderRootVariantAssets::const_iterator itFoundRootShaderVariantAsset = AZStd::find_if( + itFoundSuperVariant->m_rootVariantAssets.begin(), + itFoundSuperVariant->m_rootVariantAssets.end(), + [&perAPIShaderData](const ShaderRootVariantAssetPair& rootShaderVariantAsset) + { + return perAPIShaderData.m_APIType == rootShaderVariantAsset.first; + }); + + if (itFoundRootShaderVariantAsset == itFoundSuperVariant->m_rootVariantAssets.end()) + { + ReportWarning("Failed to find root shader variant asset for API [%d] Supervariant [%s]", perAPIShaderData.m_APIType, supervariant.m_name.GetCStr()); + } + else + { + supervariant.m_rootShaderVariantAsset = itFoundRootShaderVariantAsset->second; + } } } - } } // namespace RPI } // namespace AZ From 392d08e2f0272c3bbe62207124e6664fb4c77a4e Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Mon, 17 Jan 2022 17:09:30 -0800 Subject: [PATCH 215/272] Update Terrain renderer code to use the ProcessRegion API functions instead of the Get* functions Signed-off-by: amzn-sj --- .../TerrainDetailMaterialManager.cpp | 76 ++++++++++--------- .../TerrainFeatureProcessor.cpp | 33 ++++---- 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainDetailMaterialManager.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainDetailMaterialManager.cpp index 2bc9e42bff..1f43b476a1 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainDetailMaterialManager.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainDetailMaterialManager.cpp @@ -751,50 +751,56 @@ namespace Terrain pixels.resize((quadrantWorldArea.m_max.m_x - quadrantWorldArea.m_min.m_x) * (quadrantWorldArea.m_max.m_y - quadrantWorldArea.m_min.m_y)); uint32_t index = 0; - for (int yPos = quadrantWorldArea.m_min.m_y; yPos < quadrantWorldArea.m_max.m_y; ++yPos) + auto perPositionCallback = [this, &pixels, &index]( + [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, + [[maybe_unused]] bool terrainExists) { - for (int xPos = quadrantWorldArea.m_min.m_x; xPos < quadrantWorldArea.m_max.m_x; ++xPos) + // Store the top two surface weights in the texture with m_blend storing the relative weight. + bool isFirstMaterial = true; + float firstWeight = 0.0f; + AZ::Vector2 position(surfacePoint.m_position.GetX(), surfacePoint.m_position.GetY()); + for (const auto& surfaceTagWeight : surfacePoint.m_surfaceTags) { - AZ::Vector2 position = AZ::Vector2(xPos * DetailTextureScale, yPos * DetailTextureScale); - AzFramework::SurfaceData::SurfaceTagWeightList surfaceWeights; - AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::GetSurfaceWeightsFromVector2, position, surfaceWeights, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, nullptr); - - // Store the top two surface weights in the texture with m_blend storing the relative weight. - bool isFirstMaterial = true; - float firstWeight = 0.0f; - for (const auto& surfaceTagWeight : surfaceWeights) + if (surfaceTagWeight.m_weight > 0.0f) { - if (surfaceTagWeight.m_weight > 0.0f) + AZ::Crc32 surfaceType = surfaceTagWeight.m_surfaceType; + uint16_t materialId = GetDetailMaterialForSurfaceTypeAndPosition(surfaceType, position); + if (materialId != m_detailMaterials.NoFreeSlot && materialId < 255) { - AZ::Crc32 surfaceType = surfaceTagWeight.m_surfaceType; - uint16_t materialId = GetDetailMaterialForSurfaceTypeAndPosition(surfaceType, position); - if (materialId != m_detailMaterials.NoFreeSlot && materialId < 255) + if (isFirstMaterial) { - if (isFirstMaterial) - { - pixels.at(index).m_material1 = aznumeric_cast(materialId); - firstWeight = surfaceTagWeight.m_weight; - // m_blend only needs to be calculated is material 2 is found, otherwise the initial value of 0 is correct. - isFirstMaterial = false; - } - else - { - pixels.at(index).m_material2 = aznumeric_cast(materialId); - float totalWeight = firstWeight + surfaceTagWeight.m_weight; - float blendWeight = 1.0f - (firstWeight / totalWeight); - pixels.at(index).m_blend = aznumeric_cast(AZStd::round(blendWeight * 255.0f)); - break; - } + pixels.at(index).m_material1 = aznumeric_cast(materialId); + firstWeight = surfaceTagWeight.m_weight; + // m_blend only needs to be calculated is material 2 is found, otherwise the initial value of 0 is correct. + isFirstMaterial = false; + } + else + { + pixels.at(index).m_material2 = aznumeric_cast(materialId); + float totalWeight = firstWeight + surfaceTagWeight.m_weight; + float blendWeight = 1.0f - (firstWeight / totalWeight); + pixels.at(index).m_blend = aznumeric_cast(AZStd::round(blendWeight * 255.0f)); + break; } } - else - { - break; // since the list is ordered, no other materials are in the list with positive weights. - } } - ++index; + else + { + break; // since the list is ordered, no other materials are in the list with positive weights. + } } - } + ++index; + }; + + AZ::Vector3 worldMin(quadrantWorldArea.m_min.m_x * DetailTextureScale, quadrantWorldArea.m_min.m_y * DetailTextureScale, 0.0f); + AZ::Vector3 worldMax(quadrantWorldArea.m_max.m_x * DetailTextureScale, quadrantWorldArea.m_max.m_y * DetailTextureScale, 0.0f); + AZ::Vector2 stepSize(DetailTextureScale); + AZ::Aabb region; + region.Set(worldMin, worldMax); + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromRegion, + region, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); const int32_t left = quadrantTextureArea.m_min.m_x; const int32_t top = quadrantTextureArea.m_min.m_y; diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp index 351c34308a..ebc8a16fcb 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -226,25 +226,26 @@ namespace Terrain auto& surfaceDataContext = SurfaceData::SurfaceDataSystemRequestBus::GetOrCreateContext(false); typename SurfaceData::SurfaceDataSystemRequestBus::Context::DispatchLockGuard scopeLock(surfaceDataContext.m_contextMutex); - for (int32_t y = yStart; y < yEnd; y++) + auto perPositionCallback = [this, &pixels] + ([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, + const AzFramework::SurfaceData::SurfacePoint& surfacePoint, + [[maybe_unused]] bool terrainExists) { - for (int32_t x = xStart; x < xEnd; x++) - { - bool terrainExists = true; - float terrainHeight = 0.0f; - float xPos = x * m_sampleSpacing; - float yPos = y * m_sampleSpacing; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - terrainHeight, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, - xPos, yPos, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, &terrainExists); + const float clampedHeight = AZ::GetClamp((surfacePoint.m_position.GetZ() - m_terrainBounds.GetMin().GetZ()) / m_terrainBounds.GetExtents().GetZ(), 0.0f, 1.0f); + const float expandedHeight = AZStd::roundf(clampedHeight * AZStd::numeric_limits::max()); + const uint16_t uint16Height = aznumeric_cast(expandedHeight); - const float clampedHeight = AZ::GetClamp((terrainHeight - m_terrainBounds.GetMin().GetZ()) / m_terrainBounds.GetExtents().GetZ(), 0.0f, 1.0f); - const float expandedHeight = AZStd::roundf(clampedHeight * AZStd::numeric_limits::max()); - const uint16_t uint16Height = aznumeric_cast(expandedHeight); + pixels.push_back(uint16Height); + }; - pixels.push_back(uint16Height); - } - } + AZ::Vector2 stepSize(m_sampleSpacing); + AZ::Vector3 maxBound( + m_dirtyRegion.GetMax().GetX() + m_sampleSpacing, m_dirtyRegion.GetMax().GetY() + m_sampleSpacing, 0.0f); + AZ::Aabb region; + region.Set(m_dirtyRegion.GetMin(), maxBound); + AzFramework::Terrain::TerrainDataRequestBus::Broadcast( + &AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, + region, stepSize, perPositionCallback,AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); } if (m_heightmapImage) From c1bbe3806db1cb4dea1eea710a1c9fbd8ef2bb67 Mon Sep 17 00:00:00 2001 From: Ignacio Martinez <82394219+AMZN-Igarri@users.noreply.github.com> Date: Tue, 18 Jan 2022 13:29:06 +0100 Subject: [PATCH 216/272] Asset Browser Search Entries Highlight (#6133) * Adding hilight to search entries Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Delegate Cleanup Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * delegate cleanup Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * General cleanup Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * reformatting file Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Updated Comments Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Abstracted richText functions Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Extracting highlighting behavior Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Added highlighter to the entity outliner Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Addressed Code Review Comments Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Switched to static functions Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * changed variable name Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Removed unused variable Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Apply changes to the Entity Outliner Model Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Removed duplicated line Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../AzAssetBrowser/AzAssetBrowserWindow.cpp | 4 ++ .../UI/Outliner/OutlinerListModel.cpp | 22 ++------ .../AssetBrowser/AssetBrowserFilterModel.cpp | 5 ++ .../AssetBrowser/AssetBrowserFilterModel.h | 4 +- .../AssetBrowser/AssetBrowserModel.cpp | 16 ++++++ .../AssetBrowser/AssetBrowserModel.h | 9 ++- .../AssetBrowser/Search/Filter.cpp | 5 ++ .../AssetBrowser/Search/Filter.h | 1 + .../Views/AssetBrowserTableView.cpp | 1 + .../AssetBrowser/Views/EntryDelegate.cpp | 27 +++++++-- .../AssetBrowser/Views/EntryDelegate.h | 3 +- .../Editor/RichTextHighlighter.cpp | 55 +++++++++++++++++++ .../Editor/RichTextHighlighter.h | 36 ++++++++++++ .../UI/Outliner/EntityOutlinerListModel.cpp | 30 +--------- .../aztoolsframework_files.cmake | 2 + 15 files changed, 167 insertions(+), 53 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp index bcaaa02b67..a7faea36f6 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp @@ -17,6 +17,7 @@ #include #include #include +#include // AzQtComponents #include @@ -83,6 +84,9 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent) m_ui->m_assetBrowserTableViewWidget->setVisible(false); m_ui->m_toggleDisplayViewBtn->setVisible(false); m_ui->m_searchWidget->SetFilterInputInterval(AZStd::chrono::milliseconds(250)); + + m_assetBrowserModel->SetFilterModel(m_filterModel.data()); + if (ed_useNewAssetBrowserTableView) { m_ui->m_toggleDisplayViewBtn->setVisible(true); diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp index 08d79adcf5..1c361b050d 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include "OutlinerDisplayOptionsMenu.h" #include "OutlinerSortFilterProxyModel.hxx" @@ -252,17 +253,7 @@ QVariant OutlinerListModel::dataForName(const QModelIndex& index, int role) cons if (s_paintingName && !m_filterString.empty()) { // highlight characters in filter - int highlightTextIndex = 0; - do - { - highlightTextIndex = label.lastIndexOf(QString(m_filterString.c_str()), highlightTextIndex - 1, Qt::CaseInsensitive); - if (highlightTextIndex >= 0) - { - const QString BACKGROUND_COLOR{ "#707070" }; - label.insert(static_cast(highlightTextIndex + m_filterString.length()), ""); - label.insert(highlightTextIndex, ""); - } - } while(highlightTextIndex > 0); + label = AzToolsFramework::RichTextHighlighter::HighlightText(label, m_filterString.c_str()); } return label; } @@ -2609,16 +2600,11 @@ void OutlinerItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optionV4.widget->style()->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); // Now we setup a Text Document so it can draw the rich text - QTextDocument textDoc; - textDoc.setDefaultFont(optionV4.font); - textDoc.setDefaultStyleSheet("body {color: white}"); - textDoc.setHtml("" + entityNameRichText + ""); int verticalOffset = GetEntityNameVerticalOffset(entityId); painter->translate(textRect.topLeft() + QPoint(0, verticalOffset)); - textDoc.setTextWidth(textRect.width()); - textDoc.drawContents(painter, QRectF(0, 0, textRect.width(), textRect.height())); - painter->restore(); + AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect); + OutlinerListModel::s_paintingName = false; } else diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp index c6772ea2d7..21229e5570 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp @@ -68,6 +68,11 @@ namespace AzToolsFramework } } + QSharedPointer AssetBrowserFilterModel::GetStringFilter() const + { + return m_stringFilter; + } + bool AssetBrowserFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { //get the source idx, if invalid early out diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h index 5d3ad0e1b0..cafe694ad6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h @@ -48,7 +48,7 @@ namespace AzToolsFramework // AssetBrowserComponentNotificationBus ////////////////////////////////////////////////////////////////////////// void OnAssetBrowserComponentReady() override; - + QSharedPointer GetStringFilter() const; Q_SIGNALS: void filterChanged(); ////////////////////////////////////////////////////////////////////////// @@ -70,7 +70,7 @@ namespace AzToolsFramework //Asset source name match filter FilterConstType m_filter; AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...' - QWeakPointer m_stringFilter; + QSharedPointer m_stringFilter; QWeakPointer m_assetTypeFilter; QCollator m_collator; // cache the collator as its somewhat expensive to constantly create and destroy one. AZ_POP_DISABLE_WARNING diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.cpp index f0e1520aab..fd05543097 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 'QRegularExpression::d': class 'QExplicitlySharedDataPointer' needs to have dll-interface to be used by clients of class 'QRegularExpression' @@ -268,6 +269,21 @@ namespace AzToolsFramework m_rootEntry = rootEntry; } + AssetBrowserFilterModel* AssetBrowserModel::GetFilterModel() + { + return m_filterModel; + } + + const AssetBrowserFilterModel* AssetBrowserModel::GetFilterModel() const + { + return m_filterModel; + } + + void AssetBrowser::AssetBrowserModel::SetFilterModel(AssetBrowserFilterModel* filterModel) + { + m_filterModel = filterModel; + } + QModelIndex AssetBrowserModel::parent(const QModelIndex& child) const { if (!child.isValid()) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.h index c46b73417c..2905844a23 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserModel.h @@ -35,6 +35,7 @@ namespace AzToolsFramework class AssetBrowserEntry; class RootAssetBrowserEntry; class AssetEntryChangeset; + class AssetBrowserFilterModel; class AssetBrowserModel : public QAbstractItemModel @@ -75,7 +76,7 @@ namespace AzToolsFramework void EndAddEntry(AssetBrowserEntry* parent) override; void BeginRemoveEntry(AssetBrowserEntry* entry) override; void EndRemoveEntry() override; - + ////////////////////////////////////////////////////////////////////////// // TickBus ////////////////////////////////////////////////////////////////////////// @@ -84,10 +85,16 @@ namespace AzToolsFramework AZStd::shared_ptr GetRootEntry() const; void SetRootEntry(AZStd::shared_ptr rootEntry); + AssetBrowserFilterModel* GetFilterModel(); + const AssetBrowserFilterModel* GetFilterModel() const; + void SetFilterModel(AssetBrowserFilterModel* filterModel); + static void SourceIndexesToAssetIds(const QModelIndexList& indexes, AZStd::vector& assetIds); static void SourceIndexesToAssetDatabaseEntries(const QModelIndexList& indexes, AZStd::vector& entries); private: + //Non owning pointer + AssetBrowserFilterModel* m_filterModel = nullptr; AZStd::shared_ptr m_rootEntry; bool m_loaded; bool m_addingEntry; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp index d617638632..4ec26d4c3d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp @@ -229,6 +229,11 @@ namespace AzToolsFramework Q_EMIT updatedSignal(); } + QString StringFilter::GetFilterString() const + { + return m_filterString; + } + QString StringFilter::GetNameInternal() const { return m_filterString; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h index 94f47e0599..1d93d4d0cf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h @@ -106,6 +106,7 @@ namespace AzToolsFramework ~StringFilter() override = default; void SetFilterString(const QString& filterString); + QString GetFilterString() const; protected: QString GetNameInternal() const override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp index cfcac579ff..a913009da0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp @@ -66,6 +66,7 @@ namespace AzToolsFramework m_tableModel = qobject_cast(model); AZ_Assert(m_tableModel, "Expecting AssetBrowserTableModel"); m_sourceFilterModel = qobject_cast(m_tableModel->sourceModel()); + m_delegate->Init(); AzQtComponents::TableView::setModel(model); connect(m_tableModel, &AssetBrowserTableModel::layoutChanged, this, &AssetBrowserTableView::layoutChangedSlot); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp index 8b58791e68..8e69d5f788 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include #include +#include #include +#include + AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // 4251: class 'QScopedPointer' needs to have dll-interface to be used by clients of class 'QBrush' // 4800: 'uint': forcing value to bool 'true' or 'false' (performance warning) #include @@ -160,13 +164,20 @@ namespace AzToolsFramework LoadBranchPixMaps(); } + void SearchEntryDelegate::Init() + { + AssetBrowserModel* assetBrowserModel; + AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel); + AZ_Assert(assetBrowserModel, "Failed to get filebrowser model"); + m_assetBrowserFilerModel = assetBrowserModel->GetFilterModel(); + } + void SearchEntryDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto data = index.data(AssetBrowserModel::Roles::EntryRole); if (data.canConvert()) { bool isEnabled = (option.state & QStyle::State_Enabled) != 0; - bool isSelected = (option.state & QStyle::State_Selected) != 0; QStyle* style = option.widget ? option.widget->style() : QApplication::style(); @@ -265,13 +276,21 @@ namespace AzToolsFramework remainingRect.adjust(thumbX, 0, 0, 0); // bump it to the right by the size of the thumbnail remainingRect.adjust(EntrySpacingLeftPixels, 0, 0, 0); // bump it to the right by the spacing. } + QString displayString = index.column() == aznumeric_cast(AssetBrowserEntry::Column::Name) ? qvariant_cast(entry->data(aznumeric_cast(AssetBrowserEntry::Column::Name))) : qvariant_cast(entry->data(aznumeric_cast(AssetBrowserEntry::Column::Path))); - style->drawItemText( - painter, remainingRect, option.displayAlignment, actualPalette, isEnabled, displayString, - isSelected ? QPalette::HighlightedText : QPalette::Text); + QStyleOptionViewItem optionV4{ option }; + initStyleOption(&optionV4, index); + optionV4.state &= ~(QStyle::State_HasFocus | QStyle::State_Selected); + + if (m_assetBrowserFilerModel && m_assetBrowserFilerModel->GetStringFilter() + && !m_assetBrowserFilerModel->GetStringFilter()->GetFilterString().isEmpty()) + { + displayString = RichTextHighlighter::HighlightText(displayString, m_assetBrowserFilerModel->GetStringFilter()->GetFilterString()); + } + RichTextHighlighter::PaintHighlightedRichText(displayString, painter, optionV4, remainingRect); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h index ac68c19248..7c7d919f2d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h @@ -70,7 +70,7 @@ namespace AzToolsFramework Q_OBJECT public: explicit SearchEntryDelegate(QWidget* parent = nullptr); - + void Init(); void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; private: @@ -78,6 +78,7 @@ namespace AzToolsFramework void DrawBranchPixMap(EntryBranchType branchType, QPainter* painter, const QPoint& point, const QSize& size) const; private: + AssetBrowserFilterModel* m_assetBrowserFilerModel; QMap m_branchIcons; }; } // namespace AssetBrowser diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp new file mode 100644 index 0000000000..8b28298c3d --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include "RichTextHighlighter.h" + +namespace AzToolsFramework +{ + + QString RichTextHighlighter::HighlightText(const QString& displayString, const QString& matchingSubstring) + { + QString highlightedString = displayString; + int highlightTextIndex = 0; + do + { + highlightTextIndex = highlightedString.lastIndexOf(matchingSubstring, highlightTextIndex - 1, Qt::CaseInsensitive); + if (highlightTextIndex >= 0) + { + const QString backgroundColor{ "#707070" }; + highlightedString.insert(static_cast(highlightTextIndex + matchingSubstring.length()), ""); + highlightedString.insert(highlightTextIndex, ""); + } + } while (highlightTextIndex > 0); + + return highlightedString; + } + + void RichTextHighlighter::PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + // Now we setup a Text Document so it can draw the rich text + QTextDocument textDoc; + textDoc.setDefaultFont(option.font); + if (option.state & QStyle::State_Enabled) + { + textDoc.setDefaultStyleSheet("body {color: white}"); + } + else + { + textDoc.setDefaultStyleSheet("body {color: #7C7C7C}"); + } + textDoc.setHtml("" + highlightedString + ""); + painter->translate(availableRect.topLeft()); + textDoc.setTextWidth(availableRect.width()); + textDoc.drawContents(painter, QRectF(0, 0, availableRect.width(), availableRect.height())); + + painter->restore(); + } +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h new file mode 100644 index 0000000000..b5c1859497 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +AZ_PUSH_DISABLE_WARNING(4251 4800,"-Wunknown-warning-option") // 4251: class 'QScopedPointer' needs to have dll-interface to be used + // by clients of class 'QBrush' 4800: 'uint': forcing value to bool 'true' or 'false' (performance warning) +#include +AZ_POP_DISABLE_WARNING + +namespace AzToolsFramework +{ + //! @class RichTextHighlighter + //! @brief Highlights a given string given a matching substring. + class RichTextHighlighter + { + public: + AZ_CLASS_ALLOCATOR(RichTextHighlighter, AZ::SystemAllocator, 0); + RichTextHighlighter() = delete; + + static QString HighlightText(const QString& displayString, const QString& matchingSubstring); + static void PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect); + + }; +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp index 056f16c52f..e0060e2b42 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp @@ -66,6 +66,7 @@ #include #include #include +#include //////////////////////////////////////////////////////////////////////////// // EntityOutlinerListModel @@ -259,17 +260,7 @@ namespace AzToolsFramework if (s_paintingName && !m_filterString.empty()) { // highlight characters in filter - int highlightTextIndex = 0; - do - { - highlightTextIndex = label.lastIndexOf(QString(m_filterString.c_str()), highlightTextIndex - 1, Qt::CaseInsensitive); - if (highlightTextIndex >= 0) - { - const QString BACKGROUND_COLOR{ "#707070" }; - label.insert(highlightTextIndex + static_cast(m_filterString.length()), ""); - label.insert(highlightTextIndex, ""); - } - } while(highlightTextIndex > 0); + label = AzToolsFramework::RichTextHighlighter::HighlightText(label, m_filterString.c_str()); } return label; } @@ -2375,23 +2366,8 @@ namespace AzToolsFramework optionV4.text.clear(); optionV4.widget->style()->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); - // Now we setup a Text Document so it can draw the rich text - QTextDocument textDoc; - textDoc.setDefaultFont(optionV4.font); - if (option.state & QStyle::State_Enabled) - { - textDoc.setDefaultStyleSheet("body {color: white}"); - } - else - { - textDoc.setDefaultStyleSheet("body {color: #7C7C7C}"); - } - textDoc.setHtml("" + entityNameRichText + ""); - painter->translate(textRect.topLeft()); - textDoc.setTextWidth(textRect.width()); - textDoc.drawContents(painter, QRectF(0, 0, textRect.width(), textRect.height())); + AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect); - painter->restore(); EntityOutlinerListModel::s_paintingName = false; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 05c07afecd..0d7bf05211 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -123,6 +123,8 @@ set(FILES ContainerEntity/ContainerEntitySystemComponent.h Editor/EditorContextMenuBus.h Editor/EditorSettingsAPIBus.h + Editor/RichTextHighlighter.h + Editor/RichTextHighlighter.cpp Entity/EditorEntityStartStatus.h Entity/EditorEntityAPIBus.h Entity/EditorEntityContextComponent.cpp From e166479bb7c77e0d0ebc391ff9bc9d2835ebb5eb Mon Sep 17 00:00:00 2001 From: Ignacio Martinez <82394219+AMZN-Igarri@users.noreply.github.com> Date: Tue, 18 Jan 2022 16:47:27 +0100 Subject: [PATCH 217/272] Fixed Camera angle on switch levels (#6954) Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- Code/Editor/EditorViewportWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index e9a57dba4f..a8180bcace 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -582,11 +582,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) case eNotify_OnCloseScene: m_renderViewport->SetScene(nullptr); - SetDefaultCamera(); break; case eNotify_OnEndSceneOpen: UpdateScene(); + SetDefaultCamera(); break; case eNotify_OnBeginNewScene: From 338eecd9e687815a56bca750a3f830e22a944976 Mon Sep 17 00:00:00 2001 From: moraaar Date: Tue, 18 Jan 2022 16:00:28 +0000 Subject: [PATCH 218/272] Blast memory allocator must allocate with 16 byte aligment (#6968) From Blast allocator documentation "Allocates size bytes of memory, which must be 16-byte aligned." https://gameworksdocs.nvidia.com/Blast/1.1/api_docs/files/class_nv_1_1_blast_1_1_allocator_callback.html Fixes #5162 Signed-off-by: moraaar moraaar@amazon.com --- Gems/Blast/Code/Source/Components/BlastSystemComponent.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Gems/Blast/Code/Source/Components/BlastSystemComponent.h b/Gems/Blast/Code/Source/Components/BlastSystemComponent.h index 8f6c200870..a3d4b200bc 100644 --- a/Gems/Blast/Code/Source/Components/BlastSystemComponent.h +++ b/Gems/Blast/Code/Source/Components/BlastSystemComponent.h @@ -100,11 +100,14 @@ namespace Blast class AZBlastAllocatorCallback : public Nv::Blast::AllocatorCallback { public: + // Blast requires 16-byte alignment + static const size_t alignment = 16; + void* allocate( size_t size, const char* typeName, [[maybe_unused]] const char* filename, [[maybe_unused]] int line) override { - return azmalloc_4(size, 0, AZ::SystemAllocator, typeName); + return azmalloc_4(size, alignment, AZ::SystemAllocator, typeName); } void deallocate(void* ptr) override From 27d256679ac7fb2d820afb0be5f678e11ac6dee3 Mon Sep 17 00:00:00 2001 From: Nicholas Lawson <70027408+lawsonamzn@users.noreply.github.com> Date: Tue, 18 Jan 2022 08:16:25 -0800 Subject: [PATCH 219/272] Update the package of Pybind11 that o3de points at to be the latest version (#6898) Signed-off-by: lawsonamzn <70027408+lawsonamzn@users.noreply.github.com> --- cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake | 2 +- cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake | 2 +- cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index f1e8fdc950..d174f935e2 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -11,7 +11,7 @@ ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) -ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b) +ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev3-multiplatform TARGETS pybind11 PACKAGE_HASH dccb5546607b8b31cd207033aaf24ab044ce6e188a9f12411236a010f9e0c4ff) ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2) ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418) ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665) diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index 575a2dd70e..95f7c89930 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -11,7 +11,7 @@ ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) -ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b) +ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev3-multiplatform TARGETS pybind11 PACKAGE_HASH dccb5546607b8b31cd207033aaf24ab044ce6e188a9f12411236a010f9e0c4ff) ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2) ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418) ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665) diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 7fd07927cc..1f7cb8d28f 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -11,7 +11,7 @@ ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf) ly_associate_package(PACKAGE_NAME RapidJSON-1.1.0-rev1-multiplatform TARGETS RapidJSON PACKAGE_HASH 2f5e26ecf86c3b7a262753e7da69ac59928e78e9534361f3d00c1ad5879e4023) ly_associate_package(PACKAGE_NAME RapidXML-1.13-rev1-multiplatform TARGETS RapidXML PACKAGE_HASH 4b7b5651e47cfd019b6b295cc17bb147b65e53073eaab4a0c0d20a37ab74a246) -ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev2-multiplatform TARGETS pybind11 PACKAGE_HASH d8012f907b6c54ac990b899a0788280857e7c93a9595405a28114b48c354eb1b) +ly_associate_package(PACKAGE_NAME pybind11-2.4.3-rev3-multiplatform TARGETS pybind11 PACKAGE_HASH dccb5546607b8b31cd207033aaf24ab044ce6e188a9f12411236a010f9e0c4ff) ly_associate_package(PACKAGE_NAME cityhash-1.1-multiplatform TARGETS cityhash PACKAGE_HASH 0ace9e6f0b2438c5837510032d2d4109125845c0efd7d807f4561ec905512dd2) ly_associate_package(PACKAGE_NAME expat-2.1.0-multiplatform TARGETS expat PACKAGE_HASH 452256acd1fd699cef24162575b3524fccfb712f5321c83f1df1ce878de5b418) ly_associate_package(PACKAGE_NAME zstd-1.35-multiplatform TARGETS zstd PACKAGE_HASH 45d466c435f1095898578eedde85acf1fd27190e7ea99aeaa9acfd2f09e12665) From 74623bb1d7c56f5a91ccaa40b8b1de1538aaa462 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 18 Jan 2022 10:21:54 -0600 Subject: [PATCH 220/272] Removed some more unused Editor code and images Signed-off-by: Chris Galvan --- .../PropertyGenericCtrl.cpp | 1 - Code/Editor/CrtDebug.cpp | 170 ------- Code/Editor/CryEdit.cpp | 16 - Code/Editor/CryEdit.h | 1 - Code/Editor/CryEditDoc.cpp | 26 +- Code/Editor/CryEditDoc.h | 3 - Code/Editor/CryEditLiveCreate.rc | 213 -------- Code/Editor/DimensionsDialog.cpp | 71 --- Code/Editor/DimensionsDialog.h | 47 -- Code/Editor/DimensionsDialog.ui | 120 ----- Code/Editor/GameEngine.cpp | 2 - Code/Editor/MainWindow.qrc | 30 -- Code/Editor/NewLevelDialog.cpp | 3 - Code/Editor/NewTerrainDialog.cpp | 168 ------- Code/Editor/NewTerrainDialog.h | 71 --- Code/Editor/NewTerrainDialog.ui | 112 ----- Code/Editor/PakManagerDlg.qrc | 6 - Code/Editor/PakManagerDlg.ui | 202 -------- Code/Editor/SelectEAXPresetDlg.cpp | 67 --- Code/Editor/SelectEAXPresetDlg.h | 43 -- Code/Editor/SelectEAXPresetDlg.ui | 67 --- Code/Editor/SurfaceTypeValidator.cpp | 23 - Code/Editor/SurfaceTypeValidator.h | 24 - Code/Editor/UndoViewPosition.cpp | 67 --- Code/Editor/UndoViewPosition.h | 36 -- Code/Editor/UndoViewRotation.cpp | 78 --- Code/Editor/UndoViewRotation.h | 39 -- Code/Editor/UserMessageDefines.h | 60 --- Code/Editor/ViewPane.cpp | 1 - Code/Editor/WipFeatureManager.cpp | 454 ------------------ Code/Editor/WipFeatureManager.h | 162 ------- Code/Editor/WipFeaturesDlg.cpp | 239 --------- Code/Editor/WipFeaturesDlg.h | 58 --- Code/Editor/WipFeaturesDlg.qrc | 5 - Code/Editor/WipFeaturesDlg.ui | 184 ------- Code/Editor/arhitype_tree_00.png | 3 - Code/Editor/arhitype_tree_01.png | 3 - Code/Editor/arhitype_tree_02.png | 3 - Code/Editor/arhitype_tree_03.png | 3 - Code/Editor/bmp00005_00.png | 3 - Code/Editor/bmp00005_01.png | 3 - Code/Editor/bmp00005_02.png | 3 - Code/Editor/bmp00005_03.png | 3 - Code/Editor/bmp00005_04.png | 3 - Code/Editor/bmp00005_05.png | 3 - Code/Editor/bmp00005_06.png | 3 - Code/Editor/bmp00005_07.png | 3 - Code/Editor/bmp00005_08.png | 3 - Code/Editor/bmp00005_09.png | 3 - Code/Editor/bmp00006_00.png | 3 - Code/Editor/bmp00006_01.png | 3 - Code/Editor/bmp00006_02.png | 3 - Code/Editor/bmp00006_03.png | 3 - Code/Editor/bmp00006_04.png | 3 - Code/Editor/bmp00006_05.png | 3 - Code/Editor/bmp00006_06.png | 3 - Code/Editor/bmp00006_07.png | 3 - Code/Editor/editor_lib_files.cmake | 20 - Code/Editor/particles_tree_00.png | 3 - Code/Editor/particles_tree_01.png | 3 - Code/Editor/particles_tree_02.png | 3 - Code/Editor/particles_tree_03.png | 3 - Code/Editor/particles_tree_04.png | 3 - Code/Editor/particles_tree_05.png | 3 - Code/Editor/particles_tree_06.png | 3 - Code/Editor/particles_tree_07.png | 3 - 66 files changed, 1 insertion(+), 2978 deletions(-) delete mode 100644 Code/Editor/CrtDebug.cpp delete mode 100644 Code/Editor/CryEditLiveCreate.rc delete mode 100644 Code/Editor/DimensionsDialog.cpp delete mode 100644 Code/Editor/DimensionsDialog.h delete mode 100644 Code/Editor/DimensionsDialog.ui delete mode 100644 Code/Editor/NewTerrainDialog.cpp delete mode 100644 Code/Editor/NewTerrainDialog.h delete mode 100644 Code/Editor/NewTerrainDialog.ui delete mode 100644 Code/Editor/PakManagerDlg.qrc delete mode 100644 Code/Editor/PakManagerDlg.ui delete mode 100644 Code/Editor/SelectEAXPresetDlg.cpp delete mode 100644 Code/Editor/SelectEAXPresetDlg.h delete mode 100644 Code/Editor/SelectEAXPresetDlg.ui delete mode 100644 Code/Editor/SurfaceTypeValidator.cpp delete mode 100644 Code/Editor/SurfaceTypeValidator.h delete mode 100644 Code/Editor/UndoViewPosition.cpp delete mode 100644 Code/Editor/UndoViewPosition.h delete mode 100644 Code/Editor/UndoViewRotation.cpp delete mode 100644 Code/Editor/UndoViewRotation.h delete mode 100644 Code/Editor/UserMessageDefines.h delete mode 100644 Code/Editor/WipFeatureManager.cpp delete mode 100644 Code/Editor/WipFeatureManager.h delete mode 100644 Code/Editor/WipFeaturesDlg.cpp delete mode 100644 Code/Editor/WipFeaturesDlg.h delete mode 100644 Code/Editor/WipFeaturesDlg.qrc delete mode 100644 Code/Editor/WipFeaturesDlg.ui delete mode 100644 Code/Editor/arhitype_tree_00.png delete mode 100644 Code/Editor/arhitype_tree_01.png delete mode 100644 Code/Editor/arhitype_tree_02.png delete mode 100644 Code/Editor/arhitype_tree_03.png delete mode 100644 Code/Editor/bmp00005_00.png delete mode 100644 Code/Editor/bmp00005_01.png delete mode 100644 Code/Editor/bmp00005_02.png delete mode 100644 Code/Editor/bmp00005_03.png delete mode 100644 Code/Editor/bmp00005_04.png delete mode 100644 Code/Editor/bmp00005_05.png delete mode 100644 Code/Editor/bmp00005_06.png delete mode 100644 Code/Editor/bmp00005_07.png delete mode 100644 Code/Editor/bmp00005_08.png delete mode 100644 Code/Editor/bmp00005_09.png delete mode 100644 Code/Editor/bmp00006_00.png delete mode 100644 Code/Editor/bmp00006_01.png delete mode 100644 Code/Editor/bmp00006_02.png delete mode 100644 Code/Editor/bmp00006_03.png delete mode 100644 Code/Editor/bmp00006_04.png delete mode 100644 Code/Editor/bmp00006_05.png delete mode 100644 Code/Editor/bmp00006_06.png delete mode 100644 Code/Editor/bmp00006_07.png delete mode 100644 Code/Editor/particles_tree_00.png delete mode 100644 Code/Editor/particles_tree_01.png delete mode 100644 Code/Editor/particles_tree_02.png delete mode 100644 Code/Editor/particles_tree_03.png delete mode 100644 Code/Editor/particles_tree_04.png delete mode 100644 Code/Editor/particles_tree_05.png delete mode 100644 Code/Editor/particles_tree_06.png delete mode 100644 Code/Editor/particles_tree_07.png diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp index 8ff83dd894..9609fb5014 100644 --- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp +++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp @@ -24,7 +24,6 @@ // Editor #include "SelectLightAnimationDialog.h" #include "SelectSequenceDialog.h" -#include "SelectEAXPresetDlg.h" #include "QtViewPaneManager.h" AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/CrtDebug.cpp b/Code/Editor/CrtDebug.cpp deleted file mode 100644 index f9335373da..0000000000 --- a/Code/Editor/CrtDebug.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -//#ifdef _CRTDBG_MAP_ALLOC -#ifdef CRTDBG_MAP_ALLOC -#pragma pack (push,1) -#define nNoMansLandSize 4 -typedef struct MyCrtMemBlockHeader -{ - struct MyCrtMemBlockHeader* pBlockHeaderNext; - struct MyCrtMemBlockHeader* pBlockHeaderPrev; - char* szFileName; - int nLine; - size_t nDataSize; - int nBlockUse; - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} MyCrtMemBlockHeader; -#pragma pack (pop) - -#define pbData(pblock) ((unsigned char*)((MyCrtMemBlockHeader*)pblock + 1)) -#define pHdr(pbData) (((MyCrtMemBlockHeader*)pbData) - 1) - - -void crtdebug(const char* s, ...) -{ - char str[32768]; - va_list arg_ptr; - va_start(arg_ptr, s); - vsprintf(str, s, arg_ptr); - va_end(arg_ptr); - - FILE* l = nullptr; - azfopen(&l, "crtdump.txt", "a+t"); - if (l) - { - fprintf(l, "%s", str); - fclose(l); - } -} - -int crtAllocHook(int nAllocType, void* pvData, - size_t nSize, int nBlockUse, long lRequest, - const unsigned char* szFileName, int nLine) -{ - if (nBlockUse == _CRT_BLOCK) - { - return TRUE; - } - - static int total_cnt = 0; - static int total_mem = 0; - if (nAllocType == _HOOK_ALLOC) - { - //total_mem += nSize; - //total_cnt++; - //_CrtMemState mem_state; - //_CrtMemCheckpoint( &mem_state ); - //total_cnt = mem_state.lCounts[_NORMAL_BLOCK]; - //total_mem = mem_state.lTotalCount; - if ((total_cnt & 0xF) == 0) - { - //_CrtCheckMemory(); - } - - total_cnt++; - total_mem += nSize; - - //crtdebug( " Alloc %d,size=%d,in: %s %d (total size=%d,num=%d)\n",lRequest,nSize,szFileName,nLine,total_mem,total_cnt ); - crtdebug("Size=%d, [Total=%d,N=%d] [%s:%d]\n", nSize, total_mem, total_cnt, szFileName, nLine); - } - else if (nAllocType == _HOOK_FREE) - { - MyCrtMemBlockHeader* pHead; - pHead = pHdr(pvData); - - total_cnt--; - total_mem -= pHead->nDataSize; - - crtdebug("Size=%d, [Total=%d,N=%d] [%s:%d]\n", pHead->nDataSize, total_mem, total_cnt, pHead->szFileName, pHead->nLine); - //crtdebug( " Free size=%d,in: %s %d (total size=%d,num=%d)\n",pHead->nDataSize,pHead->szFileName,pHead->nLine,total_mem,total_cnt ); - //total_mem -= nSize; - //total_cnt--; - } - return TRUE; -} - -int crtReportHook(int nRptType, char* szMsg, int* retVal) -{ - static int gl_num_asserts = 0; - if (gl_num_asserts != 0) - { - return TRUE; - } - gl_num_asserts++; - switch (nRptType) - { - case _CRT_WARN: - crtdebug(" %s\n", szMsg); - break; - case _CRT_ERROR: - crtdebug(" %s\n", szMsg); - break; - case _CRT_ASSERT: - crtdebug(" %s\n", szMsg); - break; - } - gl_num_asserts--; - return TRUE; -} - -void InitCrt() -{ - FILE* l = nullptr; - azfopen(&l, "crtdump.txt", "w"); - if (l) - { - fclose(l); - } - - //_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG ); - //_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); - //_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG ); - - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_WNDW); - - //_CrtSetDbgFlag( _CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_CHECK_CRT_DF|_CRTDBG_LEAK_CHECK_DF|_CRTDBG_DELAY_FREE_MEM_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ); - //_CrtSetDbgFlag( _CRTDBG_CHECK_CRT_DF|_CRTDBG_LEAK_CHECK_DF/*|_CRTDBG_DELAY_FREE_MEM_DF*/ | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) ); - int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flags &= ~_CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_CRT_DF; - - _CrtSetDbgFlag(flags); - - _CrtSetAllocHook (crtAllocHook); - _CrtSetReportHook(crtReportHook); -} - -void DoneCrt() -{ - //_CrtCheckMemory(); - //_CrtDumpMemoryLeaks(); -} - -// Autoinit CRT. -//struct __autoinit_crt { __autoinit_crt() { InitCrt(); }; ~__autoinit_crt() { DoneCrt(); } } __autoinit_crt_var; -#endif - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 1c4e22b99e..3beaf4d438 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -124,9 +124,6 @@ AZ_POP_DISABLE_WARNING #include "ScopedVariableSetter.h" #include "Util/3DConnexionDriver.h" - -#include "DimensionsDialog.h" - #include "Util/AutoDirectoryRestoreFileDialog.h" #include "Util/EditorAutoLevelLoadTest.h" #include "AboutDialog.h" @@ -1806,12 +1803,6 @@ bool CCryEditApp::InitInstance() InitLevel(cmdInfo); }); -#ifdef USE_WIP_FEATURES_MANAGER - // load the WIP features file - CWipFeatureManager::Instance()->EnableManager(!cmdInfo.m_bDeveloperMode); - CWipFeatureManager::Init(); -#endif - if (!m_bConsoleMode && !m_bPreviewMode) { GetIEditor()->UpdateViews(); @@ -2142,13 +2133,6 @@ int CCryEditApp::ExitInstance(int exitCode) } qobject_cast(qApp)->UnloadSettings(); - #ifdef USE_WIP_FEATURES_MANAGER - // - // close wip features manager - // - CWipFeatureManager::Shutdown(); - #endif - if (IsInRegularEditorMode()) { if (GetIEditor()) diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h index 97fcde8f34..48f362003c 100644 --- a/Code/Editor/CryEdit.h +++ b/Code/Editor/CryEdit.h @@ -14,7 +14,6 @@ #if !defined(Q_MOC_RUN) #include #include -#include "WipFeatureManager.h" #include "CryEditDoc.h" #include "ViewPane.h" diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index 3bcba4d5e0..9d93fd5f5b 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -45,7 +45,6 @@ #include "ActionManager.h" #include "Include/IObjectManager.h" #include "ErrorReportDialog.h" -#include "SurfaceTypeValidator.h" #include "Util/AutoLogTime.h" #include "CheckOutDialog.h" #include "GameExporter.h" @@ -99,8 +98,7 @@ namespace Internal // CCryEditDoc construction/destruction CCryEditDoc::CCryEditDoc() - : doc_validate_surface_types(nullptr) - , m_modifiedModuleFlags(eModifiedNothing) + : m_modifiedModuleFlags(eModifiedNothing) { //////////////////////////////////////////////////////////////////////// // Set member variables to initial values @@ -120,7 +118,6 @@ CCryEditDoc::CCryEditDoc() GetIEditor()->SetDocument(this); CLogFile::WriteLine("Document created"); - RegisterConsoleVariables(); MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_AS, this, &CCryEditDoc::OnFileSaveAs); bool isPrefabSystemEnabled = false; @@ -459,8 +456,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename) } } - CSurfaceTypeValidator().Validate(); - LogLoadTime(GetTickCount() - t0); // Loaded with success, remove event from log file GetIEditor()->GetSettingsManager()->UnregisterEvent(loadEvent); @@ -1910,25 +1905,6 @@ void CCryEditDoc::SetDocumentReady(bool bReady) m_bDocumentReady = bReady; } -void CCryEditDoc::RegisterConsoleVariables() -{ - doc_validate_surface_types = gEnv->pConsole->GetCVar("doc_validate_surface_types"); - - if (!doc_validate_surface_types) - { - doc_validate_surface_types = REGISTER_INT_CB("doc_validate_surface_types", 0, 0, - "Flag indicating whether icons are displayed on the animation graph.\n" - "Default is 1.\n", - OnValidateSurfaceTypesChanged); - } -} - -void CCryEditDoc::OnValidateSurfaceTypesChanged(ICVar*) -{ - CErrorsRecorder errorsRecorder(GetIEditor()); - CSurfaceTypeValidator().Validate(); -} - void CCryEditDoc::OnStartLevelResourceList() { // after loading another level we clear the RFOM_Level list, the first time the list should be empty diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index f7e97d308e..5d20bddf45 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -176,9 +176,7 @@ protected: virtual void OnFileSaveAs(); //! called immediately after saving the level. void AfterSave(); - void RegisterConsoleVariables(); void OnStartLevelResourceList(); - static void OnValidateSurfaceTypesChanged(ICVar*); QString GetCryIndexPath(const char* levelFilePath) const; @@ -194,7 +192,6 @@ protected: XmlNodeRef m_environmentTemplate; std::list m_listeners; bool m_bDocumentReady = false; - ICVar* doc_validate_surface_types = nullptr; int m_modifiedModuleFlags; // On construction, it assumes loaded levels have already been exported. Can be a big fat lie, though. // The right way would require us to save to the level folder the export status of the level. diff --git a/Code/Editor/CryEditLiveCreate.rc b/Code/Editor/CryEditLiveCreate.rc deleted file mode 100644 index 3dac96d682..0000000000 --- a/Code/Editor/CryEditLiveCreate.rc +++ /dev/null @@ -1,213 +0,0 @@ -ÿþ// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -#include "resource.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "#include ""resource.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU_LIVECREATE MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "Save settings", ID_FILE_SAVESETTINGS - MENUITEM "Close", ID_FILE_CLOSE_LIVECREATE_VIEW - END - POPUP "&View" - BEGIN - MENUITEM "LiveCreate Logger", ID_VIEW_LIVECREATELOGGER, CHECKED - MENUITEM "LiveCreate Profile Editor", ID_VIEW_LIVECREATEPROFILEEDITOR, CHECKED - MENUITEM "LiveCreate File Sync Settings", ID_VIEW_LIVECREATEFILESYNCSETTINGS, CHECKED - END -END - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_LIVECREATE_PICKER DIALOGEX 0, 0, 316, 259 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select game build directory" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,200,238,50,14 - PUSHBUTTON "Cancel",IDCANCEL,259,238,50,14 - CONTROL "",IDC_DIRECTORY_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,302,227 -END - -IDD_LIVECREATE_ADD_TARGETS DIALOGEX 0, 0, 500, 400 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Discover LiveCreate targets" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Refresh",IDC_REFRESH,8,8,70,18 - PUSHBUTTON "Add custom...",IDC_BUTTON_ADD_PEER,82,8,70,18 - CONTROL "Use wider search (broadcast)",IDC_CHECK_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,12,200,10 - CONTROL "",IDC_LIST_PEERS,"XTPReport",WS_TABSTOP,8,32,484,342,WS_EX_STATICEDGE - DEFPUSHBUTTON "Use selected",IDOK,180,379,70,18 - PUSHBUTTON "Cancel",IDCANCEL,259,379,70,18 - PUSHBUTTON "Add by IP...",IDC_BUTTON_ADD_MATERIAL,157,8,70,18 -END - -IDD_LIVECREATE_PEER_LIST DIALOGEX 0, 0, 395, 213 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - LTEXT "Peers:",IDC_STATIC,17,27,22,8 - PUSHBUTTON "Add...",IDC_BUTTON_ADD_PEER,56,24,56,16 - PUSHBUTTON "Edit...",IDC_BUTTON_EDIT_PEER,116,24,56,16 - PUSHBUTTON "Remove",IDC_BUTTON_DELETE_PEER,176,24,52,16 - DEFPUSHBUTTON "Start All",IDC_BUTTON_START_ALL,4,4,48,16 - PUSHBUTTON "Reset All",IDC_BUTTON_RESET_ALL,176,4,52,16 - PUSHBUTTON "Force Sync All",IDC_BUTTON_FORCE_SYNC_ALL,56,4,56,16 - PUSHBUTTON "Clean All",IDC_BUTTON_CLEAN_ALL,232,4,52,16 - PUSHBUTTON "Screenshot All",IDC_BUTTON_SCREENSHOT_ALL,116,4,56,16 - CONTROL "",IDC_LIST_PEERS,"XTPReport",WS_TABSTOP,4,44,386,164,WS_EX_STATICEDGE - CHECKBOX "LiveCreate",IDC_BUTTON_ENABLE_LIVECREATE,288,4,52,36,BS_PUSHLIKE | BS_MULTILINE - CHECKBOX "Sync\nCamera",IDC_BUTTON_CAMERA_SYNC,345,4,52,36,BS_PUSHLIKE | BS_MULTILINE - PUSHBUTTON "Discover",IDC_BUTTON_DISCOVER_PEERS,232,24,52,16 -END - -IDD_IDD_LIVECREATE_SETTINGS_PANEL DIALOGEX 0, 0, 156, 204 -STYLE DS_SETFONT | WS_CHILD -FONT 8, "MS Shell Dlg 2", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Add targets...",IDC_BUTTON_DISCOVER_PEERS,4,4,80,16 -END - -IDD_LIVECREATE_EDIT_CONNECTION DIALOGEX 0, 0, 288, 183 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "LiveCreate host settings" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,158,154,58,20 - PUSHBUTTON "Cancel",IDCANCEL,221,154,58,20 - LTEXT "Name:",IDC_STATIC,16,46,22,8 - EDITTEXT IDC_EDIT_TARGET_NAME,44,44,100,14,ES_AUTOHSCROLL - LTEXT "IP:",IDC_STATIC,152,46,10,8 - CONTROL "",IDC_TARGET_IPADDRESS,"SysIPAddress32",WS_TABSTOP,168,44,100,15 - LTEXT "Platform:",IDC_STATIC,8,26,30,8 - LTEXT "Build path (automatic):",IDC_STATIC,19,120,74,8 - PUSHBUTTON "Test IP",IDC_BUTTON_TEST_CONNECTION,168,60,100,16 - COMBOBOX IDC_COMBO_PLATFORM,44,24,100,88,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Resovle name to IP",IDC_BUTTON_REFRESH_IP,44,60,100,16 - CONTROL "Enable this peer",IDC_CHECK_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,8,67,10 - GROUPBOX "Build settings",IDC_STATIC,7,80,272,71 - LTEXT "Build executable:",IDC_STATIC,19,92,56,8 - PUSHBUTTON "...",IDC_BUTTON_PICK_GAME_DIRECTORY,249,104,22,14 - EDITTEXT IDC_EDIT_BUILD_ROOT_PATH,20,104,226,14,ES_AUTOHSCROLL - EDITTEXT IDC_EDIT_BUILD_EXECUTABLE,20,131,249,14,ES_AUTOHSCROLL -END - -IDD_LIVECREATE_TASK_WAIT DIALOGEX 0, 0, 238, 41 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,94,20,50,14 - LTEXT "Static",IDC_TASK_PROGRESS_TEXT,7,7,224,8 -END - -IDD_LIVECREATE_ADD_BY_IP DIALOGEX 0, 0, 137, 75 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add LiveCreate by IP" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,7,48,58,20 - PUSHBUTTON "Cancel",IDCANCEL,71,48,58,20 - LTEXT "IP:",-1,9,12,10,8 - EDITTEXT IDC_TARGET_IPADDRESS,25,10,100,15,WS_TABSTOP - PUSHBUTTON "Test IP",IDC_BUTTON_TEST_CONNECTION,25,27,100,16 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_LIVECREATE_ADD_TARGETS, DIALOG - BEGIN - END - - IDD_LIVECREATE_EDIT_CONNECTION, DIALOG - BEGIN - END - - IDD_LIVECREATE_TASK_WAIT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 231 - TOPMARGIN, 7 - BOTTOMMARGIN, 34 - END - - IDD_LIVECREATE_ADD_BY_IP, DIALOG - BEGIN - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED \ No newline at end of file diff --git a/Code/Editor/DimensionsDialog.cpp b/Code/Editor/DimensionsDialog.cpp deleted file mode 100644 index 6c8e6a616b..0000000000 --- a/Code/Editor/DimensionsDialog.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "DimensionsDialog.h" - -// Qt -#include - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - - -///////////////////////////////////////////////////////////////////////////// -CDimensionsDialog::CDimensionsDialog(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_group(new QButtonGroup(this)) - , ui(new Ui::CDimensionsDialog) -{ - ui->setupUi(this); - - setWindowTitle(tr("Generate Terrain Texture")); - - m_group->addButton(ui->Dim512, 512); - m_group->addButton(ui->Dim1024, 1024); - m_group->addButton(ui->Dim2048, 2048); - m_group->addButton(ui->Dim4096, 4096); - m_group->addButton(ui->Dim8192, 8192); - m_group->addButton(ui->Dim16384, 16384); -} - - -////////////////////////////////////////////////////////////////////////// -CDimensionsDialog::~CDimensionsDialog() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CDimensionsDialog::SetDimensions(unsigned int iWidth) -{ - //////////////////////////////////////////////////////////////////////// - // Select a dimension option button in the dialog - //////////////////////////////////////////////////////////////////////// - - QAbstractButton* button = m_group->button(iWidth); - assert(button); - - button->setChecked(true); -} - -UINT CDimensionsDialog::GetDimensions() -{ - //////////////////////////////////////////////////////////////////////// - // Get the currently selected dimension option button in the dialog - //////////////////////////////////////////////////////////////////////// - - assert(m_group->checkedId() != -1); - - return m_group->checkedId(); -} - -#include diff --git a/Code/Editor/DimensionsDialog.h b/Code/Editor/DimensionsDialog.h deleted file mode 100644 index b94c58bf95..0000000000 --- a/Code/Editor/DimensionsDialog.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once -#ifndef CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H -#define CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H - -#if !defined(Q_MOC_RUN) -#include - -#include -#endif - -class QButtonGroup; - -namespace Ui { - class CDimensionsDialog; -} - -class CDimensionsDialog - : public QDialog -{ - Q_OBJECT - -public: - CDimensionsDialog(QWidget* pParent = nullptr); // standard constructor - ~CDimensionsDialog(); - - UINT GetDimensions(); - void SetDimensions(unsigned int iWidth); - -protected: - void UpdateData(bool fromUi = true); // DDX/DDV support - -private: - QButtonGroup* m_group; - - QScopedPointer ui; -}; - -#endif // CRYINCLUDE_EDITOR_DIMENSIONSDIALOG_H diff --git a/Code/Editor/DimensionsDialog.ui b/Code/Editor/DimensionsDialog.ui deleted file mode 100644 index 316a060c92..0000000000 --- a/Code/Editor/DimensionsDialog.ui +++ /dev/null @@ -1,120 +0,0 @@ - - - CDimensionsDialog - - - - 0 - 0 - 465 - 237 - - - - Qt::StrongFocus - - - - - - Texture Dimensions (Texture Dimensions divided by Terrain Size = Texels per meter) - - - - - - Qt::StrongFocus - - - 512 x 512 - - - true - - - - - - - Qt::StrongFocus - - - 1024 x 1024 - - - - - - - Qt::StrongFocus - - - 2048 x 2048 - - - - - - - Qt::StrongFocus - - - 4096 x 4096 - - - - - - - Qt::StrongFocus - - - 8192 x 8192 - - - - - - - Qt::StrongFocus - - - 16384 x 16384 - - - - - - - - - - Qt::StrongFocus - - - QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CDimensionsDialog - accept() - - - 77 - 294 - - - 7 - 296 - - - - - diff --git a/Code/Editor/GameEngine.cpp b/Code/Editor/GameEngine.cpp index db4c587f54..9786dcf1b8 100644 --- a/Code/Editor/GameEngine.cpp +++ b/Code/Editor/GameEngine.cpp @@ -42,8 +42,6 @@ #include "ViewManager.h" #include "AnimationContext.h" -#include "UndoViewPosition.h" -#include "UndoViewRotation.h" #include "MainWindow.h" #include "Include/IObjectManager.h" #include "ActionManager.h" diff --git a/Code/Editor/MainWindow.qrc b/Code/Editor/MainWindow.qrc index c68e05ef41..57afc596bb 100644 --- a/Code/Editor/MainWindow.qrc +++ b/Code/Editor/MainWindow.qrc @@ -154,36 +154,6 @@ res/error_report_warning.svg res/error_report_comment.svg res/error_report_helper.svg - particles_tree_00.png - particles_tree_01.png - particles_tree_02.png - particles_tree_03.png - particles_tree_04.png - particles_tree_05.png - particles_tree_06.png - particles_tree_07.png - arhitype_tree_00.png - arhitype_tree_01.png - arhitype_tree_02.png - arhitype_tree_03.png - bmp00005_00.png - bmp00005_01.png - bmp00005_02.png - bmp00005_03.png - bmp00005_04.png - bmp00005_05.png - bmp00005_06.png - bmp00005_07.png - bmp00005_08.png - bmp00005_09.png - bmp00006_00.png - bmp00006_01.png - bmp00006_02.png - bmp00006_03.png - bmp00006_04.png - bmp00006_05.png - bmp00006_06.png - bmp00006_07.png res/arr_addkey.cur diff --git a/Code/Editor/NewLevelDialog.cpp b/Code/Editor/NewLevelDialog.cpp index a97eb30f57..b22d9dbaf3 100644 --- a/Code/Editor/NewLevelDialog.cpp +++ b/Code/Editor/NewLevelDialog.cpp @@ -18,9 +18,6 @@ #include #include -// Editor -#include "NewTerrainDialog.h" - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/NewTerrainDialog.cpp b/Code/Editor/NewTerrainDialog.cpp deleted file mode 100644 index 0e66482eb4..0000000000 --- a/Code/Editor/NewTerrainDialog.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -// NewTerrainDialog.cpp : implementation file -// - -#include "EditorDefs.h" - -#include "NewTerrainDialog.h" - - -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - - - -CNewTerrainDialog::CNewTerrainDialog(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_terrainResolutionIndex(0) - , m_terrainUnitsIndex(0) - , m_bUpdate(false) - , ui(new Ui::CNewTerrainDialog) - , m_initialized(false) -{ - ui->setupUi(this); - - setWindowTitle(tr("Terrain options")); - - // Default is 1024x1024, and m_terrainResolution holds an index to the combo box - m_terrainResolutionIndex = 3; - - connect(ui->TERRAIN_RESOLUTION, SIGNAL(activated(int)), this, SLOT(OnComboBoxSelectionTerrainResolution())); - connect(ui->TERRAIN_UNITS, SIGNAL(activated(int)), this, SLOT(OnComboBoxSelectionTerrainUnits())); -} - - -CNewTerrainDialog::~CNewTerrainDialog() -{ -} - - -void CNewTerrainDialog::UpdateData(bool fromUi) -{ - if (fromUi) - { - m_terrainResolutionIndex = ui->TERRAIN_RESOLUTION->currentIndex(); - m_terrainUnitsIndex = ui->TERRAIN_UNITS->currentIndex(); - } - else - { - ui->TERRAIN_RESOLUTION->setCurrentIndex(m_terrainResolutionIndex); - ui->TERRAIN_UNITS->setCurrentIndex(m_terrainUnitsIndex); - } -} - - -void CNewTerrainDialog::OnInitDialog() -{ - // Initialize terrain values. - int resolution = Ui::START_TERRAIN_RESOLUTION; - - // Fill terrain resolution combo box - for (int i = 0; i < 6; i++) - { - ui->TERRAIN_RESOLUTION->addItem(QString("%1x%1").arg(resolution)); - resolution *= 2; - } - - UpdateTerrainUnits(); - UpdateTerrainInfo(); - - // Save data. - UpdateData(false); -} - - -void CNewTerrainDialog::UpdateTerrainUnits() -{ - uint32 terrainRes = GetTerrainResolution(); - int size = terrainRes * GetTerrainUnits(); - int maxUnit = IntegerLog2(Ui::MAXIMUM_TERRAIN_RESOLUTION / terrainRes); - int units = Ui::START_TERRAIN_UNITS; - - ui->TERRAIN_UNITS->clear(); - for (int i = 0; i <= maxUnit; i++) - { - ui->TERRAIN_UNITS->addItem(QString::number(units)); - units *= 2; - } - if (size > Ui::MAXIMUM_TERRAIN_RESOLUTION) - { - m_terrainUnitsIndex = 0; - } - ui->TERRAIN_UNITS->setCurrentText(QString::number(m_terrainUnitsIndex)); -} - - -void CNewTerrainDialog::UpdateTerrainInfo() -{ - int sizeX = GetTerrainResolution() * GetTerrainUnits(); - int sizeY = GetTerrainResolution() * GetTerrainUnits(); - - QString str; - if (sizeX >= 1000) - { - str = tr("Terrain Size: %1 x %2 Kilometers").arg((float)sizeX / 1000.0f, 0, 'f', 3).arg((float)sizeY / 1000.0f, 0, 'f', 3); - } - else if (sizeX > 0) - { - str = tr("Terrain Size: %1 x %2 Meters").arg(sizeX).arg(sizeY); - } - else - { - str = tr("Level will have no terrain"); - } - - ui->TERRAIN_INFO->setText(str); -} - - -int CNewTerrainDialog::GetTerrainResolution() const -{ - // convert combo box index into resolution value - return Ui::START_TERRAIN_RESOLUTION * (1 << m_terrainResolutionIndex); -} - - -int CNewTerrainDialog::GetTerrainUnits() const -{ - // convert combo box index into units value - return Ui::START_TERRAIN_UNITS * (1 << m_terrainUnitsIndex); -} - - -void CNewTerrainDialog::OnComboBoxSelectionTerrainResolution() -{ - UpdateData(); - - UpdateTerrainUnits(); - - UpdateTerrainInfo(); -} - - -void CNewTerrainDialog::OnComboBoxSelectionTerrainUnits() -{ - UpdateData(); - - UpdateTerrainInfo(); -} - - -void CNewTerrainDialog::showEvent(QShowEvent* event) -{ - if (!m_initialized) - { - OnInitDialog(); - m_initialized = true; - } - QDialog::showEvent(event); -} - -#include diff --git a/Code/Editor/NewTerrainDialog.h b/Code/Editor/NewTerrainDialog.h deleted file mode 100644 index 8905a8c123..0000000000 --- a/Code/Editor/NewTerrainDialog.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once -#ifndef CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H -#define CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H - -#if !defined(Q_MOC_RUN) -#include - -#include - -#include -#endif - -namespace Ui -{ - class CNewTerrainDialog; - - enum TerrainDialogConstants - { - START_TERRAIN_RESOLUTION_POWER_OF_TWO = 7, - START_TERRAIN_RESOLUTION = 1 << START_TERRAIN_RESOLUTION_POWER_OF_TWO, - MAXIMUM_TERRAIN_POWER_OF_TWO = 16, - MAXIMUM_TERRAIN_RESOLUTION = 1 << MAXIMUM_TERRAIN_POWER_OF_TWO, - POWER_OFFSET = (MAXIMUM_TERRAIN_POWER_OF_TWO - START_TERRAIN_RESOLUTION_POWER_OF_TWO), - START_TERRAIN_UNITS = 1 - }; -} - -class CNewTerrainDialog - : public QDialog -{ - Q_OBJECT - -public: - CNewTerrainDialog(QWidget* pParent = nullptr); // standard constructor - ~CNewTerrainDialog(); - - int GetTerrainResolution() const; - int GetTerrainUnits() const; - - void IsResize(bool bIsResize); - - -protected: - void UpdateData(bool fromUi = true); - void OnInitDialog(); - - void UpdateTerrainUnits(); - void UpdateTerrainInfo(); - - void showEvent(QShowEvent* event) override; - -protected slots: - void OnComboBoxSelectionTerrainResolution(); - void OnComboBoxSelectionTerrainUnits(); - -public: - int m_terrainResolutionIndex; - int m_terrainUnitsIndex; - bool m_bUpdate; - - QScopedPointer ui; - bool m_initialized; -}; -#endif // CRYINCLUDE_EDITOR_NEWTERRAINDIALOG_H diff --git a/Code/Editor/NewTerrainDialog.ui b/Code/Editor/NewTerrainDialog.ui deleted file mode 100644 index 977db11918..0000000000 --- a/Code/Editor/NewTerrainDialog.ui +++ /dev/null @@ -1,112 +0,0 @@ - - - CNewTerrainDialog - - - - 0 - 0 - 292 - 160 - - - - false - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Heightmap Resolution: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - TERRAIN_RESOLUTION - - - - - - - - - - Meters Per Texel: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - TERRAIN_UNITS - - - - - - - - - - Terrain Size: 32x32 Km - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - - - buttonBox - accepted() - CNewTerrainDialog - accept() - - - 164 - 176 - - - 169 - 1 - - - - - buttonBox - rejected() - CNewTerrainDialog - reject() - - - 245 - 172 - - - 247 - -1 - - - - - diff --git a/Code/Editor/PakManagerDlg.qrc b/Code/Editor/PakManagerDlg.qrc deleted file mode 100644 index bea8f8aafd..0000000000 --- a/Code/Editor/PakManagerDlg.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - res/pakmanager_file.png - res/pakmanager_folder.png - - diff --git a/Code/Editor/PakManagerDlg.ui b/Code/Editor/PakManagerDlg.ui deleted file mode 100644 index 087e5379da..0000000000 --- a/Code/Editor/PakManagerDlg.ui +++ /dev/null @@ -1,202 +0,0 @@ - - - CPakManagerDlg - - - - 0 - 0 - 661 - 494 - - - - - - - - - - 0 - 45 - - - - Open PAK... - - - - - - - - 0 - 45 - - - - Create PAK... - - - - - - - - 0 - 45 - - - - Add files... - - - - - - - - 0 - 45 - - - - Add folder... - - - - - - - - 0 - 45 - - - - Extract... - - - - - - - - 0 - 45 - - - - Delete entries - - - - - - - - 0 - 45 - - - - &Close - - - - - - - - - - - Path: - - - - - - - - 0 - 0 - - - - QFrame::Panel - - - QFrame::Sunken - - - <none> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - QFrame::Box - - - Qt::ScrollBarAlwaysOn - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::SelectItems - - - 120 - - - false - - - - Filename - - - - - Size - - - - - Modified - - - - - - - - Ready - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Qt::AlignCenter - - - - - - - - - - diff --git a/Code/Editor/SelectEAXPresetDlg.cpp b/Code/Editor/SelectEAXPresetDlg.cpp deleted file mode 100644 index 733de8b9cf..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SelectEAXPresetDlg.h" - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include "ui_SelectEAXPresetDlg.h" -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - -CSelectEAXPresetDlg::CSelectEAXPresetDlg(QWidget* pParent) - : QDialog(pParent) - , m_ui(new Ui_CSelectEAXPresetDlg) -{ - m_ui->setupUi(this); -} - -CSelectEAXPresetDlg::~CSelectEAXPresetDlg() -{ -} - -void CSelectEAXPresetDlg::SetCurrPreset(const QString& sPreset) -{ - QAbstractListModel* model = Model(); - if (!model) - { - return; - } - - QModelIndexList indexes = model->match(QModelIndex(), Qt::DisplayRole, sPreset, 1, Qt::MatchExactly); - - if (!indexes.isEmpty()) - { - m_ui->listView->setCurrentIndex(indexes.at(0)); - } -} - -QString CSelectEAXPresetDlg::GetCurrPreset() const -{ - if (m_ui->listView->currentIndex().isValid()) - { - return m_ui->listView->currentIndex().data().toString(); - } - // EXCEPTION: OCX Property Pages should return false - return QString(); -} - - -void CSelectEAXPresetDlg::SetModel(QAbstractListModel* model) -{ - m_ui->listView->setModel(model); -} - -QAbstractListModel* CSelectEAXPresetDlg::Model() const -{ - return static_cast(m_ui->listView->model()); -} - -#include "moc_SelectEAXPresetDlg.cpp" diff --git a/Code/Editor/SelectEAXPresetDlg.h b/Code/Editor/SelectEAXPresetDlg.h deleted file mode 100644 index 9943585987..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once - -// CSelectEAXPresetDlg dialog -#ifndef CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H -#define CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H - -#if !defined(Q_MOC_RUN) -#include -#endif - -class QAbstractListModel; -class Ui_CSelectEAXPresetDlg; - -class CSelectEAXPresetDlg - : public QDialog -{ - Q_OBJECT - -public: - CSelectEAXPresetDlg(QWidget* pParent = nullptr); // standard constructor - ~CSelectEAXPresetDlg(); - - void SetCurrPreset(const QString& sPreset); - QString GetCurrPreset() const; - -protected: - void SetModel(QAbstractListModel* model); - QAbstractListModel* Model() const; - -private: - Ui_CSelectEAXPresetDlg* m_ui; -}; - -#endif // CRYINCLUDE_EDITOR_SELECTEAXPRESETDLG_H diff --git a/Code/Editor/SelectEAXPresetDlg.ui b/Code/Editor/SelectEAXPresetDlg.ui deleted file mode 100644 index 3177b66c38..0000000000 --- a/Code/Editor/SelectEAXPresetDlg.ui +++ /dev/null @@ -1,67 +0,0 @@ - - - CSelectEAXPresetDlg - - - - 0 - 0 - 197 - 233 - - - - Select Preset... - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - listView - - - - - buttonBox - accepted() - CSelectEAXPresetDlg - accept() - - - 51 - 207 - - - 49 - 199 - - - - - buttonBox - rejected() - CSelectEAXPresetDlg - reject() - - - 148 - 213 - - - 131 - 199 - - - - - diff --git a/Code/Editor/SurfaceTypeValidator.cpp b/Code/Editor/SurfaceTypeValidator.cpp deleted file mode 100644 index 9f246cd453..0000000000 --- a/Code/Editor/SurfaceTypeValidator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "SurfaceTypeValidator.h" - -// Editor -#include "Include/IObjectManager.h" -#include "Objects/BaseObject.h" -#include "ErrorReport.h" - - -void CSurfaceTypeValidator::Validate() -{ -} - diff --git a/Code/Editor/SurfaceTypeValidator.h b/Code/Editor/SurfaceTypeValidator.h deleted file mode 100644 index 6b1a3fbed7..0000000000 --- a/Code/Editor/SurfaceTypeValidator.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H -#define CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H -#pragma once - - - -class CSurfaceTypeValidator -{ -public: - void Validate(); - -private: -}; - -#endif // CRYINCLUDE_EDITOR_SURFACETYPEVALIDATOR_H diff --git a/Code/Editor/UndoViewPosition.cpp b/Code/Editor/UndoViewPosition.cpp deleted file mode 100644 index 1934d255d3..0000000000 --- a/Code/Editor/UndoViewPosition.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - - -#include "EditorDefs.h" - -#include "UndoViewPosition.h" - -// Editor -#include "ViewManager.h" - -CUndoViewPosition::CUndoViewPosition(const QString& pUndoDescription) -{ - m_undoDescription = pUndoDescription; - - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - m_undo = tm.GetTranslation(); - } -} - -int CUndoViewPosition::GetSize() -{ - return sizeof(*this); -} - -QString CUndoViewPosition::GetDescription() -{ - return m_undoDescription; -} - -void CUndoViewPosition::Undo(bool bUndo) -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - if (bUndo) - { - m_redo = tm.GetTranslation(); - } - - tm.SetTranslation(m_undo); - pRenderViewport->SetViewTM(tm); - } -} - -void CUndoViewPosition::Redo() -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetTranslation(m_redo); - pRenderViewport->SetViewTM(tm); - } -} diff --git a/Code/Editor/UndoViewPosition.h b/Code/Editor/UndoViewPosition.h deleted file mode 100644 index e0c6c145e8..0000000000 --- a/Code/Editor/UndoViewPosition.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - -#ifndef CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H -#define CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H -#pragma once - -#include "Undo/IUndoObject.h" - -class CUndoViewPosition - : public IUndoObject -{ -public: - CUndoViewPosition(const QString& pUndoDescription = "Set Current View Position"); - -protected: - int GetSize(); - QString GetDescription(); - void Undo(bool bUndo); - void Redo(); - -private: - Vec3 m_undo; - Vec3 m_redo; - QString m_undoDescription; -}; - -#endif // CRYINCLUDE_EDITOR_UNDOVIEWPOSITION_H diff --git a/Code/Editor/UndoViewRotation.cpp b/Code/Editor/UndoViewRotation.cpp deleted file mode 100644 index a305641d3b..0000000000 --- a/Code/Editor/UndoViewRotation.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewPosition) - - -#include "EditorDefs.h" - -#include "UndoViewRotation.h" - -// Editor -#include "ViewManager.h" - -#include -#include -#include -#include - -Ang3 CUndoViewRotation::GetActiveCameraRotation() -{ - AZ::Transform activeCameraTm = AZ::Transform::CreateIdentity(); - Camera::ActiveCameraRequestBus::BroadcastResult( - activeCameraTm, - &Camera::ActiveCameraRequestBus::Events::GetActiveCameraTransform - ); - const AZ::Matrix3x4 cameraMatrix = AZ::Matrix3x4::CreateFromTransform(activeCameraTm); - const Matrix33 cameraMatrixCry = AZMatrix3x3ToLYMatrix3x3(AZ::Matrix3x3::CreateFromMatrix3x4(cameraMatrix)); - return RAD2DEG(Ang3::GetAnglesXYZ(cameraMatrixCry)); -} - -CUndoViewRotation::CUndoViewRotation(const QString& pUndoDescription) -{ - m_undoDescription = pUndoDescription; - m_undo = GetActiveCameraRotation(); -} - -int CUndoViewRotation::GetSize() -{ - return sizeof(*this); -} - -QString CUndoViewRotation::GetDescription() -{ - return m_undoDescription; -} - -void CUndoViewRotation::Undo(bool bUndo) -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - if (bUndo) - { - m_redo = GetActiveCameraRotation(); - } - - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetRotationXYZ(Ang3(DEG2RAD(m_undo.x), DEG2RAD(m_undo.y), DEG2RAD(m_undo.z)), tm.GetTranslation()); - pRenderViewport->SetViewTM(tm); - } -} - -void CUndoViewRotation::Redo() -{ - CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport(); - if (pRenderViewport) - { - Matrix34 tm = pRenderViewport->GetViewTM(); - tm.SetRotationXYZ(Ang3(DEG2RAD(m_redo.x), DEG2RAD(m_redo.y), DEG2RAD(m_redo.z)), tm.GetTranslation()); - pRenderViewport->SetViewTM(tm); - } -} diff --git a/Code/Editor/UndoViewRotation.h b/Code/Editor/UndoViewRotation.h deleted file mode 100644 index 2e086a3f05..0000000000 --- a/Code/Editor/UndoViewRotation.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// Description : Undo for Python function (PySetCurrentViewRotation) - - -#ifndef CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H -#define CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H -#pragma once -#include "Undo/IUndoObject.h" - - -class CUndoViewRotation - : public IUndoObject -{ -public: - CUndoViewRotation(const QString& pUndoDescription = "Set Current View Rotation"); - -protected: - int GetSize(); - QString GetDescription(); - void Undo(bool bUndo); - void Redo(); - -private: - static Ang3 GetActiveCameraRotation(); - - Ang3 m_undo; - Ang3 m_redo; - QString m_undoDescription; -}; - -#endif // CRYINCLUDE_EDITOR_UNDOVIEWROTATION_H diff --git a/Code/Editor/UserMessageDefines.h b/Code/Editor/UserMessageDefines.h deleted file mode 100644 index 0b13d2819f..0000000000 --- a/Code/Editor/UserMessageDefines.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H -#define CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H -#pragma once - - -enum ESandboxUserMessages -{ - // InPlaceComboBox - WM_USER_ON_SELECTION_CANCEL = WM_USER + 1, - WM_USER_ON_SELECTION_OK, - WM_USER_ON_NEW_SELECTION, - WM_USER_ON_EDITCHANGE, - WM_USER_ON_OPENDROPDOWN, - WM_USER_ON_EDITKEYDOWN, - WM_USER_ON_EDITCLICK, - // ACListWnd - ENAC_UPDATE, - // EditWithButton - WM_USER_EDITWITHBUTTON_CLICKED, - // FillSliderCtrl - WMU_FS_CHANGED, - WMU_FS_LBUTTONDOWN, - WMU_FS_LBUTTONUP, - FLM_EDITTEXTCHANGED, - FLM_FILTERTEXTCHANGED, - // NumberCtrlEdit - WMU_LBUTTONDOWN, - WMU_LBUTTONUP, - WM_ONWINDOWFOCUSCHANGES, - // SelectObjectDialog - IDT_TIMER_0, - IDT_TIMER_1, - // LensFlareEditor - WM_FLAREEDITOR_UPDATETREECONTROL, - // EquipPackDialog - UM_EQUIPLIST_CHECKSTATECHANGE, - // MaterialSender/MatEditMainDlg - WM_MATEDITPICK, - // GridMapWindow - WM_USER_ON_DBL_CLICK, - // LMCompDialog - WM_UPDATE_LIGHTMAP_GENERATION_PROGRESS, - WM_UPDATE_LIGHTMAP_GENERATION_MEMUSAGE, - WM_UPDATE_LIGHTMAP_GENERATION_MEMUSAGE_STATIC, - WM_UPDATE_GLM_NAME_EDIT, - // Viewport - WM_VIEWPORT_ON_TITLE_CHANGE, - // VisualLogControls - UWM_BUTTON_CLICKED, -}; -#endif // CRYINCLUDE_EDITOR_USERMESSAGEDEFINES_H diff --git a/Code/Editor/ViewPane.cpp b/Code/Editor/ViewPane.cpp index 421db8394e..e3494a4049 100644 --- a/Code/Editor/ViewPane.cpp +++ b/Code/Editor/ViewPane.cpp @@ -38,7 +38,6 @@ #include "Viewport.h" #include "LayoutConfigDialog.h" #include "TopRendererWnd.h" -#include "UserMessageDefines.h" #include "MainWindow.h" #include "QtViewPaneManager.h" #include "EditorViewportWidget.h" diff --git a/Code/Editor/WipFeatureManager.cpp b/Code/Editor/WipFeatureManager.cpp deleted file mode 100644 index 4fb9ed1d93..0000000000 --- a/Code/Editor/WipFeatureManager.cpp +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "WipFeatureManager.h" - -#ifdef USE_WIP_FEATURES_MANAGER -#include "WipFeaturesDlg.h" - -#if defined(AZ_PLATFORM_WINDOWS) -const char* CWipFeatureManager::kWipFeaturesFilename = "@user@\\Editor\\UI\\WipFeatures.xml"; -#else -const char* CWipFeatureManager::kWipFeaturesFilename = "@user@/Editor/UI/WipFeatures.xml"; -#endif -CWipFeatureManager* CWipFeatureManager::s_pInstance = nullptr; - -static void WipFeatureVarChange(ICVar* pVar) -{ - QString strParams = pVar->GetString(); - QStringList params; - - SplitString(strParams, params, ' '); - - if (strParams == "edit") - { - static CWipFeaturesDlg dlg; - - dlg.show(); - - return; - } - - if (params.size() >= 2) - { - QString featName = params[0].trimmed(); - QString attr = params[1].trimmed(); - - if (featName.isEmpty()) - { - return; - } - - int id = featName.toInt(); - - // if all features - if (featName == "*") - { - if (attr == "enable") - { - CWipFeatureManager::Instance()->EnableAllFeatures(true); - } - else - if (attr == "disable") - { - CWipFeatureManager::Instance()->EnableAllFeatures(false); - } - else - if (attr == "hide") - { - CWipFeatureManager::Instance()->ShowAllFeatures(false); - } - else - if (attr == "show") - { - CWipFeatureManager::Instance()->ShowAllFeatures(true); - } - else - if (attr == "safemode") - { - CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(true); - } - else - if (attr == "fullmode") - { - CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(false); - } - else - { - CWipFeatureManager::Instance()->SetAllFeaturesParams(attr.toUtf8().data()); - } - - return; - } - - if (attr == "enable") - { - CWipFeatureManager::Instance()->EnableFeature(id, true); - } - else - if (attr == "disable") - { - CWipFeatureManager::Instance()->EnableFeature(id, false); - } - else - if (attr == "hide") - { - CWipFeatureManager::Instance()->ShowFeature(id, false); - } - else - if (attr == "show") - { - CWipFeatureManager::Instance()->ShowFeature(id, true); - } - else - if (attr == "safemode") - { - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, true); - } - else - if (attr == "fullmode") - { - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, false); - } - else - { - CWipFeatureManager::Instance()->SetFeatureParams(id, attr.toUtf8().data()); - } - } -} - -CWipFeatureManager::CWipFeatureManager() -{ - m_bEnabled = true; -} - -CWipFeatureManager::~CWipFeatureManager() -{ -} - -bool CWipFeatureManager::Init(bool bLoadXml) -{ - if (!gEnv) - { - return false; - } - - IConsole* pConsole = gEnv->pConsole; - - if (!pConsole) - { - return false; - } - - REGISTER_CVAR2_CB("e_wipfeature", (const char**)&CWipFeatureManager::Instance()->m_consoleCmdParams, "", VF_ALWAYSONCHANGE | VF_CHEAT, "wipfeature enable|disable|hide|show|safemode|fullmode", WipFeatureVarChange); - - if (bLoadXml) - { - CWipFeatureManager::Instance()->Load(); - } - - return true; -} - -void CWipFeatureManager::Shutdown() -{ - CWipFeatureManager::Instance()->Save(); - delete s_pInstance; - s_pInstance = nullptr; -} - -bool CWipFeatureManager::Load(const char* pFilename, bool bClearExisting) -{ - if (!GetISystem()) - { - return false; - } - - XmlNodeRef root = GetISystem()->LoadXmlFromFile(pFilename); - - if (!root) - { - return false; - } - - if (bClearExisting) - { - m_features.clear(); - } - - Log("Loading WIP features file: '%s'...", pFilename); - - for (size_t i = 0, iCount = root->getChildCount(); i < iCount; ++i) - { - SWipFeatureInfo wf; - XmlNodeRef node = root->getChild(static_cast(i)); - XmlString str; - - node->getAttr("id", wf.m_id); - node->getAttr("displayName", str); - wf.m_displayName = str; - node->getAttr("visible", wf.m_bVisible); - node->getAttr("enabled", wf.m_bEnabled); - node->getAttr("safeMode", wf.m_bSafeMode); - node->getAttr("params", str); - wf.m_params = str; - wf.m_bLoadedFromXml = true; - - TWipFeatures::iterator iter = m_features.find(wf.m_id); - - if (iter == m_features.end()) - { - m_features[wf.m_id] = wf; - } - else - { - m_features[wf.m_id].m_bVisible = wf.m_bVisible; - m_features[wf.m_id].m_bEnabled = wf.m_bEnabled; - m_features[wf.m_id].m_bSafeMode = wf.m_bSafeMode; - m_features[wf.m_id].m_params = wf.m_params; - } - } - - Log("Loaded %d WIP features.", m_features.size()); - - return true; -} - -bool CWipFeatureManager::Save(const char* pFilename) -{ - if (!gEnv) - { - return false; - } - - if (!GetISystem()) - { - return false; - } - - ISystem* pISystem = GetISystem(); - - XmlNodeRef root = pISystem->CreateXmlNode("features"); - - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - SWipFeatureInfo& wf = iter->second; - XmlNodeRef node = root->createNode("feature"); - - node->setAttr("id", wf.m_id); - node->setAttr("displayName", wf.m_displayName.c_str()); - node->setAttr("visible", wf.m_bVisible); - node->setAttr("enabled", wf.m_bEnabled); - node->setAttr("safeMode", wf.m_bSafeMode); - node->setAttr("params", wf.m_params.c_str()); - - root->addChild(node); - } - - root->saveToFile(pFilename); - - return true; -} - -int CWipFeatureManager::RegisterFeature(const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml) -{ - int aMaxId = -1; - - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - if (iter->first > aMaxId) - { - aMaxId = iter->first; - } - } - - ++aMaxId; - SetFeature(aMaxId, pDisplayName, bVisible, bEnabled, bSafeMode, pParams, bSaveToXml); - - return aMaxId; -} - -void CWipFeatureManager::SetFeature(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml) -{ - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - m_features[aFeatureId].m_bVisible = bVisible; - m_features[aFeatureId].m_bEnabled = bEnabled; - m_features[aFeatureId].m_bSafeMode = bSafeMode; - m_features[aFeatureId].m_bSaveToXml = bSaveToXml; - m_features[aFeatureId].m_params = pParams; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams); - } -} - -void CWipFeatureManager::SetDefaultFeatureStates(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams) -{ - TWipFeatures::iterator iter = m_features.find(aFeatureId); - - // set feature if not existing - if (iter == m_features.end() || (iter != m_features.end() && !iter->second.m_bLoadedFromXml)) - { - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - m_features[aFeatureId].m_bVisible = bVisible; - m_features[aFeatureId].m_bEnabled = bEnabled; - m_features[aFeatureId].m_bSafeMode = bSafeMode; - m_features[aFeatureId].m_params = pParams; - } - else - if (iter != m_features.end() && iter->second.m_bLoadedFromXml) - { - m_features[aFeatureId].m_id = aFeatureId; - m_features[aFeatureId].m_displayName = pDisplayName; - } - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams); - } -} - -bool CWipFeatureManager::IsFeatureVisible(int aFeatureId) -{ - return m_features[aFeatureId].m_bVisible || !m_bEnabled; -} - -bool CWipFeatureManager::IsFeatureEnabled(int aFeatureId) -{ - return m_features[aFeatureId].m_bEnabled || !m_bEnabled; -} - -bool CWipFeatureManager::IsFeatureInSafeMode(int aFeatureId) -{ - if (!m_bEnabled) - { - return false; - } - - return m_features[aFeatureId].m_bSafeMode; -} - -const char* CWipFeatureManager::GetFeatureParams(int aFeatureId) -{ - return m_features[aFeatureId].m_params.c_str(); -} - -void CWipFeatureManager::ShowFeature(int aFeatureId, bool bShow) -{ - m_features[aFeatureId].m_bVisible = bShow; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bShow, nullptr, nullptr, nullptr); - } -} - -void CWipFeatureManager::EnableFeature(int aFeatureId, bool bEnable) -{ - m_features[aFeatureId].m_bEnabled = bEnable; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, &bEnable, nullptr, nullptr); - } -} - -void CWipFeatureManager::SetFeatureSafeMode(int aFeatureId, bool bSafeMode) -{ - m_features[aFeatureId].m_bSafeMode = bSafeMode; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, &bSafeMode, nullptr); - } -} - -void CWipFeatureManager::SetFeatureParams(int aFeatureId, const char* pParams) -{ - m_features[aFeatureId].m_params = pParams; - - if (m_features[aFeatureId].m_pfnUpdateFeature) - { - m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, nullptr, pParams); - } -} - -void CWipFeatureManager::ShowAllFeatures(bool bShow) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bVisible = bShow; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, &bShow, nullptr, nullptr, nullptr); - } - } -} - -void CWipFeatureManager::EnableAllFeatures(bool bEnable) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bEnabled = bEnable; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, &bEnable, nullptr, nullptr); - } - } -} - -void CWipFeatureManager::SetAllFeaturesSafeMode(bool bSafeMode) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_bSafeMode = bSafeMode; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, &bSafeMode, nullptr); - } - } -} - -void CWipFeatureManager::SetAllFeaturesParams(const char* pParams) -{ - for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter) - { - iter->second.m_params = pParams; - - if (iter->second.m_pfnUpdateFeature) - { - iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, nullptr, pParams); - } - } -} - -void CWipFeatureManager::EnableManager(bool bEnable) -{ - m_bEnabled = bEnable; -} - -void CWipFeatureManager::SetFeatureUpdateCallback(int aFeatureId, TWipFeatureUpdateCallback pfnUpdate) -{ - m_features[aFeatureId].m_pfnUpdateFeature = pfnUpdate; -} - -AZStd::map& CWipFeatureManager::GetFeatures() -{ - return m_features; -} - -#endif diff --git a/Code/Editor/WipFeatureManager.h b/Code/Editor/WipFeatureManager.h deleted file mode 100644 index cd20f6d591..0000000000 --- a/Code/Editor/WipFeatureManager.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#ifndef CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H -#define CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H -#pragma once - -#include -#include - -/* - This class is used to control work in progress features at runtime, so QA can test even if the end user will not see those features - You can use the console command: e_wipfeature enable|disable|hide|show|safemode|fullmode - ****************************************************************************************************************************************** - *** GOOD TO KNOW: "e_wipfeature edit" console command will display the WIP dialog and you can control the features from there - ****************************************************************************************************************************************** -*/ - -// undef this define to spot all wip feature usages within the editor at compile time -#define USE_WIP_FEATURES_MANAGER - -#ifdef USE_WIP_FEATURES_MANAGER - -// use this to register new wip features, usage from inside functions -// @param id is the numeric unique id of the feature, its good to have all feature ids in an enum in one file -// @param bVisible is the feature visible by default -// @param bEnabled is the feature enabled (usually visual enable like non-grayed) by default -// @param bSafeMode is the feature operating in some sort of safe mode (the safe mode behavior defined by the feature itself) -// @param pTWipFeatureUpdateCallback callback of type TWipFeatureUpdateCallback for when a feature state (visible,enabled and so on) was modified -#define REGISTER_WIP_FEATURE(id, bVisible, bEnabled, bSafeMode, pTWipFeatureUpdateCallback) \ - static CWipFeatureManager::CWipFeatureRegisterer s_wipFeatureRegisterer_##id(id, ""#id, bVisible, bEnabled, bSafeMode, pTWipFeatureUpdateCallback); - -#define IS_WIP_FEATURE_VISIBLE(id) CWipFeatureManager::Instance()->IsFeatureVisible(id) -#define IS_WIP_FEATURE_ENABLED(id) CWipFeatureManager::Instance()->IsFeatureEnabled(id) -#define IS_WIP_FEATURE_SAFEMODE(id) CWipFeatureManager::Instance()->IsFeatureInSafeMode(id) - -// The feature manager singleton itself -class CWipFeatureManager -{ -public: - - static const char* kWipFeaturesFilename; - - // Used to register a callback function to update the state of features whitin the editor - // pbVisible, pbEnabled, pbSafeMode, pParams - if the pointer is nullptr, then that attribute was not changed - typedef void (* TWipFeatureUpdateCallback)(int aFeatureId, const bool* const pbVisible, const bool* const pbEnabled, const bool* const pbSafeMode, const char* pParams); - - // wip feature registerer auto create object, used for static auto feature creation with the REGISTER_WIP_FEATURE macro - class CWipFeatureRegisterer - { - public: - - CWipFeatureRegisterer(int id, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, TWipFeatureUpdateCallback pTWipFeatureUpdateCallback) - { - CWipFeatureManager::Instance()->SetFeatureUpdateCallback(id, pTWipFeatureUpdateCallback); - CWipFeatureManager::Instance()->SetDefaultFeatureStates(id, pDisplayName, bVisible, bEnabled, bSafeMode); - } - }; - - struct SWipFeatureInfo - { - SWipFeatureInfo() - : m_id(0) - , m_displayName("") - , m_bVisible(true) - , m_bEnabled(true) - , m_bSafeMode(false) - , m_pfnUpdateFeature(nullptr) - , m_bLoadedFromXml(false) - {} - - int m_id; - AZStd::string m_displayName, m_params; - bool m_bVisible, m_bEnabled, m_bSafeMode, - // if true, this feature will be saved into the xml file when Save(...) will be called - m_bSaveToXml, m_bLoadedFromXml; - TWipFeatureUpdateCallback m_pfnUpdateFeature; - }; - - typedef AZStd::map TWipFeatures; - -private: - - CWipFeatureManager(); - ~CWipFeatureManager(); - - static CWipFeatureManager* s_pInstance; - -public: - - static CWipFeatureManager* Instance() - { - if (!s_pInstance) - { - s_pInstance = new CWipFeatureManager(); - AZ_Assert(s_pInstance, "Could not construct CWipFeatureManager"); - } - - return s_pInstance; - } - - static bool Init(bool bLoadXml = true); - static void Shutdown(); - - bool Load(const char* pFilename = kWipFeaturesFilename, bool bClearExisting = true); - bool Save(const char* pFilename = kWipFeaturesFilename); - - // Register a new feature - // @return a new feature ID - int RegisterFeature(const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = "", bool bSaveToXml = true); - // Set an existing feature - void SetFeature(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = "", bool bSaveToXml = true); - // Create a new feature, but it will take into account the existing feature info from the loaded XML file, with persistent settings, if any - void SetDefaultFeatureStates(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams = ""); - bool IsFeatureVisible(int aFeatureId); - bool IsFeatureEnabled(int aFeatureId); - bool IsFeatureInSafeMode(int aFeatureId); - const char* GetFeatureParams(int aFeatureId); - - void ShowFeature(int aFeatureId, bool bShow = true); - void EnableFeature(int aFeatureId, bool bEnable = true); - void SetFeatureSafeMode(int aFeatureId, bool bSafeMode); - void SetFeatureParams(int aFeatureId, const char* pParams); - - void ShowAllFeatures(bool bShow = true); - void EnableAllFeatures(bool bEnable = true); - void SetAllFeaturesSafeMode(bool bSafeMode); - void SetAllFeaturesParams(const char* pParams); - - // if manager is disabled, then all queries about feature enable/visible/fullmode states will return true always - void EnableManager(bool bEnable = true); - - void SetFeatureUpdateCallback(int aFeatureId, TWipFeatureUpdateCallback pfnUpdate); - TWipFeatures& GetFeatures(); - -private: - - static const int kMaxWipCmdSize = 200; - - TWipFeatures m_features; - char m_consoleCmdParams[kMaxWipCmdSize]; - bool m_bEnabled; -}; - -#else - -// -// no WIP feature manager in production build -// -#define REGISTER_WIP_FEATURE -#define IS_WIP_FEATURE_VISIBLE(id) true -#define IS_WIP_FEATURE_ENABLED(id) true -#define IS_WIP_FEATURE_SAFEMODE(id) true - -#endif //USE_WIP_FEATURES_MANAGER -#endif // CRYINCLUDE_EDITOR_WIPFEATUREMANAGER_H diff --git a/Code/Editor/WipFeaturesDlg.cpp b/Code/Editor/WipFeaturesDlg.cpp deleted file mode 100644 index bc4372d7fb..0000000000 --- a/Code/Editor/WipFeaturesDlg.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#include "EditorDefs.h" - -#include "WipFeatureManager.h" - -#include "WipFeaturesDlg.h" - -// Qt -#include - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include "ui_WipFeaturesDlg.h" -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - -#ifdef USE_WIP_FEATURES_MANAGER - -// CWipFeaturesDlg dialog - -class WipFeaturesModel - : public QAbstractTableModel -{ -public: - WipFeaturesModel(QObject* parent = nullptr) - : QAbstractTableModel(parent) - { - } - - int rowCount(const QModelIndex& parent = QModelIndex()) const override - { - return parent.isValid() ? 0 : static_cast(CWipFeatureManager::Instance()->GetFeatures().size()); - } - - int columnCount(const QModelIndex& parent = QModelIndex()) const override - { - return parent.isValid() ? 0 : 5; - } - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override - { - if (orientation != Qt::Horizontal || section >= columnCount()) - { - return QVariant(); - } - - - switch (role) - { - case Qt::TextAlignmentRole: - return section == 0 ? Qt::AlignLeft : Qt::AlignCenter; - case Qt::DisplayRole: - switch (section) - { - case 0: - return tr("Name"); - case 1: - return tr("Id"); - case 2: - return tr("Visible"); - case 3: - return tr("Enabled"); - case 4: - return tr("SafeMode"); - default: - return QVariant(); - } - default: - return QVariant(); - } - } - - bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override - { - if (!index.isValid() || index.column() >= columnCount(index.parent()) || index.row() >= rowCount(index.parent())) - { - return false; - } - - if (role != Qt::EditRole || !value.canConvert()) - { - return false; - } - - auto it = CWipFeatureManager::Instance()->GetFeatures().begin(); - std::advance(it, index.row()); - - auto id = it->first; - - switch (index.column()) - { - case 2: - CWipFeatureManager::Instance()->ShowFeature(id, value.toBool()); - break; - case 3: - CWipFeatureManager::Instance()->EnableFeature(id, value.toBool()); - break; - case 4: - CWipFeatureManager::Instance()->SetFeatureSafeMode(id, value.toBool()); - break; - default: - return false; - } - - emit dataChanged(index, index); - return true; - } - - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override - { - if (!index.isValid() || index.column() >= columnCount(index.parent()) || index.row() >= rowCount(index.parent())) - { - return QVariant(); - } - - if (role == Qt::TextAlignmentRole) - { - return headerData(index.column(), Qt::Horizontal, role); - } - - if (role != Qt::DisplayRole) - { - return QVariant(); - } - - auto it = CWipFeatureManager::Instance()->GetFeatures().begin(); - std::advance(it, index.row()); - - auto feature = it->second; - - switch (index.column()) - { - case 0: - return QString(feature.m_displayName.c_str()); - case 1: - return feature.m_id; - case 2: - return feature.m_bVisible ? tr("X") : QString(); - case 3: - return feature.m_bEnabled ? tr("X") : QString(); - case 4: - return feature.m_bSafeMode ? tr("X") : QString(); - default: - return QVariant(); - } - } -}; - -CWipFeaturesDlg::CWipFeaturesDlg(QWidget* pParent /*=nullptr*/) - : QDialog(pParent) - , m_ui(new Ui::WipFeaturesDlg) -{ - m_ui->setupUi(this); - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - setFixedSize(size()); - - OnInitDialog(); - - connect(m_ui->buttonShow, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonShow); - connect(m_ui->buttonHide, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonHide); - connect(m_ui->buttonEnable, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonEnable); - connect(m_ui->buttonDisable, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonDisable); - connect(m_ui->buttonSafeMode, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonSafemode); - connect(m_ui->buttonNormalMode, &QPushButton::clicked, this, &CWipFeaturesDlg::OnBnClickedButtonNormalmode); -} - -CWipFeaturesDlg::~CWipFeaturesDlg() -{ -} - -// CWipFeaturesDlg message handlers - -void CWipFeaturesDlg::OnInitDialog() -{ - m_ui->m_lstFeatures->setModel(new WipFeaturesModel(this)); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(0, 300); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(1, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(2, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(3, 70); - m_ui->m_lstFeatures->horizontalHeader()->resizeSection(4, 70); -} - -void CWipFeaturesDlg::OnBnClickedButtonShow() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 2), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonHide() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 2), false); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonEnable() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 3), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonDisable() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 3), false); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonSafemode() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 4), true); - } -} - -void CWipFeaturesDlg::OnBnClickedButtonNormalmode() -{ - for (auto index : m_ui->m_lstFeatures->selectionModel()->selectedRows()) - { - m_ui->m_lstFeatures->model()->setData(index.sibling(index.row(), 4), false); - } -} - -#include - -#endif // USE_WIP_FEATURES_MANAGER diff --git a/Code/Editor/WipFeaturesDlg.h b/Code/Editor/WipFeaturesDlg.h deleted file mode 100644 index 28f4f43958..0000000000 --- a/Code/Editor/WipFeaturesDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -#pragma once -#ifndef CRYINCLUDE_EDITOR_WIPFEATURESDLG_H -#define CRYINCLUDE_EDITOR_WIPFEATURESDLG_H - -#if !defined(Q_MOC_RUN) -#include -#endif - -#ifdef USE_WIP_FEATURES_MANAGER - -// CWipFeaturesDlg dialog - -namespace Ui -{ - class WipFeaturesDlg; -} - -class CWipFeaturesDlg - : public QDialog -{ - Q_OBJECT -public: - CWipFeaturesDlg(QWidget* pParent = nullptr); // standard constructor - virtual ~CWipFeaturesDlg(); - -private: - void OnInitDialog(); - void OnBnClickedButtonShow(); - void OnBnClickedButtonHide(); - void OnBnClickedButtonEnable(); - void OnBnClickedButtonDisable(); - void OnBnClickedButtonSafemode(); - void OnBnClickedButtonNormalmode(); - -private: - QScopedPointer m_ui; -}; - -#else - -class CWipFeaturesDlg - : public QDialog -{ - Q_OBJECT -}; - -#endif // USE_WIP_FEATURES_MANAGER - -#endif // CRYINCLUDE_EDITOR_WIPFEATURESDLG_H diff --git a/Code/Editor/WipFeaturesDlg.qrc b/Code/Editor/WipFeaturesDlg.qrc deleted file mode 100644 index 1205b1063e..0000000000 --- a/Code/Editor/WipFeaturesDlg.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - res/work_in_progress_icon.png - - diff --git a/Code/Editor/WipFeaturesDlg.ui b/Code/Editor/WipFeaturesDlg.ui deleted file mode 100644 index b4bf95e2c5..0000000000 --- a/Code/Editor/WipFeaturesDlg.ui +++ /dev/null @@ -1,184 +0,0 @@ - - - WipFeaturesDlg - - - - 0 - 0 - 620 - 342 - - - - Work in Progress Features - - - - - - Work in progress features: - - - - - - Qt::ScrollBarAlwaysOff - - - QAbstractItemView::SelectRows - - - true - - - false - - - 19 - - - - - - - Show - - - - - - - Hide - - - - - - - Qt::Horizontal - - - QSizePolicy::Ignored - - - - 74 - 20 - - - - - - - - Enable - - - - - - - Disable - - - - - - - Qt::Horizontal - - - QSizePolicy::Ignored - - - - 74 - 20 - - - - - - - - Normal Mode - - - - - - - Safe Mode - - - - - - - - - - - 64 - 64 - - - - - 64 - 64 - - - - :/res/work_in_progress_icon.png - - - - - - - - 0 - 0 - - - - NOTE:<br/>The states of the WIP features will be saved in the Editor/UI/WipFeatures.xml file when the editor exits successfuly - - - true - - - - - - - QDialogButtonBox::Close - - - - - - - - - - - buttonBox - rejected() - WipFeaturesDlg - close() - - - 647 - 339 - - - 674 - 314 - - - - - diff --git a/Code/Editor/arhitype_tree_00.png b/Code/Editor/arhitype_tree_00.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/arhitype_tree_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/arhitype_tree_01.png b/Code/Editor/arhitype_tree_01.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/arhitype_tree_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/arhitype_tree_02.png b/Code/Editor/arhitype_tree_02.png deleted file mode 100644 index f29a502de1..0000000000 --- a/Code/Editor/arhitype_tree_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8b26d30e8c00514648cf72bb80fe8be3f665eb7473b6565b31a4b078816bfd -size 208 diff --git a/Code/Editor/arhitype_tree_03.png b/Code/Editor/arhitype_tree_03.png deleted file mode 100644 index f29a502de1..0000000000 --- a/Code/Editor/arhitype_tree_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8b26d30e8c00514648cf72bb80fe8be3f665eb7473b6565b31a4b078816bfd -size 208 diff --git a/Code/Editor/bmp00005_00.png b/Code/Editor/bmp00005_00.png deleted file mode 100644 index 345abfaf01..0000000000 --- a/Code/Editor/bmp00005_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5e4a0284f8d3b2625c3f27d6505b19a0babb7af0825f08b4e08f40e647d10873 -size 388 diff --git a/Code/Editor/bmp00005_01.png b/Code/Editor/bmp00005_01.png deleted file mode 100644 index abeba83277..0000000000 --- a/Code/Editor/bmp00005_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43f64ba8198c197f2dd91f00947df808fa41274411934d3d1f81e3eb44f78e7a -size 532 diff --git a/Code/Editor/bmp00005_02.png b/Code/Editor/bmp00005_02.png deleted file mode 100644 index 45439597e2..0000000000 --- a/Code/Editor/bmp00005_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:556929870bb8c26fe8ebf4e94536e74c2eb1084e6f566007ec3a5f2e6303fa53 -size 392 diff --git a/Code/Editor/bmp00005_03.png b/Code/Editor/bmp00005_03.png deleted file mode 100644 index b67ec062ff..0000000000 --- a/Code/Editor/bmp00005_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:239843fcd5a08e260106ee6eb3f69d3606321267e94df1e64ab25573d14980e1 -size 486 diff --git a/Code/Editor/bmp00005_04.png b/Code/Editor/bmp00005_04.png deleted file mode 100644 index 565730be66..0000000000 --- a/Code/Editor/bmp00005_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98baf372c91fe63c423237a2a3ae5a043a4da41095698035ce86fd13f2051e44 -size 514 diff --git a/Code/Editor/bmp00005_05.png b/Code/Editor/bmp00005_05.png deleted file mode 100644 index 232c374515..0000000000 --- a/Code/Editor/bmp00005_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a570ae986b5f0b7e573094a7e75a8cfcc42f88b4766c47785bab26a9e8b1c2bb -size 239 diff --git a/Code/Editor/bmp00005_06.png b/Code/Editor/bmp00005_06.png deleted file mode 100644 index 3de6336a89..0000000000 --- a/Code/Editor/bmp00005_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c527f2b8c883c73aebba0b5f0df6215f73b7259db61b13fa5ff7aa7b96a7b9b -size 779 diff --git a/Code/Editor/bmp00005_07.png b/Code/Editor/bmp00005_07.png deleted file mode 100644 index a813c0ad0b..0000000000 --- a/Code/Editor/bmp00005_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f7f84cb48b2f9031b3a23abeddaed95d54601de33c58057d6677073b3e083aa -size 501 diff --git a/Code/Editor/bmp00005_08.png b/Code/Editor/bmp00005_08.png deleted file mode 100644 index b9f98ffe1c..0000000000 --- a/Code/Editor/bmp00005_08.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:804491b4251adfe017f8c52e00324dd74f00ebec445eedd947dea9356865cd56 -size 682 diff --git a/Code/Editor/bmp00005_09.png b/Code/Editor/bmp00005_09.png deleted file mode 100644 index 8650cc6a9e..0000000000 --- a/Code/Editor/bmp00005_09.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ecf6333b6b402e1834f3047b13e58e4f80e17a8eed3750017219b5694d1b6f67 -size 625 diff --git a/Code/Editor/bmp00006_00.png b/Code/Editor/bmp00006_00.png deleted file mode 100644 index c48f7ede09..0000000000 --- a/Code/Editor/bmp00006_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70724fdada9cecd5a8d7ee5211ee713accc8f9642415e5dd93b6d621ed7273cf -size 139 diff --git a/Code/Editor/bmp00006_01.png b/Code/Editor/bmp00006_01.png deleted file mode 100644 index 7fb55bc8a5..0000000000 --- a/Code/Editor/bmp00006_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d12de5789fb345c5ffe4b76246ec0ba4d7972fb14d15db3f36886f3beaed3ff -size 166 diff --git a/Code/Editor/bmp00006_02.png b/Code/Editor/bmp00006_02.png deleted file mode 100644 index 7b1ab690a3..0000000000 --- a/Code/Editor/bmp00006_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fffdbe9b4e1630f4158c4a00985e713ddb6fae50bc71e8c100255bab04054c0a -size 235 diff --git a/Code/Editor/bmp00006_03.png b/Code/Editor/bmp00006_03.png deleted file mode 100644 index 4829767efd..0000000000 --- a/Code/Editor/bmp00006_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d5e4092107dbc45863abe1cbecb30c48135e17155b5a85afa07a4a90b3eb1221 -size 274 diff --git a/Code/Editor/bmp00006_04.png b/Code/Editor/bmp00006_04.png deleted file mode 100644 index dc809b8a65..0000000000 --- a/Code/Editor/bmp00006_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc454d6cf883b78ae4cc32bfe4a81a6d5ee64e5e1bade9f2069e7e1b405ad9b1 -size 373 diff --git a/Code/Editor/bmp00006_05.png b/Code/Editor/bmp00006_05.png deleted file mode 100644 index 2f3c67fff6..0000000000 --- a/Code/Editor/bmp00006_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:359236f395259b21b75f8f3fa250dfeea9ef82b9d541c7344954cf93db5c9d47 -size 616 diff --git a/Code/Editor/bmp00006_06.png b/Code/Editor/bmp00006_06.png deleted file mode 100644 index 86c43264ea..0000000000 --- a/Code/Editor/bmp00006_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc8e5dd88bb78f4f63ba8618e2bf0c1fd74d2dbdcf48261cfa57883c476619fe -size 1101 diff --git a/Code/Editor/bmp00006_07.png b/Code/Editor/bmp00006_07.png deleted file mode 100644 index 067b20a5fb..0000000000 --- a/Code/Editor/bmp00006_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1fbfb749ecfec92f461979d15642dfb940cc7895db3d27c47d040b0a7e2a1ae4 -size 1288 diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake index 345a8e15e1..5d45bbd853 100644 --- a/Code/Editor/editor_lib_files.cmake +++ b/Code/Editor/editor_lib_files.cmake @@ -347,7 +347,6 @@ set(FILES MainStatusBar.cpp MainStatusBar.h MainStatusBarItems.h - CrtDebug.cpp CryEdit.rc CryEditDoc.cpp CryEditDoc.h @@ -358,7 +357,6 @@ set(FILES LogFile.cpp LogFile.h Resource.h - UserMessageDefines.h ActionManager.cpp ActionManager.h ShortcutDispatcher.cpp @@ -397,9 +395,6 @@ set(FILES ResizeResolutionDialog.cpp ResizeResolutionDialog.h ResizeResolutionDialog.ui - SelectEAXPresetDlg.cpp - SelectEAXPresetDlg.h - SelectEAXPresetDlg.ui SelectLightAnimationDialog.cpp SelectLightAnimationDialog.h SelectSequenceDialog.cpp @@ -421,9 +416,6 @@ set(FILES IconListDialog.ui UndoDropDown.cpp UndoDropDown.h - DimensionsDialog.cpp - DimensionsDialog.h - DimensionsDialog.ui NewLevelDialog.cpp NewLevelDialog.h NewLevelDialog.ui @@ -456,12 +448,7 @@ set(FILES ToolBox.h TrackViewNewSequenceDialog.h UndoConfigSpec.h - UndoViewPosition.h - UndoViewRotation.h Util/GeometryUtil.h - WipFeaturesDlg.h - WipFeaturesDlg.ui - WipFeaturesDlg.qrc LevelIndependentFileMan.cpp LevelIndependentFileMan.h LogFileImpl.cpp @@ -550,11 +537,6 @@ set(FILES TrackViewNewSequenceDialog.cpp TrackViewNewSequenceDialog.ui UndoConfigSpec.cpp - UndoViewPosition.cpp - UndoViewRotation.cpp - WipFeatureManager.cpp - WipFeatureManager.h - WipFeaturesDlg.cpp Dialogs/ErrorsDlg.cpp Dialogs/ErrorsDlg.h Dialogs/ErrorsDlg.ui @@ -571,8 +553,6 @@ set(FILES ProcessInfo.cpp ProcessInfo.h Report.h - SurfaceTypeValidator.cpp - SurfaceTypeValidator.h TrackView/AtomOutputFrameCapture.cpp TrackView/AtomOutputFrameCapture.h TrackView/TrackViewDialog.qrc diff --git a/Code/Editor/particles_tree_00.png b/Code/Editor/particles_tree_00.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/particles_tree_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/particles_tree_01.png b/Code/Editor/particles_tree_01.png deleted file mode 100644 index 274b2b0667..0000000000 --- a/Code/Editor/particles_tree_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9cc3783ba8ccc940e89039455f2a8617a67520400ce74c9ce4c3d16d942ead8 -size 208 diff --git a/Code/Editor/particles_tree_02.png b/Code/Editor/particles_tree_02.png deleted file mode 100644 index 96f4bec585..0000000000 --- a/Code/Editor/particles_tree_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:19b1ee36ba28ede080ef34bd13d37a8b579ad8e106089cd1b800b15aef1b58df -size 252 diff --git a/Code/Editor/particles_tree_03.png b/Code/Editor/particles_tree_03.png deleted file mode 100644 index 3ead10b3b4..0000000000 --- a/Code/Editor/particles_tree_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e6ef5e26d5d1566f51824c3bfa0ed3d2653cb49e38111aaf0572590b2fd15be -size 261 diff --git a/Code/Editor/particles_tree_04.png b/Code/Editor/particles_tree_04.png deleted file mode 100644 index 0920a2667d..0000000000 --- a/Code/Editor/particles_tree_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:acbeaa97474bd203ac35bf87fdea49d8b3d60f18db62d64dd47c3b1b50e54816 -size 303 diff --git a/Code/Editor/particles_tree_05.png b/Code/Editor/particles_tree_05.png deleted file mode 100644 index 0a4ce61ba0..0000000000 --- a/Code/Editor/particles_tree_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d92fc6ec4afc582ff5d019f5b26c48e3dbe6c5f3c753271d7918cd5ca95b8b32 -size 254 diff --git a/Code/Editor/particles_tree_06.png b/Code/Editor/particles_tree_06.png deleted file mode 100644 index e0ab042cb3..0000000000 --- a/Code/Editor/particles_tree_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02066aed1d53c3ffc53c0f844a88ba8870b6c2c9c846c47ef6443c21ce4b7d0c -size 224 diff --git a/Code/Editor/particles_tree_07.png b/Code/Editor/particles_tree_07.png deleted file mode 100644 index 2ab767a7e9..0000000000 --- a/Code/Editor/particles_tree_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:67668cc830b553605d2f9ccad57f2fcd422da6a7515cfc4e9af0f43aa8591543 -size 213 From 2a9990ead3da2a82ca9d113eaee6f272a9c11ad7 Mon Sep 17 00:00:00 2001 From: amzn-phist <52085794+amzn-phist@users.noreply.github.com> Date: Tue, 18 Jan 2022 10:27:06 -0600 Subject: [PATCH 221/272] Fix engine template issue (#6927) * fix get_enabled_gem_cmake_file to work with "Dem" or "Code" or "Gem/Code" folder in a project fix o3de_restricted_path to make the past paramter optional Signed-off-by: byrcolin * Fix resolution of variables in `cmake_path(COMPARE)` calls in PAL.cmake The documentation for `cmake_path(COMPARE)` states that parameters marked as [](https://cmake.org/cmake/help/latest/command/cmake_path.html#conventions) are string literals. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Co-authored-by: byrcolin Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- cmake/PAL.cmake | 35 ++++++++++++++++++++--------------- scripts/o3de/o3de/cmake.py | 28 ++++++++++++++++++---------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index d0d1ad5396..ef431ff92a 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -157,17 +157,17 @@ function(o3de_restricted_id o3de_json_file restricted parent_relative_path) # This object did not have a "restricted" set, now we must look at the parent # Stop if this is a top level object o3de_manifest_restricted(manifest_restricted_paths) - get_filename_component(o3de_json_file_parent ${o3de_json_file} DIRECTORY) - get_filename_component(relative_path ${o3de_json_file_parent} NAME) - get_filename_component(o3de_json_file_parent ${o3de_json_file_parent} DIRECTORY) + cmake_path(GET o3de_json_file PARENT_PATH o3de_json_file_parent) + cmake_path(GET o3de_json_file_parent FILENAME relative_path) + cmake_path(GET o3de_json_file_parent PARENT_PATH o3de_json_file_parent) if(${o3de_json_file_parent} IN_LIST manifest_restricted_paths) set(${parent_relative_path} "" PARENT_SCOPE) set(${restricted} "" PARENT_SCOPE) return() endif() - string(LENGTH ${o3de_json_file_parent} parent_len) - while(parent_len) + set(is_prev_path_segment TRUE) + while(is_prev_path_segment) if(EXISTS ${o3de_json_file_parent}/engine.json) o3de_json_restricted(${o3de_json_file_parent}/engine.json restricted_name) if(restricted_name) @@ -199,10 +199,12 @@ function(o3de_restricted_id o3de_json_file restricted parent_relative_path) return() endif() - get_filename_component(parent ${o3de_json_file_parent} NAME) - string(PREPEND relative_path ${parent}/) - get_filename_component(o3de_json_file_parent ${o3de_json_file_parent} DIRECTORY) - string(LENGTH ${o3de_json_file_parent} parent_len) + # Remove one path segment from the end of the o3de json candidate path + cmake_path(GET o3de_json_file_parent PARENT_PATH parent_path) + cmake_path(GET o3de_json_file_parent FILENAME path_segment) + cmake_path(COMPARE "${o3de_json_file_parent}" NOT_EQUAL "${parent_path}" is_prev_path_segment) + cmake_path(SET o3de_json_file_parent "${parent_path}") + cmake_path(SET relative_path "${path_segment}/${relative_path}") endwhile() endfunction() @@ -232,10 +234,13 @@ endfunction() #! o3de_restricted_path: # # \arg:o3de_json_file json file to read restricted id from -# \arg:restricted_name name of the restricted object -function(o3de_restricted_path o3de_json_file restricted_path parent_relative_path) +# \arg:restricted_path output path of the restricted object +# \arg:parent_relative_path optional output of the path relative to the parent +function(o3de_restricted_path o3de_json_file restricted_path) #parent_relative_path o3de_restricted_id(${o3de_json_file} restricted_name parent_relative) - set(${parent_relative_path} ${parent_relative} PARENT_SCOPE) + if(${ARGC} GREATER 2) + set(${ARGV2} ${parent_relative} PARENT_SCOPE) + endif() if(restricted_name) o3de_find_restricted_folder(${restricted_name} restricted_folder) if(restricted_folder) @@ -254,7 +259,7 @@ foreach(detection_file ${detection_files}) endforeach() # set the O3DE_ENGINE_RESTRICTED_PATH -o3de_restricted_path(${LY_ROOT_FOLDER}/engine.json O3DE_ENGINE_RESTRICTED_PATH engine_has_no_parent) +o3de_restricted_path(${LY_ROOT_FOLDER}/engine.json O3DE_ENGINE_RESTRICTED_PATH) # detect platforms in the restricted path file(GLOB detection_files ${O3DE_ENGINE_RESTRICTED_PATH}/*/cmake/PALDetection_*.cmake) @@ -338,7 +343,7 @@ function(o3de_pal_dir out_name in_name object_restricted_path object_path) #pare cmake_path(GET current_object_path PARENT_PATH parent_path) cmake_path(GET current_object_path FILENAME path_segment) list(PREPEND path_segments_visited ${path_segment}) - cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(COMPARE "${current_object_path}" NOT_EQUAL "${parent_path}" is_prev_path_segment) cmake_path(SET current_object_path "${parent_path}") set(is_prev_path_segment TRUE) @@ -346,7 +351,7 @@ function(o3de_pal_dir out_name in_name object_restricted_path object_path) #pare # Remove one path segment from the end of the current_object_path and prepend it to the list path_segments cmake_path(GET current_object_path PARENT_PATH parent_path) cmake_path(GET current_object_path FILENAME path_segment) - cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(COMPARE "${current_object_path}" NOT_EQUAL "${parent_path}" is_prev_path_segment) cmake_path(SET current_object_path "${parent_path}") # The Path is in a PAL structure # Decompose the path into sections before "Platform" and after "Platform" diff --git a/scripts/o3de/o3de/cmake.py b/scripts/o3de/o3de/cmake.py index ec970d06f4..7a820a9677 100644 --- a/scripts/o3de/o3de/cmake.py +++ b/scripts/o3de/o3de/cmake.py @@ -235,14 +235,22 @@ def get_enabled_gem_cmake_file(project_name: str = None, enable_gem_filename = "enabled_gems.cmake" if platform == 'Common': - project_code_dir = project_path / 'Gem/Code' - if project_code_dir.is_dir(): - dependencies_file_path = project_code_dir / enable_gem_filename - return dependencies_file_path.resolve() - return (project_path / 'Code' / enable_gem_filename).resolve() + possible_project_enable_gem_filename_paths = [ + pathlib.Path(project_path / 'Gem' / enable_gem_filename), + pathlib.Path(project_path / 'Gem/Code' / enable_gem_filename), + pathlib.Path(project_path / 'Code' / enable_gem_filename) + ] + for possible_project_enable_gem_filename_path in possible_project_enable_gem_filename_paths: + if possible_project_enable_gem_filename_path.is_file(): + return possible_project_enable_gem_filename_path.resolve() + return possible_project_enable_gem_filename_paths[0].resolve() else: - project_code_dir = project_path / 'Gem/Code/Platform' / platform - if project_code_dir.is_dir(): - dependencies_file_path = project_code_dir / enable_gem_filename - return dependencies_file_path.resolve() - return (project_path / 'Code/Platform' / platform / enable_gem_filename).resolve() + possible_project_platform_enable_gem_filename_paths = [ + pathlib.Path(project_path / 'Gem/Platform' / platform / enable_gem_filename), + pathlib.Path(project_path / 'Gem/Code/Platform' / platform / enable_gem_filename), + pathlib.Path(project_path / 'Code/Platform' / platform / enable_gem_filename) + ] + for possible_project_platform_enable_gem_filename_path in possible_project_platform_enable_gem_filename_paths: + if possible_project_platform_enable_gem_filename_path.is_file(): + return possible_project_platform_enable_gem_filename_path.resolve() + return possible_project_platform_enable_gem_filename_paths[0].resolve() From 9f25c9f6774fcb2bc92f6a5b23f227efb9c5905f Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 18 Jan 2022 11:54:29 -0600 Subject: [PATCH 222/272] Skipping ShapeIntersectionFilter test Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index 5b1e504442..af1c187817 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -131,6 +131,7 @@ class TestAutomation_PrefabNotEnabled(EditorTestSuite): class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module + @pytest.mark.skip("https://github.com/o3de/o3de/issues/6973") class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module From 7694a29fa1f4cd4d4872d8c1ccc1fc83ea9cdc63 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Tue, 18 Jan 2022 10:16:33 -0800 Subject: [PATCH 223/272] Material Editor tests for window pane function Signed-off-by: Scott Murray --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 4 +++- .../Atom/atom_utils/material_editor_utils.py | 4 ++-- .../hydra_AtomMaterialEditor_BasicTests.py | 24 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 7051b9983c..f1e66ac492 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -173,9 +173,11 @@ class TestMaterialEditorBasicTests(object): "Document saved as copy is saved with changes: True", "Document saved as child is saved with changes: True", "Save All worked as expected: True", + "P1: Asset Browser visibility working as expected: True", + "P1: Inspector visibility working as expected: True", ] unexpected_lines = [ - "Traceback (most recent call last):" + # Including any lines in unexpected_lines will cause the test to run for the duration of the timeout ] hydra.launch_and_validate_results( diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py index f7ff970541..96eeb4279e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py @@ -125,11 +125,11 @@ def is_pane_visible(pane_name): """ :return: bool """ - return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name) + return atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name) def set_pane_visibility(pane_name, value): - atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value) + atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value) def select_lighting_config(config_name): diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py index baad02318d..bd00a84919 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py @@ -36,6 +36,19 @@ MATERIAL_TYPE_PATH = os.path.join( CACHE_FILE_EXTENSION = ".azmaterial" +def verify_pane_visibility(pane_name: str): + """ + print log lines indicating Material Editor pane visibility function + :param pane_name: Name of the pane to be tested + """ + initial_value = material_editor.is_pane_visible(pane_name) + material_editor.set_pane_visibility(pane_name, not initial_value) + result = (material_editor.is_pane_visible(pane_name) is not initial_value) + material_editor.set_pane_visibility(pane_name, initial_value) + result = result and (initial_value is material_editor.is_pane_visible(pane_name)) + print(f"P1: {pane_name} visibility working as expected: {result}") + + def run(): """ Summary: @@ -49,9 +62,12 @@ def run(): 7. Saving as a New Material 8. Saving as a Child Material 9. Saving all Open Materials + 10. Verify Asset Browser pane visibility + 11. Verify Material Inspector pane visibility Expected Result: All the above functions work as expected in Material Editor. + Pane visibility functions as expected :return: None """ @@ -186,6 +202,14 @@ def run(): material_editor.set_property(document2_id, property2_name, initial_color) material_editor.save_all() material_editor.close_all_documents() + + # 10) Verify Asset Browser pane visibility + verify_pane_visibility("Asset Browser") + + # 11) Verify Material Inspector pane visibility + verify_pane_visibility("Inspector") + + # Confirm documents closed and exit Material Editor material_editor.wait_for_condition(lambda: (not material_editor.is_open(document1_id)) and (not material_editor.is_open(document2_id)) and From 626b16dbaeeb40594303fa49ad473d37684eb9b1 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 18 Jan 2022 10:27:10 -0800 Subject: [PATCH 224/272] Updating NetworkingSpawnableLibrary to only store network spawnables, instead of all spawnables Signed-off-by: Gene Walters --- .../Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp | 4 ++-- .../Code/Source/NetworkEntity/NetworkSpawnableLibrary.h | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp index f60778dbb4..7fb7bfdc39 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Multiplayer @@ -42,7 +41,8 @@ namespace Multiplayer auto enumerateCallback = [this](const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info) { - if (info.m_assetType == AZ::AzTypeInfo::Uuid()) + if (info.m_assetType == AZ::AzTypeInfo::Uuid() && + info.m_relativePath.ends_with(".network.spawnable")) { ProcessSpawnableAsset(info.m_relativePath, id); } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h index 0fc3ae07cc..469086f4cb 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h @@ -23,12 +23,15 @@ namespace Multiplayer NetworkSpawnableLibrary(); ~NetworkSpawnableLibrary(); - /// INetworkSpawnableLibrary overrides. + //! INetworkSpawnableLibrary overrides. + //! @{ + // Iterates over all assets (on-disk and in-memory) and stores any spawnables that are "network.spawnables" + // This allows us to look up network spawnable assets by name or id for later use void BuildSpawnablesList() override; void ProcessSpawnableAsset(const AZStd::string& relativePath, AZ::Data::AssetId id) override; AZ::Name GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId) override; AZ::Data::AssetId GetAssetIdByName(AZ::Name name) override; - + //! @} private: AZStd::unordered_map m_spawnables; From c5b128bec422a9ac716ac4f9164b204daabd29c3 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 17 Dec 2021 00:46:40 -0800 Subject: [PATCH 225/272] First pass at reworking and formalizing the way deferred material asset baking works. The feature basically works but needs more testing. Before, the material builder was loading the MaterialTypeAsset and doing some processing with it, but was avoiding declaring job dependencies that would cause reprocessing lots of assets when a shader or .materialtype file changes. Reading the asset data isn't safe when not declaring a job dependency (or when declaring a weak job dependency like OrderOnce which is the case here). This caused to several known bugs. The main change here is it no longer loads the MaterialTypeAsset at all; all other changes flow from there. The biggest changes (when deferred material processing is enabled) are ... 1) MaterialSourceData no longer loads MaterialTypeAsset. All it really needs is to determine whether a string is an image file reference or an enum value, which is easy to do by just looking for the "." for the extension. 2) MaterialAssetCreator no longer produces a finalized material asset. It no longer uses MaterialAssetCreatorCommon because that only produces a non-finalized MaterialAsset, which has very different needs for the SetPropertyValue function. (We could consider merging MaterialAssetCreatorCommon into MaterialTypeAssetCreator since that's the only subclass at this point). And it doesn't do any validation against the properties layout since that can be done at runtime. 3) Moved processing of enum property values from MaterialSourceData to MaterialAsset::Finalize (this was the only thing being done in the builder that actually needed to read the material type asset data). Also... - Updated the MaterialAsset class mostly to clarify and formalize the two different modes it can be in: whether it is finalized or not. - Merged the separate "IncludeMaterialPropertyNames" registry settings from MaterialConverterSystemComponent and MaterialBuilder into one "FinalizeMaterialAssets" setting used for both. - Removed MaterialSourceData::ApplyVersionUpdates. Now the flow of data is the same regardless of whether the materials are finalized by the AP or at runtime. Version updates are always applied on the MaterialAsset. - Added a validation check to MaterialTypeAssetCreator ensuring that once a property is renamed, the old name can never be used again for a new property. This assumption was already made previously, but not formalized, in that Material::FindPropertyIndex does not expect every caller to provide a version number for the material property name, also the material asset's list of raw property names was never versioned. The only way for this to be a safe assumption is to prevent reuse of old names. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../MaterialConverterSystemComponent.cpp | 8 +- .../MaterialConverterSystemComponent.h | 6 - .../RPI.Edit/Material/MaterialConverterBus.h | 4 - .../RPI.Edit/Material/MaterialSourceData.h | 21 +- .../Atom/RPI.Edit/Material/MaterialUtils.h | 5 + .../Atom/RPI.Reflect/Material/MaterialAsset.h | 53 +++-- .../Material/MaterialAssetCreator.h | 19 +- .../Material/MaterialPropertyValue.h | 4 + .../RPI.Builders/Material/MaterialBuilder.cpp | 62 ++--- .../Model/MaterialAssetBuilderComponent.cpp | 25 +- .../RPI.Edit/Material/MaterialSourceData.cpp | 220 ++++++++---------- .../RPI.Edit/Material/MaterialUtils.cpp | 15 ++ .../RPI.Reflect/Material/MaterialAsset.cpp | 139 +++++++---- .../Material/MaterialAssetCreator.cpp | 115 +++------ .../Material/MaterialTypeAssetCreator.cpp | 15 ++ .../Material/MaterialVersionUpdate.cpp | 12 +- .../Code/Source/Document/MaterialDocument.cpp | 6 - 17 files changed, 368 insertions(+), 361 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp index fd1c836b96..d5096d7a0b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.cpp @@ -28,8 +28,7 @@ namespace AZ serializeContext->Class() ->Version(2) ->Field("Enable", &MaterialConverterSettings::m_enable) - ->Field("DefaultMaterial", &MaterialConverterSettings::m_defaultMaterial) - ->Field("IncludeMaterialPropertyNames", &MaterialConverterSettings::m_includeMaterialPropertyNames); + ->Field("DefaultMaterial", &MaterialConverterSettings::m_defaultMaterial); } } @@ -70,11 +69,6 @@ namespace AZ return m_settings.m_enable; } - bool MaterialConverterSystemComponent::ShouldIncludeMaterialPropertyNames() const - { - return m_settings.m_includeMaterialPropertyNames; - } - bool MaterialConverterSystemComponent::ConvertMaterial( const AZ::SceneAPI::DataTypes::IMaterialData& materialData, RPI::MaterialSourceData& sourceData) { diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.h b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.h index 150529b474..7d95024759 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.h +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialConverterSystemComponent.h @@ -26,11 +26,6 @@ namespace AZ bool m_enable = true; AZStd::string m_defaultMaterial; - //! Sets whether to include material property names when generating material assets. If this - //! setting is true, material property name resolution and validation is deferred into load - //! time rather than at build time, allowing to break some dependencies (e.g. fbx files will no - //! longer need to be dependent on materialtype files). - bool m_includeMaterialPropertyNames = true; }; //! Atom's implementation of converting SceneAPI data into Atom's default material: StandardPBR @@ -50,7 +45,6 @@ namespace AZ // MaterialConverterBus overrides ... bool IsEnabled() const override; - bool ShouldIncludeMaterialPropertyNames() const override; bool ConvertMaterial(const AZ::SceneAPI::DataTypes::IMaterialData& materialData, RPI::MaterialSourceData& out) override; AZStd::string GetMaterialTypePath() const override; AZStd::string GetDefaultMaterialPath() const override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialConverterBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialConverterBus.h index 1807fca15e..8052fc4feb 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialConverterBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialConverterBus.h @@ -32,10 +32,6 @@ namespace AZ virtual bool IsEnabled() const = 0; - //! Returns true if material property names should be included in azmaterials. This allows unlinking of dependencies for some - //! file types to materialtype files (e.g. fbx). - virtual bool ShouldIncludeMaterialPropertyNames() const = 0; - //! Converts data from a IMaterialData object to an Atom MaterialSourceData. //! Only works when IsEnabled() is true. //! @return true if the MaterialSourceData output was populated with converted material data. diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h index 53d3072370..a5fb0214e6 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h @@ -33,6 +33,12 @@ namespace AZ class MaterialAsset; class MaterialAssetCreator; + enum MaterialAssetProcessingMode + { + PreBake, //!< all material asset processing is done in the Asset Processor, producing a finalized material asset + DeferredBake //!< some material asset processing is deferred, and the material asset is finalized at runtime after loading + }; + //! This is a simple data structure for serializing in/out material source files. class MaterialSourceData final { @@ -72,35 +78,28 @@ namespace AZ UpdatesApplied }; - //! Checks the material type version and potentially applies a series of property changes (most common are simple property renames) - //! based on the MaterialTypeAsset's version update procedure. - //! @param materialSourceFilePath Indicates the path of the .material file that the MaterialSourceData represents. Used for resolving file-relative paths. - ApplyVersionUpdatesResult ApplyVersionUpdates(AZStd::string_view materialSourceFilePath = ""); - //! Creates a MaterialAsset from the MaterialSourceData content. //! @param assetId ID for the MaterialAsset //! @param materialSourceFilePath Indicates the path of the .material file that the MaterialSourceData represents. Used for //! resolving file-relative paths. + //! @param processingMode Indicates whether to finalize the material asset using data from the MaterialTypeAsset. //! @param elevateWarnings Indicates whether to treat warnings as errors - //! @param includeMaterialPropertyNames Indicates whether to save material property names into the material asset file Outcome> CreateMaterialAsset( Data::AssetId assetId, - AZStd::string_view materialSourceFilePath = "", - bool elevateWarnings = true, - bool includeMaterialPropertyNames = true) const; + AZStd::string_view materialSourceFilePath, + MaterialAssetProcessingMode processingMode, + bool elevateWarnings = true) const; //! Creates a MaterialAsset from the MaterialSourceData content. //! @param assetId ID for the MaterialAsset //! @param materialSourceFilePath Indicates the path of the .material file that the MaterialSourceData represents. Used for //! resolving file-relative paths. //! @param elevateWarnings Indicates whether to treat warnings as errors - //! @param includeMaterialPropertyNames Indicates whether to save material property names into the material asset file //! @param sourceDependencies if not null, will be populated with a set of all of the loaded material and material type paths Outcome> CreateMaterialAssetFromSourceData( Data::AssetId assetId, AZStd::string_view materialSourceFilePath = "", bool elevateWarnings = true, - bool includeMaterialPropertyNames = true, AZStd::unordered_set* sourceDependencies = nullptr) const; private: diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h index c1183c7aa1..2fb55e5f40 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h @@ -64,6 +64,11 @@ namespace AZ void CheckForUnrecognizedJsonFields( const AZStd::string_view* acceptedFieldNames, uint32_t acceptedFieldNameCount, const rapidjson::Value& object, JsonDeserializerContext& context, JsonSerializationResult::ResultCode& result); + + //! Materials assets can either be finalized during asset-processing time or when materials are loaded at runtime. + //! Finalizing during asset processing reduces load times and obfuscates the material data. + //! Waiting to finalize at load time reduces dependencies on the material type data, resulting in fewer asset rebuilds and less time spent processing assets. + bool BuildersShouldFinalizeMaterialAssets(); } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 2a1de6debd..34e51b40af 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -105,6 +105,16 @@ namespace AZ //! Returns a layout that includes a list of MaterialPropertyDescriptors for each material property. const MaterialPropertiesLayout* GetMaterialPropertiesLayout() const; + //! Returns whether the material's properties are fully processed or not. + //! If true, property values can be accessed through GetPropertyValues(). + //! If false, property values can be accessed through GetRawPropertyValues(). + bool IsFinalized() const; + + //! If the material asset is not finalized yet, this does the final processing of m_rawPropertyValues to + //! get the material asset ready to be used. + //! Note m_materialTypeAsset must be valid before this is called. + void Finalize(); + //! Returns the list of values for all properties in this material. //! The entries in this list align with the entries in the MaterialPropertiesLayout. Each AZStd::any is guaranteed //! to have a value of type that matches the corresponding MaterialPropertyDescriptor. @@ -112,16 +122,13 @@ namespace AZ //! //! Note that even though material source data files contain only override values and inherit the rest from //! their parent material, they all get flattened at build time so every MaterialAsset has the full set of values. - AZStd::array_view GetPropertyValues() const; + const AZStd::vector& GetPropertyValues() const; + + const AZStd::vector>& GetRawPropertyValues() const; private: bool PostLoadInit() override; - //! Realigns property value and name indices with MaterialProperiesLayout by using m_propertyNames. Property names not found in the - //! MaterialPropertiesLayout are discarded, while property names not included in m_propertyNames will use the default value - //! from m_materialTypeAsset. - void RealignPropertyValuesAndNames(); - //! Checks the material type version and potentially applies a series of property changes (most common are simple property renames) //! based on the MaterialTypeAsset's version update procedure. void ApplyVersionUpdates(); @@ -146,17 +153,33 @@ namespace AZ //! Holds values for each material property, used to initialize Material instances. //! This is indexed by MaterialPropertyIndex and aligns with entries in m_materialPropertiesLayout. AZStd::vector m_propertyValues; - //! This is used to realign m_propertyValues as well as itself with MaterialPropertiesLayout when not empty. - //! If empty, this implies that m_propertyValues is aligned with the entries in m_materialPropertiesLayout. - AZStd::vector m_propertyNames; - //! The materialTypeVersion this materialAsset was based of. If the versions do not match at runtime when a - //! materialTypeAsset is loaded, an update will be performed on m_propertyNames if populated. + //! The MaterialAsset can be created in a "half-baked" state where minimal processing has been done because it does + //! not yet have access to the MaterialTypeAsset. In that case, this list will be populated with values copied from + //! the source .material file with little or no validation or other processing, and the m_propertyValues list will be empty. + //! Once a MaterialTypeAsset is available, Finalize() must be called to finish processing these values into the + //! final m_propertyValues list. + //! Note that the content of this list will remain after finalizing in order to support hot-reload of the MaterialTypeAsset. + //! The reason we use a vector instead of a map is to ensure inherited property values are applied in the right order; + //! if the material has a parent, and that parent uses an older material type version with renamed properties, then + //! m_rawPropertyValues could be holding two values for the same property under different names. The auto-rename process + //! can't be applied until the MaterialTypeAsset is available, so we have to keep the properties in the same order they + //! were originally encountered. + AZStd::vector> m_rawPropertyValues; + + //! Tracks whether Finalize() has been called, meaning m_propertyValues is populated with data matching the material type's property layout. + bool m_isFinalized = false; + + //! Tracks whether the MaterialAsset was already in a finalized state when it was loaded. + //! (This value is intentionally not serialized) + bool m_wasPreFinalized = false; + + //! The materialTypeVersion this materialAsset was based off. If the versions do not match at runtime when a + //! materialTypeAsset is loaded, automatic updates will be attempted at runtime. Note this is not needed to + //! determine which updates to apply, but simply as an optimization to ignore the update procedure when the + //! version numbers match. (We determine which updates to apply by simply checking the property name, and not + //! allowing the same name to ever be used for two different properties, see MaterialTypeAssetCreator::ValidateMaterialVersion) uint32_t m_materialTypeVersion = 1; - - //! A flag to determine if m_propertyValues needs to be aligned with MaterialPropertiesLayout. Set to true whenever - //! m_materialTypeAsset is reinitializing. - bool m_isDirty = true; }; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h index 862d98ce0c..b7b1f9705f 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h @@ -9,7 +9,6 @@ #include #include -#include namespace AZ { @@ -19,21 +18,21 @@ namespace AZ //! The MaterialAsset will be based on a MaterialTypeAsset or another MaterialAsset. //! Either way, the base provides the necessary data to define the layout //! and behavior of the material. The MaterialAsset only provides property value overrides. - class MaterialAssetCreator + //! Note however that the MaterialTypeAsset does not have to be loaded and available yet; + //! only the AssetId is required. The resulting MaterialAsset will be in a non-finalized state; + //! it must be finalized afterwards when the MaterialTypeAsset is available before it can be used. + class MaterialAssetCreator : public AssetCreator - , public MaterialAssetCreatorCommon { public: friend class MaterialSourceData; - - void Begin(const Data::AssetId& assetId, MaterialAsset& parentMaterial, bool includeMaterialPropertyNames = true); - void Begin(const Data::AssetId& assetId, MaterialTypeAsset& materialType, bool includeMaterialPropertyNames = true); + + void Begin(const Data::AssetId& assetId, const Data::Asset& materialType); bool End(Data::Asset& result); - private: - void PopulatePropertyNameList(); - - const MaterialPropertiesLayout* m_materialPropertiesLayout = nullptr; + void SetMaterialTypeVersion(uint32_t version); + + void SetPropertyValue(const Name& name, const MaterialPropertyValue& value); }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyValue.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyValue.h index 718615eb9f..79dda1d80a 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyValue.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyValue.h @@ -30,6 +30,10 @@ namespace AZ { namespace RPI { + //! This is a variant data type that represents the value of a material property. + //! For convenience, it supports all the types necessary for *both* the runtime data (MaterialAsset) as well as .material file data (MaterialSourceData). + //! For example, Instance is exclusive to the runtime data and AZStd::string is primarily for image file paths in .material files. Most other + //! data types are relevant in both contexts. class MaterialPropertyValue final { public: diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index f11b2f94ac..1b5635a1c1 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -43,17 +43,24 @@ namespace AZ const char* MaterialBuilder::JobKey = "Atom Material Builder"; + AZStd::string GetBuilderSettingsFingerprint() + { + return AZStd::string::format("[BuildersShouldFinalizeMaterialAssets=%d]", MaterialUtils::BuildersShouldFinalizeMaterialAssets()); + } + void MaterialBuilder::RegisterBuilder() { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 110; // Material version auto update feature + materialBuilderDescriptor.m_version = 111; // material dependency improvements materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); materialBuilderDescriptor.m_createJobFunction = AZStd::bind(&MaterialBuilder::CreateJobs, this, AZStd::placeholders::_1, AZStd::placeholders::_2); materialBuilderDescriptor.m_processJobFunction = AZStd::bind(&MaterialBuilder::ProcessJob, this, AZStd::placeholders::_1, AZStd::placeholders::_2); + materialBuilderDescriptor.m_analysisFingerprint = GetBuilderSettingsFingerprint(); + BusConnect(materialBuilderDescriptor.m_busId); AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, materialBuilderDescriptor); @@ -63,7 +70,7 @@ namespace AZ { BusDisconnect(); } - + bool MaterialBuilder::ReportMaterialAssetWarningsAsErrors() const { bool warningsAsErrors = false; @@ -77,15 +84,18 @@ namespace AZ //! Adds all relevant dependencies for a referenced source file, considering that the path might be relative to the original file location or a full asset path. //! This will usually include multiple source dependencies and a single job dependency, but will include only source dependencies if the file is not found. //! Note the AssetBuilderSDK::JobDependency::m_platformIdentifier will not be set by this function. The calling code must set this value before passing back - //! to the AssetBuilderSDK::CreateJobsResponse. If isOrderedOnceForMaterialTypes is true and the dependency is a .materialtype file, the job dependency type - //! will be set to JobDependencyType::OrderOnce. - void AddPossibleDependencies(AZStd::string_view currentFilePath, - AZStd::string_view referencedParentPath, + //! to the AssetBuilderSDK::CreateJobsResponse. + void AddPossibleDependencies( + const AZStd::string& currentFilePath, + const AZStd::string& referencedParentPath, const char* jobKey, - AZStd::vector& jobDependencies, - bool isOrderedOnceForMaterialTypes = false) + AZStd::vector& jobDependencies) { bool dependencyFileFound = false; + + const bool currentFileIsMaterial = AzFramework::StringFunc::Path::IsExtension(currentFilePath.c_str(), MaterialSourceData::Extension); + const bool referencedFileIsMaterialType = AzFramework::StringFunc::Path::IsExtension(referencedParentPath.c_str(), MaterialTypeSourceData::Extension); + const bool ShouldFinalizeMaterialAssets = MaterialUtils::BuildersShouldFinalizeMaterialAssets(); AZStd::vector possibleDependencies = RPI::AssetUtils::GetPossibleDepenencyPaths(currentFilePath, referencedParentPath); for (auto& file : possibleDependencies) @@ -103,9 +113,15 @@ namespace AZ AssetBuilderSDK::JobDependency jobDependency; jobDependency.m_jobKey = jobKey; jobDependency.m_sourceFile.m_sourceFileDependencyPath = file; - - const bool isMaterialTypeFile = AzFramework::StringFunc::Path::IsExtension(file.c_str(), MaterialTypeSourceData::Extension); - jobDependency.m_type = (isMaterialTypeFile && isOrderedOnceForMaterialTypes) ? AssetBuilderSDK::JobDependencyType::OrderOnce : AssetBuilderSDK::JobDependencyType::Order; + jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order; + + // If we aren't finalizing material assets, then a normal job dependency isn't needed because the MaterialTypeAsset data won't be used. + // However, we do still need at least an OrderOnce dependency to ensure the Asset Processor knows about the material type asset so the builder can get it's AssetId. + // This can significantly reduce AP processing time when a material type or its shaders are edited. + if (currentFileIsMaterial && referencedFileIsMaterialType && !ShouldFinalizeMaterialAssets) + { + jobDependency.m_type = AssetBuilderSDK::JobDependencyType::OrderOnce; + } jobDependencies.push_back(jobDependency); } @@ -156,7 +172,8 @@ namespace AZ // We'll build up this one JobDescriptor and reuse it to register each of the platforms AssetBuilderSDK::JobDescriptor outputJobDescriptor; outputJobDescriptor.m_jobKey = JobKey; - + outputJobDescriptor.m_additionalFingerprintInfo = GetBuilderSettingsFingerprint(); + // Load the file so we can detect and report dependencies. // If the file is a .materialtype, report dependencies on the .shader files. // If the file is a .material, report a dependency on the .materialtype and parent .material file @@ -233,24 +250,12 @@ namespace AZ parentMaterialPath = materialTypePath; } - // If includeMaterialPropertyNames is false, then a job dependency is needed so the material builder can validate MaterialAsset properties - // against the MaterialTypeAsset at asset build time. - // If includeMaterialPropertyNames is true, the material properties will be validated at runtime when the material is loaded, so the job dependency - // is needed only for first-time processing to set up the initial MaterialAsset. This speeds up AP processing time when a materialtype file - // is edited (e.g. 10s when editing StandardPBR.materialtype on AtomTest project from 45s). - bool includeMaterialPropertyNames = true; - if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) - { - settingsRegistry->Get(includeMaterialPropertyNames, "/O3DE/Atom/RPI/MaterialBuilder/IncludeMaterialPropertyNames"); - } - // Register dependency on the parent material source file so we can load it and use it's data to build this variant material. // Note, we don't need a direct dependency on the material type because the parent material will depend on it. AddPossibleDependencies(request.m_sourceFile, parentMaterialPath, JobKey, - outputJobDescriptor.m_jobDependencyList, - includeMaterialPropertyNames); + outputJobDescriptor.m_jobDependencyList); } } @@ -297,12 +302,9 @@ namespace AZ return {}; } - if (MaterialSourceData::ApplyVersionUpdatesResult::Failed == material.GetValue().ApplyVersionUpdates(materialSourceFilePath)) - { - return {}; - } + MaterialAssetProcessingMode processingMode = MaterialUtils::BuildersShouldFinalizeMaterialAssets() ? MaterialAssetProcessingMode::PreBake : MaterialAssetProcessingMode::DeferredBake; - auto materialAssetOutcome = material.GetValue().CreateMaterialAsset(Uuid::CreateRandom(), materialSourceFilePath, ReportMaterialAssetWarningsAsErrors()); + auto materialAssetOutcome = material.GetValue().CreateMaterialAsset(Uuid::CreateRandom(), materialSourceFilePath, processingMode, ReportMaterialAssetWarningsAsErrors()); if (!materialAssetOutcome.IsSuccess()) { return {}; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index c83761cf8e..ef251b6848 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -44,7 +45,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(5) // Set materialtype dependency to OrderOnce + ->Version(5) // <<<<< This probably is NOT the version number you want to bump. What you're looking for is MaterialAssetBuilderComponent::Reflect below ->Attribute(Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })); } } @@ -93,9 +94,11 @@ namespace AZ // material properties will be validated at runtime when the material is loaded, so the job dependency is needed only for // first-time processing to set up the initial MaterialAsset. This speeds up AP processing time when a materialtype file is // edited (e.g. 10s when editing StandardPBR.materialtype on AtomTest project from 45s). - bool includeMaterialPropertyNames = true; - RPI::MaterialConverterBus::BroadcastResult(includeMaterialPropertyNames, &RPI::MaterialConverterBus::Events::ShouldIncludeMaterialPropertyNames); - jobDependency.m_type = includeMaterialPropertyNames ? AssetBuilderSDK::JobDependencyType::OrderOnce : AssetBuilderSDK::JobDependencyType::Order; + + // If we aren't finalizing material assets, then a normal job dependency isn't needed because the MaterialTypeAsset data won't be used. + // However, we do still need at least an OrderOnce dependency to ensure the Asset Processor knows about the material type asset so the builder can get it's AssetId. + // This can significantly reduce AP processing time when a material type or its shaders are edited. + jobDependency.m_type = MaterialUtils::BuildersShouldFinalizeMaterialAssets() ? AssetBuilderSDK::JobDependencyType::OrderOnce : AssetBuilderSDK::JobDependencyType::Order; jobDependencyList.push_back(jobDependency); } @@ -108,10 +111,8 @@ namespace AZ bool conversionEnabled = false; RPI::MaterialConverterBus::BroadcastResult(conversionEnabled, &RPI::MaterialConverterBus::Events::IsEnabled); fingerprintInfo.insert(AZStd::string::format("[MaterialConverter enabled=%d]", conversionEnabled)); - - bool includeMaterialPropertyNames = true; - RPI::MaterialConverterBus::BroadcastResult(includeMaterialPropertyNames, &RPI::MaterialConverterBus::Events::ShouldIncludeMaterialPropertyNames); - fingerprintInfo.insert(AZStd::string::format("[MaterialConverter includeMaterialPropertyNames=%d]", includeMaterialPropertyNames)); + + fingerprintInfo.insert(AZStd::string::format("[BuildersShouldFinalizeMaterialAssets=%d]", MaterialUtils::BuildersShouldFinalizeMaterialAssets())); if (!conversionEnabled) { @@ -126,7 +127,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(16); // Optional material conversion + ->Version(17); // Optional material conversion } } @@ -230,9 +231,9 @@ namespace AZ } } } + + MaterialAssetProcessingMode processingMode = MaterialUtils::BuildersShouldFinalizeMaterialAssets() ? MaterialAssetProcessingMode::PreBake : MaterialAssetProcessingMode::DeferredBake; - bool includeMaterialPropertyNames = true; - RPI::MaterialConverterBus::BroadcastResult(includeMaterialPropertyNames, &RPI::MaterialConverterBus::Events::ShouldIncludeMaterialPropertyNames); // Build material assets. for (auto& itr : materialSourceDataByUid) { @@ -240,7 +241,7 @@ namespace AZ Data::AssetId assetId(sourceSceneUuid, GetMaterialAssetSubId(materialUid)); auto materialSourceData = itr.second; - Outcome> result = materialSourceData.m_data.CreateMaterialAsset(assetId, "", false, includeMaterialPropertyNames); + Outcome> result = materialSourceData.m_data.CreateMaterialAsset(assetId, "", processingMode, false); if (result.IsSuccess()) { context.m_outputMaterialsByUid[materialUid] = { result.GetValue(), materialSourceData.m_name }; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index 4351213c22..cd01544bfa 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -74,77 +74,49 @@ namespace AZ } } - MaterialSourceData::ApplyVersionUpdatesResult MaterialSourceData::ApplyVersionUpdates(AZStd::string_view materialSourceFilePath) - { - AZStd::string materialTypeFullPath = AssetUtils::ResolvePathReference(materialSourceFilePath, m_materialType); - auto materialTypeSourceDataOutcome = MaterialUtils::LoadMaterialTypeSourceData(materialTypeFullPath); - if (!materialTypeSourceDataOutcome.IsSuccess()) - { - return ApplyVersionUpdatesResult::Failed; - } - - MaterialTypeSourceData materialTypeSourceData = materialTypeSourceDataOutcome.TakeValue(); - - if (m_materialTypeVersion == materialTypeSourceData.m_version) - { - return ApplyVersionUpdatesResult::NoUpdates; - } - - bool changesWereApplied = false; - - // Note that the only kind of property update currently supported is rename... - - PropertyGroupMap newPropertyGroups; - for (auto& groupPair : m_properties) - { - PropertyMap& propertyMap = groupPair.second; - - for (auto& propertyPair : propertyMap) - { - MaterialPropertyId propertyId{groupPair.first, propertyPair.first}; - - if (materialTypeSourceData.ApplyPropertyRenames(propertyId, m_materialTypeVersion)) - { - changesWereApplied = true; - } - - newPropertyGroups[propertyId.GetGroupName().GetStringView()][propertyId.GetPropertyName().GetStringView()] = propertyPair.second; - } - } - - if (changesWereApplied) - { - m_properties = AZStd::move(newPropertyGroups); - - AZ_Warning( - "MaterialSourceData", false, - "This material is based on version '%u' of '%s', but the material type is now at version '%u'. " - "Automatic updates are available. Consider updating the .material source file: '%s'.", - m_materialTypeVersion, materialTypeFullPath.c_str(), materialTypeSourceData.m_version, materialSourceFilePath.data()); - } - - m_materialTypeVersion = materialTypeSourceData.m_version; - - return changesWereApplied ? ApplyVersionUpdatesResult::UpdatesApplied : ApplyVersionUpdatesResult::NoUpdates; - } - Outcome> MaterialSourceData::CreateMaterialAsset( - Data::AssetId assetId, AZStd::string_view materialSourceFilePath, bool elevateWarnings, bool includeMaterialPropertyNames) const + Data::AssetId assetId, AZStd::string_view materialSourceFilePath, MaterialAssetProcessingMode processingMode, bool elevateWarnings) const { MaterialAssetCreator materialAssetCreator; materialAssetCreator.SetElevateWarnings(elevateWarnings); - if (m_parentMaterial.empty()) + Outcome materialTypeAssetId = AssetUtils::MakeAssetId(materialSourceFilePath, m_materialType, 0); + if (!materialTypeAssetId) { - auto materialTypeAsset = AssetUtils::LoadAsset(materialSourceFilePath, m_materialType); - if (!materialTypeAsset.IsSuccess()) + return Failure(); + } + + Data::Asset materialTypeAsset; + + switch (processingMode) + { + case MaterialAssetProcessingMode::DeferredBake: { + // Don't load the material type data, just create a reference to it + materialTypeAsset = Data::Asset{ materialTypeAssetId.GetValue(), azrtti_typeid(), m_materialType }; + break; + } + case MaterialAssetProcessingMode::PreBake: + { + // In this case we need to load the material type data in preparation for the material->Finalize() step below. + auto materialTypeAssetOutcome = AssetUtils::LoadAsset(materialTypeAssetId.GetValue()); + if (!materialTypeAssetOutcome) + { + return Failure(); + } + materialTypeAsset = materialTypeAssetOutcome.GetValue(); + break; + } + default: + { + AZ_Assert(false, "Unhandled MaterialAssetProcessingMode"); return Failure(); } - - materialAssetCreator.Begin(assetId, *materialTypeAsset.GetValue().Get(), includeMaterialPropertyNames); } - else + + materialAssetCreator.Begin(assetId, materialTypeAsset); + + if (!m_parentMaterial.empty()) { auto parentMaterialAsset = AssetUtils::LoadAsset(materialSourceFilePath, m_parentMaterial); if (!parentMaterialAsset.IsSuccess()) @@ -154,25 +126,53 @@ namespace AZ // Make sure the parent material has the same material type { - auto materialTypeIdOutcome = AssetUtils::MakeAssetId(materialSourceFilePath, m_materialType, 0); - if (!materialTypeIdOutcome.IsSuccess()) - { - return Failure(); - } - - Data::AssetId expectedMaterialTypeId = materialTypeIdOutcome.GetValue(); - Data::AssetId parentMaterialId = parentMaterialAsset.GetValue().GetId(); - // This will only be valid if the parent material is not a material type Data::AssetId parentsMaterialTypeId = parentMaterialAsset.GetValue()->GetMaterialTypeAsset().GetId(); - if (expectedMaterialTypeId != parentMaterialId && expectedMaterialTypeId != parentsMaterialTypeId) + if (materialTypeAssetId.GetValue() != parentsMaterialTypeId) { AZ_Error("MaterialSourceData", false, "This material and its parent material do not share the same material type."); return Failure(); } } - materialAssetCreator.Begin(assetId, *parentMaterialAsset.GetValue().Get(), includeMaterialPropertyNames); + // Inherit the parent's property values... + switch (processingMode) + { + case MaterialAssetProcessingMode::DeferredBake: + { + for (auto& property : parentMaterialAsset.GetValue()->GetRawPropertyValues()) + { + materialAssetCreator.SetPropertyValue(property.first, property.second); + } + + break; + } + case MaterialAssetProcessingMode::PreBake: + { + const MaterialPropertiesLayout* propertiesLayout = parentMaterialAsset.GetValue()->GetMaterialPropertiesLayout(); + + if (parentMaterialAsset.GetValue()->GetPropertyValues().size() != propertiesLayout->GetPropertyCount()) + { + AZ_Assert(false, "The parent material should have been finalized with %zu properties but it has %zu. Something is out of sync.", + propertiesLayout->GetPropertyCount(), parentMaterialAsset.GetValue()->GetPropertyValues().size()); + return Failure(); + } + + for (size_t propertyIndex = 0; propertyIndex < propertiesLayout->GetPropertyCount(); ++propertyIndex) + { + materialAssetCreator.SetPropertyValue( + propertiesLayout->GetPropertyDescriptor(MaterialPropertyIndex{propertyIndex})->GetName(), + parentMaterialAsset.GetValue()->GetPropertyValues()[propertyIndex]); + } + + break; + } + default: + { + AZ_Assert(false, "Unhandled MaterialAssetProcessingMode"); + return Failure(); + } + } } ApplyPropertiesToAssetCreator(materialAssetCreator, materialSourceFilePath); @@ -180,6 +180,11 @@ namespace AZ Data::Asset material; if (materialAssetCreator.End(material)) { + if (processingMode == MaterialAssetProcessingMode::PreBake) + { + material->Finalize(); + } + return Success(material); } else @@ -192,7 +197,6 @@ namespace AZ Data::AssetId assetId, AZStd::string_view materialSourceFilePath, bool elevateWarnings, - bool includeMaterialPropertyNames, AZStd::unordered_set* sourceDependencies) const { const auto materialTypeSourcePath = AssetUtils::ResolvePathReference(materialSourceFilePath, m_materialType); @@ -270,7 +274,7 @@ namespace AZ // Create the material asset from all the previously loaded source data MaterialAssetCreator materialAssetCreator; materialAssetCreator.SetElevateWarnings(elevateWarnings); - materialAssetCreator.Begin(assetId, *materialTypeAsset.GetValue().Get(), includeMaterialPropertyNames); + materialAssetCreator.Begin(assetId, materialTypeAsset.GetValue()); while (!parentSourceDataStack.empty()) { @@ -283,6 +287,13 @@ namespace AZ Data::Asset material; if (materialAssetCreator.End(material)) { + // Unlike CreateMaterialAsset(), we can always finalize the material here because we loaded created the MaterialTypeAsset from + // the source .materialtype file, so the necessary data is always available. + // (In case you are wondering why we don't use CreateMaterialAssetFromSourceData in MaterialBuilder: that would require a + // source dependency between the .materialtype and .material file, which would cause all .material files to rebuild when you + // edit the .materialtype; it's faster to not read the material type data at all ... until it's needed at runtime) + material->Finalize(); + if (sourceDependencies) { sourceDependencies->insert(dependencies.begin(), dependencies.end()); @@ -306,59 +317,26 @@ namespace AZ { materialAssetCreator.ReportWarning("Source data for material property value is invalid."); } - else + else if (property.second.m_value.Is() && AzFramework::StringFunc::Contains(property.second.m_value.GetValue(), ".")) { - MaterialPropertyIndex propertyIndex = - materialAssetCreator.m_materialPropertiesLayout->FindPropertyIndex(propertyId.GetFullName()); - if (propertyIndex.IsValid()) - { - const MaterialPropertyDescriptor* propertyDescriptor = - materialAssetCreator.m_materialPropertiesLayout->GetPropertyDescriptor(propertyIndex); - switch (propertyDescriptor->GetDataType()) - { - case MaterialPropertyDataType::Image: - { - Data::Asset imageAsset; + Data::Asset imageAsset; - MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference( - imageAsset, materialSourceFilePath, property.second.m_value.GetValue()); + MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference( + imageAsset, materialSourceFilePath, property.second.m_value.GetValue()); - if (result == MaterialUtils::GetImageAssetResult::Missing) - { - materialAssetCreator.ReportWarning( - "Material property '%s': Could not find the image '%s'", propertyId.GetFullName().GetCStr(), - property.second.m_value.GetValue().data()); - } - - imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad); - materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset); - } - break; - case MaterialPropertyDataType::Enum: - { - AZ::Name enumName = AZ::Name(property.second.m_value.GetValue()); - uint32_t enumValue = propertyDescriptor->GetEnumValue(enumName); - if (enumValue == MaterialPropertyDescriptor::InvalidEnumValue) - { - materialAssetCreator.ReportError( - "Enum value '%s' couldn't be found in the 'enumValues' list", enumName.GetCStr()); - } - else - { - materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), enumValue); - } - } - break; - default: - materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), property.second.m_value); - break; - } - } - else + if (result == MaterialUtils::GetImageAssetResult::Missing) { materialAssetCreator.ReportWarning( - "Can not find property id '%s' in MaterialPropertyLayout", propertyId.GetFullName().GetStringView().data()); + "Material property '%s': Could not find the image '%s'", propertyId.GetFullName().GetCStr(), + property.second.m_value.GetValue().data()); } + + imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad); + materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset); + } + else + { + materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), property.second.m_value); } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index 7fff8d81bc..475c6ca219 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -135,6 +136,20 @@ namespace AZ } } } + + bool BuildersShouldFinalizeMaterialAssets() + { + // We default to the faster workflow for developers. Enable this registry setting when releasing the + // game for faster load times and obfuscation of material assets. + bool shouldFinalize = false; + + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + settingsRegistry->Get(shouldFinalize, "/O3DE/Atom/RPI/MaterialBuilder/FinalizeMaterialAssets"); + } + + return shouldFinalize; + } } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 3c6947b83d..7962844736 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -33,11 +33,12 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(11) // Material version update + ->Version(13) // added m_rawPropertyValues ->Field("materialTypeAsset", &MaterialAsset::m_materialTypeAsset) ->Field("materialTypeVersion", &MaterialAsset::m_materialTypeVersion) ->Field("propertyValues", &MaterialAsset::m_propertyValues) - ->Field("propertyNames", &MaterialAsset::m_propertyNames) + ->Field("rawPropertyValues", &MaterialAsset::m_rawPropertyValues) + ->Field("isFinalized", &MaterialAsset::m_isFinalized) ; } } @@ -102,32 +103,95 @@ namespace AZ { return m_materialTypeAsset->GetMaterialPropertiesLayout(); } - - AZStd::array_view MaterialAsset::GetPropertyValues() const + + bool MaterialAsset::IsFinalized() const { - // If property names are included, they are used to re-arrange the property value list to align with the - // MaterialPropertiesLayout. This realignment would be necessary if the material type is updated with - // a new property layout, and a corresponding material is not reprocessed by the AP and continues using the - // old property layout. - if (!m_propertyNames.empty()) + if (m_isFinalized) { - const uint32_t materialTypeVersion = m_materialTypeAsset->GetVersion(); - if (m_materialTypeVersion < materialTypeVersion) - { - // It is possible that the material type has had some properties renamed. If that's the case, and this material - // is still referencing the old property layout, we need to apply any auto updates to rename those properties - // before using them to realign the property values. - const_cast(this)->ApplyVersionUpdates(); - } + AZ_Assert(GetMaterialPropertiesLayout() && m_propertyValues.size() == GetMaterialPropertiesLayout()->GetPropertyCount(), "MaterialAsset is marked as Finalized but does not have the right number of property values."); + } - if (m_isDirty) + return m_isFinalized; + } + + void MaterialAsset::Finalize() + { + if (IsFinalized()) + { + return; + } + + const uint32_t materialTypeVersion = m_materialTypeAsset->GetVersion(); + if (m_materialTypeVersion < materialTypeVersion) + { + // It is possible that the material type has had some properties renamed or otherwise updated. If that's the case, + // and this material is still referencing the old property layout, we need to apply any auto updates to rename those + // properties before using them to realign the property values. + ApplyVersionUpdates(); + } + + const MaterialPropertiesLayout* propertyLayout = GetMaterialPropertiesLayout(); + + AZStd::vector finalizedPropertyValues(m_materialTypeAsset->GetDefaultPropertyValues().begin(), m_materialTypeAsset->GetDefaultPropertyValues().end()); + + for (const auto& [name, value] : m_rawPropertyValues) + { + const MaterialPropertyIndex propertyIndex = propertyLayout->FindPropertyIndex(name); + if (propertyIndex.IsValid()) { - const_cast(this)->RealignPropertyValuesAndNames(); + const MaterialPropertyDescriptor* propertyDescriptor = propertyLayout->GetPropertyDescriptor(propertyIndex); + + if (value.Is() && propertyDescriptor->GetDataType() == MaterialPropertyDataType::Enum) + { + AZ::Name enumName = AZ::Name(value.GetValue()); + uint32_t enumValue = propertyDescriptor->GetEnumValue(enumName); + if (enumValue == MaterialPropertyDescriptor::InvalidEnumValue) + { + AZ_Error(s_debugTraceName, false, "Material property name \"%s\" has invalid enum value \"%s\".", name.GetCStr(), enumName.GetCStr()); + } + else + { + finalizedPropertyValues[propertyIndex.GetIndex()] = enumValue; + } + } + else if (value.Is() && propertyDescriptor->GetDataType() == MaterialPropertyDataType::Image) + { + // Here we assume that the material asset builder resolved any image source file paths to an ImageAsset reference. + // So the only way a string could be present is if it's an empty image path reference, meaning no image should be bound. + AZ_Assert(value.GetValue().empty(), "Material property '%s' references in image '%s'. Image file paths must be resolved by the material asset builder."); + + finalizedPropertyValues[propertyIndex.GetIndex()] = Data::Asset{}; + } + else + { + finalizedPropertyValues[propertyIndex.GetIndex()] = value; + } + } + else + { + AZ_Warning(s_debugTraceName, false, "Material property name \"%s\" is not found in the material properties layout and will not be used.", name.GetCStr()); } } + m_propertyValues.swap(finalizedPropertyValues); + + m_isFinalized = true; + } + + const AZStd::vector& MaterialAsset::GetPropertyValues() const + { + // This can't be done in MaterialAssetHandler::LoadAssetData because the MaterialTypeAsset isn't necessarily loaded at that point. + // And it can't be done in PostLoadInit() because that happens on the next frame which might be too late. So we finalize just-in-time + // when properties are accessed. + const_cast(this)->Finalize(); + return m_propertyValues; } + + const AZStd::vector>& MaterialAsset::GetRawPropertyValues() const + { + return m_rawPropertyValues; + } void MaterialAsset::SetReady() { @@ -173,34 +237,6 @@ namespace AZ } } - void MaterialAsset::RealignPropertyValuesAndNames() - { - const MaterialPropertiesLayout* propertyLayout = GetMaterialPropertiesLayout(); - AZStd::vector alignedPropertyValues(m_materialTypeAsset->GetDefaultPropertyValues().begin(), m_materialTypeAsset->GetDefaultPropertyValues().end()); - for (size_t i = 0; i < m_propertyNames.size(); ++i) - { - const MaterialPropertyIndex propertyIndex = propertyLayout->FindPropertyIndex(m_propertyNames[i]); - if (propertyIndex.IsValid()) - { - alignedPropertyValues[propertyIndex.GetIndex()] = m_propertyValues[i]; - } - else - { - AZ_Warning(s_debugTraceName, false, "Material property name \"%s\" is not found in the material properties layout and will not be used.", m_propertyNames[i].GetCStr()); - } - } - m_propertyValues.swap(alignedPropertyValues); - - const size_t propertyCount = propertyLayout->GetPropertyCount(); - m_propertyNames.resize(propertyCount); - for (size_t i = 0; i < propertyCount; ++i) - { - m_propertyNames[i] = propertyLayout->GetPropertyDescriptor(MaterialPropertyIndex{ i })->GetName(); - } - - m_isDirty = false; - } - void MaterialAsset::ApplyVersionUpdates() { if (m_materialTypeVersion == m_materialTypeAsset->GetVersion()) @@ -248,7 +284,13 @@ namespace AZ // This also covers the case where just the MaterialTypeAsset is reloaded and not the MaterialAsset. m_materialTypeAsset = newMaterialTypeAsset; - m_isDirty = true; + // If the material asset was not finalized on disk, then we clear the previously finalized property values to force re-finalize. + // This + if (!m_wasPreFinalized) + { + m_isFinalized = false; + m_propertyValues.clear(); + } // Notify interested parties that this MaterialAsset is changed and may require other data to reinitialize as well MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialAssetReinitialized, Data::Asset{this, AZ::Data::AssetLoadBehavior::PreLoad}); @@ -276,6 +318,7 @@ namespace AZ if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete) { asset.GetAs()->AssetInitBus::Handler::BusConnect(); + asset.GetAs()->m_wasPreFinalized = asset.GetAs()->m_isFinalized; return Data::AssetHandler::LoadResult::LoadComplete; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp index b62a91a98d..4bee663791 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp @@ -16,89 +16,19 @@ namespace AZ { namespace RPI { - void MaterialAssetCreator::Begin(const Data::AssetId& assetId, MaterialAsset& parentMaterial, bool includeMaterialPropertyNames) - { - BeginCommon(assetId); - - if (ValidateIsReady()) - { - m_asset->m_materialTypeAsset = parentMaterial.m_materialTypeAsset; - m_asset->m_materialTypeVersion = m_asset->m_materialTypeAsset->GetVersion(); - - if (!m_asset->m_materialTypeAsset) - { - ReportError("MaterialTypeAsset is null"); - return; - } - - m_materialPropertiesLayout = m_asset->GetMaterialPropertiesLayout(); - if (!m_materialPropertiesLayout) - { - ReportError("MaterialPropertiesLayout is null"); - return; - } - if (includeMaterialPropertyNames) - { - PopulatePropertyNameList(); - } - - // Note we don't have to check the validity of these property values because the parent material's AssetCreator already did that. - m_asset->m_propertyValues.assign(parentMaterial.GetPropertyValues().begin(), parentMaterial.GetPropertyValues().end()); - - auto warningFunc = [this](const char* message) - { - ReportWarning("%s", message); - }; - auto errorFunc = [this](const char* message) - { - ReportError("%s", message); - }; - MaterialAssetCreatorCommon::OnBegin(m_materialPropertiesLayout, &(m_asset->m_propertyValues), warningFunc, errorFunc); - } - } - - void MaterialAssetCreator::Begin(const Data::AssetId& assetId, MaterialTypeAsset& materialType, bool includeMaterialPropertyNames) + void MaterialAssetCreator::Begin(const Data::AssetId& assetId, const Data::Asset& materialType) { BeginCommon(assetId); if (ValidateIsReady()) { - m_asset->m_materialTypeAsset = { &materialType, AZ::Data::AssetLoadBehavior::PreLoad }; + m_asset->m_materialTypeAsset = materialType; - if (!m_asset->m_materialTypeAsset) - { - ReportError("MaterialTypeAsset is null"); - return; - } - m_asset->m_materialTypeVersion = m_asset->m_materialTypeAsset->GetVersion(); + m_asset->m_materialTypeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); - m_materialPropertiesLayout = m_asset->GetMaterialPropertiesLayout(); - if (includeMaterialPropertyNames) - { - PopulatePropertyNameList(); - } - - if (!m_materialPropertiesLayout) - { - ReportError("MaterialPropertiesLayout is null"); - return; - } - - // Note we don't have to check the validity of these property values because the parent material's AssetCreator already did that. - m_asset->m_propertyValues.assign(materialType.GetDefaultPropertyValues().begin(), materialType.GetDefaultPropertyValues().end()); - - auto warningFunc = [this](const char* message) - { - ReportWarning("%s", message); - }; - auto errorFunc = [this](const char* message) - { - ReportError("%s", message); - }; - MaterialAssetCreatorCommon::OnBegin(m_materialPropertiesLayout, &(m_asset->m_propertyValues), warningFunc, errorFunc); } } - + bool MaterialAssetCreator::End(Data::Asset& result) { if (!ValidateIsReady()) @@ -106,20 +36,39 @@ namespace AZ return false; } - m_materialPropertiesLayout = nullptr; - MaterialAssetCreatorCommon::OnEnd(); - m_asset->SetReady(); return EndCommon(result); } - - void MaterialAssetCreator::PopulatePropertyNameList() + + void MaterialAssetCreator::SetMaterialTypeVersion(uint32_t version) { - for (int i = 0; i < m_materialPropertiesLayout->GetPropertyCount(); ++i) + if (ValidateIsReady()) { - MaterialPropertyIndex propertyIndex{ i }; - auto& propertyName = m_materialPropertiesLayout->GetPropertyDescriptor(propertyIndex)->GetName(); - m_asset->m_propertyNames.emplace_back(propertyName); + m_asset->m_materialTypeVersion = version; + } + } + + void MaterialAssetCreator::SetPropertyValue(const Name& name, const MaterialPropertyValue& value) + { + if (ValidateIsReady()) + { + // Here we are careful to keep the properties in the same order they were encountered. When the MaterialAsset + // is later finalized with a MaterialTypeAsset, there could be a version update procedure that includes renamed + // properties. So it's possible that the same property could be encountered twice but with two different names. + // Preserving the original order will ensure that the later properties still overwrite the earlier ones even after + // renames have been applied. + + auto iter = AZStd::find_if(m_asset->m_rawPropertyValues.begin(), m_asset->m_rawPropertyValues.end(), [&name](const AZStd::pair& pair) + { + return pair.first == name; + }); + + if (iter != m_asset->m_rawPropertyValues.end()) + { + m_asset->m_rawPropertyValues.erase(iter); + } + + m_asset->m_rawPropertyValues.emplace_back(name, value); } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp index 46086dfecc..dd023c56b8 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp @@ -122,6 +122,21 @@ namespace AZ return false; } + // We don't allow previously renamed property names to be reused for new properties. This would just complicate too many things, + // as every use of every property name (like in Material Component, or in scripts, for example) would have to have a version number + // associated with it, in order to know whether or which rename to apply. + for (size_t propertyIndex = 0; propertyIndex < m_asset->m_materialPropertiesLayout->GetPropertyCount(); ++propertyIndex) + { + Name originalPropertyName = m_asset->m_materialPropertiesLayout->GetPropertyDescriptor(MaterialPropertyIndex{propertyIndex})->GetName(); + Name newPropertyName = originalPropertyName; + if (versionUpdate.ApplyPropertyRenames(newPropertyName)) + { + ReportError("There was a material property named '%s' at material type version %d. This name cannot be reused for another property.", + originalPropertyName.GetCStr(), versionUpdate.GetVersion()); + return false; + } + } + prevVersion = versionUpdate.GetVersion(); } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialVersionUpdate.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialVersionUpdate.cpp index f5dfe9e80c..f12c865eee 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialVersionUpdate.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialVersionUpdate.cpp @@ -77,18 +77,14 @@ namespace AZ { bool changesWereApplied = false; - for (auto& propertyName : materialAsset.m_propertyNames) + for (auto& [name, value] : materialAsset.m_rawPropertyValues) { - for (const auto& action : m_actions) + if (ApplyPropertyRenames(name)) { - if (propertyName == action.m_fromPropertyId) - { - propertyName = action.m_toPropertyId; - changesWereApplied = true; - } + changesWereApplied = true; } } - + return changesWereApplied; } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp index 97d8d5e354..93da118b5b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp @@ -680,12 +680,6 @@ namespace MaterialEditor return false; } m_materialTypeSourceData = materialTypeOutcome.GetValue(); - - if (MaterialSourceData::ApplyVersionUpdatesResult::Failed == m_materialSourceData.ApplyVersionUpdates(m_absolutePath)) - { - AZ_Error("MaterialDocument", false, "Material source data could not be auto updated to the latest version of the material type: '%s'.", m_materialSourceData.m_materialType.c_str()); - return false; - } } else if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), MaterialTypeSourceData::Extension)) { From a627cda5aeee1c7d2714045f5b58b51b57440393 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:05:27 -0800 Subject: [PATCH 226/272] Got the unit tests working again. I made MaterialAsset::Finalize private so I could add some parameters specifically for MaterialAssetCreator to use. Now MaterialAssetCreator::Begin has an option to finalize the material or not. Moved MaterialAssetCreatorCommon::ValidateDataType to MaterialPropertyDescriptor as "ValidateMaterialPropertyDataType" so that MaterialAsset::Finalize could use it too Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Atom/RPI.Edit/Material/MaterialUtils.h | 1 + .../Include/Atom/RPI.Reflect/AssetCreator.h | 1 + .../Atom/RPI.Reflect/Material/MaterialAsset.h | 12 +- .../Material/MaterialAssetCreator.h | 24 +- .../Material/MaterialAssetCreatorCommon.h | 6 - .../Material/MaterialPropertyDescriptor.h | 5 + .../RPI.Builders/Material/MaterialBuilder.cpp | 2 +- .../Model/MaterialAssetBuilderComponent.cpp | 2 +- .../RPI.Edit/Material/MaterialSourceData.cpp | 23 +- .../RPI.Edit/Material/MaterialUtils.cpp | 1 + .../RPI.Reflect/Material/MaterialAsset.cpp | 27 +- .../Material/MaterialAssetCreator.cpp | 34 ++- .../Material/MaterialAssetCreatorCommon.cpp | 54 +--- .../Material/MaterialPropertyDescriptor.cpp | 51 ++++ .../Material/LuaMaterialFunctorTests.cpp | 8 +- .../Tests/Material/MaterialAssetTests.cpp | 166 +++++++---- .../Tests/Material/MaterialFunctorTests.cpp | 2 +- .../Material/MaterialSourceDataTests.cpp | 282 ++++-------------- .../RPI/Code/Tests/Material/MaterialTests.cpp | 22 +- 19 files changed, 333 insertions(+), 390 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h index 2fb55e5f40..2a992159b3 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h @@ -69,6 +69,7 @@ namespace AZ //! Finalizing during asset processing reduces load times and obfuscates the material data. //! Waiting to finalize at load time reduces dependencies on the material type data, resulting in fewer asset rebuilds and less time spent processing assets. bool BuildersShouldFinalizeMaterialAssets(); + } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/AssetCreator.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/AssetCreator.h index 79d43d0b8d..257abcc785 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/AssetCreator.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/AssetCreator.h @@ -28,6 +28,7 @@ namespace AZ // [GFX TODO] We need to iterate on this concept at some point. We may want to expose it through cvars or something // like that, or we may not need this at all. For now it's helpful for testing. void SetElevateWarnings(bool elevated); + bool GetElevateWarnings() const { return m_warningsElevated; } int GetErrorCount() const { return m_errorCount; } int GetWarningCount() const { return m_warningCount; } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 34e51b40af..736d7c5b53 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -110,11 +111,6 @@ namespace AZ //! If false, property values can be accessed through GetRawPropertyValues(). bool IsFinalized() const; - //! If the material asset is not finalized yet, this does the final processing of m_rawPropertyValues to - //! get the material asset ready to be used. - //! Note m_materialTypeAsset must be valid before this is called. - void Finalize(); - //! Returns the list of values for all properties in this material. //! The entries in this list align with the entries in the MaterialPropertiesLayout. Each AZStd::any is guaranteed //! to have a value of type that matches the corresponding MaterialPropertyDescriptor. @@ -129,6 +125,12 @@ namespace AZ private: bool PostLoadInit() override; + //! If the material asset is not finalized yet, this does the final processing of m_rawPropertyValues to + //! get the material asset ready to be used. + //! Note m_materialTypeAsset must be valid before this is called. + //! @param elevateWarnings Indicates whether to treat warnings as errors + void Finalize(AZStd::function reportWarning = nullptr, AZStd::function reportError = nullptr); + //! Checks the material type version and potentially applies a series of property changes (most common are simple property renames) //! based on the MaterialTypeAsset's version update procedure. void ApplyVersionUpdates(); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h index b7b1f9705f..74bd909e08 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h @@ -9,30 +9,38 @@ #include #include +#include +#include namespace AZ { namespace RPI { //! Use a MaterialAssetCreator to create and configure a new MaterialAsset. - //! The MaterialAsset will be based on a MaterialTypeAsset or another MaterialAsset. - //! Either way, the base provides the necessary data to define the layout - //! and behavior of the material. The MaterialAsset only provides property value overrides. - //! Note however that the MaterialTypeAsset does not have to be loaded and available yet; - //! only the AssetId is required. The resulting MaterialAsset will be in a non-finalized state; - //! it must be finalized afterwards when the MaterialTypeAsset is available before it can be used. + //! + //! There are two options for how to create the MaterialAsset, whether it should be finalized now or deferred. + //! - Finalized now: This requires the MaterialTypeAsset to be fully populated so it can read the property layout. + //! - Deferred finalize: This only requires the MaterialTypeAsset to have a valid AssetId; the data inside will not be used. MaterialAsset::Finalize() + //! will need to be called later when the final MaterialTypeAsset is available, presumably after loading the MaterialAsset at runtime. class MaterialAssetCreator : public AssetCreator { public: friend class MaterialSourceData; - - void Begin(const Data::AssetId& assetId, const Data::Asset& materialType); + + void Begin(const Data::AssetId& assetId, const Data::Asset& materialType, bool shouldFinalize); bool End(Data::Asset& result); void SetMaterialTypeVersion(uint32_t version); void SetPropertyValue(const Name& name, const MaterialPropertyValue& value); + + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + + private: + bool m_shouldFinalize = false; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h index 312739a0f0..c7fa9c2a4c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h @@ -52,12 +52,6 @@ namespace AZ private: bool PropertyCheck(TypeId typeId, const Name& name); - //! Returns the MaterialPropertyDataType value that corresponds to typeId - MaterialPropertyDataType GetMaterialPropertyDataType(TypeId typeId) const; - - //! Checks that the TypeId typeId matches the type expected by materialPropertyDescriptor - bool ValidateDataType(TypeId typeId, const Name& propertyName, const MaterialPropertyDescriptor* materialPropertyDescriptor); - const MaterialPropertiesLayout* m_propertyLayout = nullptr; //! Points to the m_propertyValues list in a MaterialAsset or MaterialTypeAsset AZStd::vector* m_propertyValues = nullptr; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h index 76bb2a6113..bd18c98780 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h @@ -17,6 +17,8 @@ namespace AZ { namespace RPI { + class MaterialPropertyDescriptor; + struct MaterialPropertyIndexType { AZ_TYPE_INFO(MaterialPropertyIndexType, "{cfc09268-f3f1-4474-bd8f-f2c8de27c5f1}"); }; @@ -76,6 +78,9 @@ namespace AZ const char* ToString(MaterialPropertyDataType materialPropertyDataType); AZStd::string GetMaterialPropertyDataTypeString(AZ::TypeId typeId); + + //! Checks that the TypeId matches the type expected by materialPropertyDescriptor + bool ValidateMaterialPropertyDataType(TypeId typeId, const Name& propertyName, const MaterialPropertyDescriptor* materialPropertyDescriptor, AZStd::function onError); //! A material property is any data input to a material, like a bool, float, Vector, Image, Buffer, etc. //! This descriptor defines a single input property, including it's name ID, and how it maps diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index 1b5635a1c1..3aa8728e08 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 111; // material dependency improvements + materialBuilderDescriptor.m_version = 112; // material dependency improvements materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index ef251b6848..6f71fb70d4 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -127,7 +127,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(17); // Optional material conversion + ->Version(18); // material dependency improvements } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index cd01544bfa..23657f4871 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -114,7 +114,7 @@ namespace AZ } } - materialAssetCreator.Begin(assetId, materialTypeAsset); + materialAssetCreator.Begin(assetId, materialTypeAsset, processingMode == MaterialAssetProcessingMode::PreBake); if (!m_parentMaterial.empty()) { @@ -180,11 +180,6 @@ namespace AZ Data::Asset material; if (materialAssetCreator.End(material)) { - if (processingMode == MaterialAssetProcessingMode::PreBake) - { - material->Finalize(); - } - return Success(material); } else @@ -270,11 +265,18 @@ namespace AZ parentSourceAbsPath = AssetUtils::ResolvePathReference(parentSourceAbsPath, parentSourceRelPath); parentSourceDataStack.emplace_back(AZStd::move(parentSourceData)); } + + // Unlike CreateMaterialAsset(), we can always finalize the material here because we loaded created the MaterialTypeAsset from + // the source .materialtype file, so the necessary data is always available. + // (In case you are wondering why we don't use CreateMaterialAssetFromSourceData in MaterialBuilder: that would require a + // source dependency between the .materialtype and .material file, which would cause all .material files to rebuild when you + // edit the .materialtype; it's faster to not read the material type data at all ... until it's needed at runtime) + const bool finalize = true; // Create the material asset from all the previously loaded source data MaterialAssetCreator materialAssetCreator; materialAssetCreator.SetElevateWarnings(elevateWarnings); - materialAssetCreator.Begin(assetId, materialTypeAsset.GetValue()); + materialAssetCreator.Begin(assetId, materialTypeAsset.GetValue(), finalize); while (!parentSourceDataStack.empty()) { @@ -287,13 +289,6 @@ namespace AZ Data::Asset material; if (materialAssetCreator.End(material)) { - // Unlike CreateMaterialAsset(), we can always finalize the material here because we loaded created the MaterialTypeAsset from - // the source .materialtype file, so the necessary data is always available. - // (In case you are wondering why we don't use CreateMaterialAssetFromSourceData in MaterialBuilder: that would require a - // source dependency between the .materialtype and .material file, which would cause all .material files to rebuild when you - // edit the .materialtype; it's faster to not read the material type data at all ... until it's needed at runtime) - material->Finalize(); - if (sourceDependencies) { sourceDependencies->insert(dependencies.begin(), dependencies.end()); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index 475c6ca219..2fe30f632f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -150,6 +150,7 @@ namespace AZ return shouldFinalize; } + } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 7962844736..ce5847d12f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -114,13 +114,29 @@ namespace AZ return m_isFinalized; } - void MaterialAsset::Finalize() + void MaterialAsset::Finalize(AZStd::function reportWarning, AZStd::function reportError) { if (IsFinalized()) { return; } + if (!reportWarning) + { + reportWarning = [](const char* message) + { + AZ_Warning(s_debugTraceName, false, "%s", message); + }; + } + + if (!reportError) + { + reportError = [](const char* message) + { + AZ_Error(s_debugTraceName, false, "%s", message); + }; + } + const uint32_t materialTypeVersion = m_materialTypeAsset->GetVersion(); if (m_materialTypeVersion < materialTypeVersion) { @@ -147,7 +163,7 @@ namespace AZ uint32_t enumValue = propertyDescriptor->GetEnumValue(enumName); if (enumValue == MaterialPropertyDescriptor::InvalidEnumValue) { - AZ_Error(s_debugTraceName, false, "Material property name \"%s\" has invalid enum value \"%s\".", name.GetCStr(), enumName.GetCStr()); + reportWarning(AZStd::string::format("Material property name \"%s\" has invalid enum value \"%s\".", name.GetCStr(), enumName.GetCStr()).c_str()); } else { @@ -164,12 +180,15 @@ namespace AZ } else { - finalizedPropertyValues[propertyIndex.GetIndex()] = value; + if (ValidateMaterialPropertyDataType(value.GetTypeId(), name, propertyDescriptor, reportError)) + { + finalizedPropertyValues[propertyIndex.GetIndex()] = value; + } } } else { - AZ_Warning(s_debugTraceName, false, "Material property name \"%s\" is not found in the material properties layout and will not be used.", name.GetCStr()); + reportWarning(AZStd::string::format("Material property name \"%s\" is not found in the material properties layout and will not be used.", name.GetCStr()).c_str()); } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp index 4bee663791..f05fb8d848 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp @@ -16,16 +16,21 @@ namespace AZ { namespace RPI { - void MaterialAssetCreator::Begin(const Data::AssetId& assetId, const Data::Asset& materialType) + void MaterialAssetCreator::Begin(const Data::AssetId& assetId, const Data::Asset& materialType, bool shouldFinalize) { BeginCommon(assetId); if (ValidateIsReady()) { + m_shouldFinalize = shouldFinalize; + m_asset->m_materialTypeAsset = materialType; - m_asset->m_materialTypeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); - + + if (shouldFinalize && !m_asset->m_materialTypeAsset) + { + ReportError("MaterialTypeAsset is null, the MaterialAsset cannot be finalized"); + } } } @@ -37,6 +42,14 @@ namespace AZ } m_asset->SetReady(); + + if (m_shouldFinalize) + { + m_asset->Finalize( + [this](const char* message) { ReportWarning("%s", message); }, + [this](const char* message) { ReportError("%s", message); }); + } + return EndCommon(result); } @@ -71,6 +84,21 @@ namespace AZ m_asset->m_rawPropertyValues.emplace_back(name, value); } } + + void MaterialAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + SetPropertyValue(name, MaterialPropertyValue{imageAsset}); + } + + void MaterialAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + SetPropertyValue(name, Data::Asset(imageAsset)); + } + + void MaterialAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + SetPropertyValue(name, Data::Asset(imageAsset)); + } } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp index 1ba74ce0b9..4b2f163f7c 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp @@ -7,6 +7,7 @@ */ #include +#include namespace AZ { @@ -32,57 +33,6 @@ namespace AZ m_reportError = nullptr; } - MaterialPropertyDataType MaterialAssetCreatorCommon::GetMaterialPropertyDataType(TypeId typeId) const - { - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Bool; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Int; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::UInt; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Float; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector2; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector3; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector4; } - if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Color; } - if (typeId == azrtti_typeid>()) { return MaterialPropertyDataType::Image; } - else - { - return MaterialPropertyDataType::Invalid; - } - } - - bool MaterialAssetCreatorCommon::ValidateDataType(TypeId typeId, const Name& propertyName, const MaterialPropertyDescriptor* materialPropertyDescriptor) - { - auto expectedDataType = materialPropertyDescriptor->GetDataType(); - auto actualDataType = GetMaterialPropertyDataType(typeId); - - if (expectedDataType == MaterialPropertyDataType::Enum) - { - if (actualDataType != MaterialPropertyDataType::UInt) - { - m_reportError( - AZStd::string::format("Material property '%s' is a Enum type, can only accept UInt value, input value is %s", - propertyName.GetCStr(), - ToString(actualDataType) - ).data()); - return false; - } - } - else - { - if (expectedDataType != actualDataType) - { - m_reportError( - AZStd::string::format("Material property '%s': Type mismatch. Expected %s but was %s", - propertyName.GetCStr(), - ToString(expectedDataType), - ToString(actualDataType) - ).data()); - return false; - } - } - - return true; - } - bool MaterialAssetCreatorCommon::PropertyCheck(TypeId typeId, const Name& name) { if (!m_reportWarning || !m_reportError) @@ -108,7 +58,7 @@ namespace AZ return false; } - if (!ValidateDataType(typeId, name, materialPropertyDescriptor)) + if (!ValidateMaterialPropertyDataType(typeId, name, materialPropertyDescriptor, m_reportError)) { return false; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialPropertyDescriptor.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialPropertyDescriptor.cpp index 5d0a88a6d3..ddbb902761 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialPropertyDescriptor.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialPropertyDescriptor.cpp @@ -97,6 +97,57 @@ namespace AZ return AZStd::string::format("", typeId.ToString().c_str()); } } + + bool ValidateMaterialPropertyDataType(TypeId typeId, const Name& propertyName, const MaterialPropertyDescriptor* materialPropertyDescriptor, AZStd::function onError) + { + auto toMaterialPropertyDataType = [](TypeId typeId) + { + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Bool; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Int; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::UInt; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Float; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector2; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector3; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Vector4; } + if (typeId == azrtti_typeid()) { return MaterialPropertyDataType::Color; } + if (typeId == azrtti_typeid>()) { return MaterialPropertyDataType::Image; } + else + { + return MaterialPropertyDataType::Invalid; + } + }; + + auto expectedDataType = materialPropertyDescriptor->GetDataType(); + auto actualDataType = toMaterialPropertyDataType(typeId); + + if (expectedDataType == MaterialPropertyDataType::Enum) + { + if (actualDataType != MaterialPropertyDataType::UInt) + { + onError( + AZStd::string::format("Material property '%s' is a Enum type, can only accept UInt value, input value is %s", + propertyName.GetCStr(), + ToString(actualDataType) + ).data()); + return false; + } + } + else + { + if (expectedDataType != actualDataType) + { + onError( + AZStd::string::format("Material property '%s': Type mismatch. Expected %s but was %s", + propertyName.GetCStr(), + ToString(expectedDataType), + ToString(actualDataType) + ).data()); + return false; + } + } + + return true; + } void MaterialPropertyOutputId::Reflect(ReflectContext* context) { diff --git a/Gems/Atom/RPI/Code/Tests/Material/LuaMaterialFunctorTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/LuaMaterialFunctorTests.cpp index 2608ac3a9b..5016f8303e 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/LuaMaterialFunctorTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/LuaMaterialFunctorTests.cpp @@ -112,7 +112,7 @@ namespace UnitTest Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_materialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_materialTypeAsset, true); EXPECT_TRUE(materialCreator.End(materialAsset)); m_material = Material::Create(materialAsset); @@ -138,7 +138,7 @@ namespace UnitTest Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_materialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(),m_materialTypeAsset, true); EXPECT_TRUE(materialCreator.End(materialAsset)); m_material = Material::Create(materialAsset); @@ -165,7 +165,7 @@ namespace UnitTest Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_materialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_materialTypeAsset, true); EXPECT_TRUE(materialCreator.End(materialAsset)); m_material = Material::Create(materialAsset); @@ -194,7 +194,7 @@ namespace UnitTest Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_materialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_materialTypeAsset, true); EXPECT_TRUE(materialCreator.End(materialAsset)); m_material = Material::Create(materialAsset); diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp index 58a852f176..633953cecc 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp @@ -94,7 +94,7 @@ namespace UnitTest Data::AssetId assetId(Uuid::CreateRandom()); MaterialAssetCreator creator; - creator.Begin(assetId, *m_testMaterialTypeAsset); + creator.Begin(assetId, m_testMaterialTypeAsset, true); creator.SetPropertyValue(Name{ "MyFloat2" }, Vector2{ 0.1f, 0.2f }); creator.SetPropertyValue(Name{ "MyFloat3" }, Vector3{ 1.1f, 1.2f, 1.3f }); creator.SetPropertyValue(Name{ "MyFloat4" }, Vector4{ 2.1f, 2.2f, 2.3f, 2.4f }); @@ -129,7 +129,7 @@ namespace UnitTest Data::AssetId assetId(Uuid::CreateRandom()); MaterialAssetCreator creator; - creator.Begin(assetId, *m_testMaterialTypeAsset); + creator.Begin(assetId, m_testMaterialTypeAsset, true); creator.SetPropertyValue(Name{ "MyFloat" }, 3.14f); Data::Asset materialAsset; @@ -171,7 +171,7 @@ namespace UnitTest Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *emptyMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), emptyMaterialTypeAsset, true); EXPECT_TRUE(materialCreator.End(materialAsset)); EXPECT_EQ(emptyMaterialTypeAsset, materialAsset->GetMaterialTypeAsset()); EXPECT_EQ(materialAsset->GetPropertyValues().size(), 0); @@ -189,7 +189,7 @@ namespace UnitTest Data::AssetId assetId(Uuid::CreateRandom()); MaterialAssetCreator creator; - creator.Begin(assetId, *m_testMaterialTypeAsset); + creator.Begin(assetId, m_testMaterialTypeAsset, true); creator.SetPropertyValue(Name{ "MyImage" }, streamingImageAsset); Data::Asset materialAsset; @@ -231,8 +231,8 @@ namespace UnitTest Data::AssetId assetId(Uuid::CreateRandom()); MaterialAssetCreator creator; - const bool includePropertyNames = true; - creator.Begin(assetId, *testMaterialTypeAssetV1, includePropertyNames); + const bool shouldFinalize = false; + creator.Begin(assetId, testMaterialTypeAssetV1, shouldFinalize); creator.SetPropertyValue(Name{ "MyInt" }, 7); creator.SetPropertyValue(Name{ "MyUInt" }, 8u); creator.SetPropertyValue(Name{ "MyFloat" }, 9.0f); @@ -307,26 +307,68 @@ namespace UnitTest // We use local functions to easily start a new MaterialAssetCreator for each test case because // the AssetCreator would just skip subsequent operations after the first failure is detected. - auto expectCreatorError = [this](AZStd::function passBadInput) + auto expectCreatorError = [this](const char* expectedErrorMessage, AZStd::function passBadInput) { - MaterialAssetCreator creator; - creator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + // Test with finalizing enabled + { + MaterialAssetCreator creator; + creator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); - AZ_TEST_START_ASSERTTEST; - passBadInput(creator); - AZ_TEST_STOP_ASSERTTEST(1); + ErrorMessageFinder errorMessageFinder; + errorMessageFinder.AddExpectedErrorMessage(expectedErrorMessage); + errorMessageFinder.AddIgnoredErrorMessage("Failed to build", true); - EXPECT_EQ(1, creator.GetErrorCount()); + passBadInput(creator); + + Data::Asset materialAsset; + EXPECT_FALSE(creator.End(materialAsset)); + + errorMessageFinder.CheckExpectedErrorsFound(); + + EXPECT_TRUE(creator.GetErrorCount() > 0); + } + + // Test with finalizing disabled, so no validation occurs because the MaterialTypeAsset data is not used. + { + MaterialAssetCreator creator; + creator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, false); + + passBadInput(creator); + + Data::Asset materialAsset; + EXPECT_TRUE(creator.End(materialAsset)); + + EXPECT_EQ(creator.GetErrorCount(), 0); + } }; auto expectCreatorWarning = [this](AZStd::function passBadInput) { - MaterialAssetCreator creator; - creator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + // Test with finalizing enabled + { + MaterialAssetCreator creator; + creator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); - passBadInput(creator); + passBadInput(creator); - EXPECT_EQ(1, creator.GetWarningCount()); + Data::Asset material; + creator.End(material); + + EXPECT_EQ(1, creator.GetWarningCount()); + } + + // Test with finalizing disabled, so no validation occurs because the MaterialTypeAsset data is not used. + { + MaterialAssetCreator creator; + creator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, false); + + passBadInput(creator); + + Data::Asset material; + creator.End(material); + + EXPECT_EQ(0, creator.GetWarningCount()); + } }; // Invalid input ID @@ -343,55 +385,65 @@ namespace UnitTest // Test data type mismatches... - expectCreatorError([this](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyBool" }, m_testImageAsset); - }); + expectCreatorError("Type mismatch", + [this](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyBool" }, m_testImageAsset); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyInt" }, 0.0f); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyInt" }, 0.0f); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyUInt" }, -1); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyUInt" }, -1); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat" }, 10u); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyFloat" }, 10u); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat2" }, 1.0f); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyFloat2" }, 1.0f); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat3" }, AZ::Vector4{}); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyFloat3" }, AZ::Vector4{}); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat4" }, AZ::Vector3{}); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyFloat4" }, AZ::Vector3{}); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyColor" }, MaterialPropertyValue(false)); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyColor" }, MaterialPropertyValue(false)); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyImage" }, true); - }); + expectCreatorError("Type mismatch", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyImage" }, true); + }); - expectCreatorError([](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyEnum" }, -1); - }); + expectCreatorError("can only accept UInt value", + [](MaterialAssetCreator& creator) + { + creator.SetPropertyValue(Name{ "MyEnum" }, -1); + }); } } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp index ff5d24ff9a..3373646c6e 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp @@ -275,7 +275,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialCreator.SetPropertyValue(registedPropertyName, 42); materialCreator.SetPropertyValue(unregistedPropertyName, 42); materialCreator.SetPropertyValue(unrelatedPropertyName, 42); diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index d4bf3e5eaa..73aeacf818 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -175,7 +175,7 @@ namespace UnitTest AddProperty(sourceData, "general", "MyImage", AZStd::string("@exefolder@/Temp/test.streamingimage")); AddProperty(sourceData, "general", "MyEnum", AZStd::string("Enum1")); - auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetOutcome.IsSuccess()); Data::Asset materialAsset = materialAssetOutcome.GetValue(); @@ -544,17 +544,17 @@ namespace UnitTest AddPropertyGroup(sourceDataLevel3, "general"); AddProperty(sourceDataLevel3, "general", "MyFloat", 3.5f); - auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel1.IsSuccess()); m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetValue().GetId()); - auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel2.IsSuccess()); m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetValue().GetId()); - auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel3.IsSuccess()); auto layout = m_testMaterialTypeAsset->GetMaterialPropertiesLayout(); @@ -604,18 +604,18 @@ namespace UnitTest sourceDataLevel3.m_materialType = "@exefolder@/Temp/otherBase.materialtype"; sourceDataLevel3.m_parentMaterial = "level2.material"; - auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel1.IsSuccess()); m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetValue().GetId()); - auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel2.IsSuccess()); m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetValue().GetId()); AZ_TEST_START_ASSERTTEST; - auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", true); + auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); AZ_TEST_STOP_ASSERTTEST(1); EXPECT_FALSE(materialAssetLevel3.IsSuccess()); } @@ -625,7 +625,7 @@ namespace UnitTest // We use local functions to easily start a new MaterialAssetCreator for each test case because // the AssetCreator would just skip subsequent operations after the first failure is detected. - auto expectWarning = [](AZStd::function setOneBadInput, [[maybe_unused]] uint32_t expectedAsserts = 1) + auto expectWarning = [](const char* expectedErrorMessage, AZStd::function setOneBadInput, bool warningOccursBeforeFinalize = false) { MaterialSourceData sourceData; @@ -635,233 +635,69 @@ namespace UnitTest setOneBadInput(sourceData); - AZ_TEST_START_ASSERTTEST; - auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", true); - AZ_TEST_STOP_ASSERTTEST(expectedAsserts); // Usually just one for when End() is called + // Check with MaterialAssetProcessingMode::PreBake + { + ErrorMessageFinder errorFinder; + errorFinder.AddExpectedErrorMessage(expectedErrorMessage); + errorFinder.AddIgnoredErrorMessage("Failed to build", true); + auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); + errorFinder.CheckExpectedErrorsFound(); - EXPECT_FALSE(materialAssetOutcome.IsSuccess()); + EXPECT_FALSE(materialAssetOutcome.IsSuccess()); + } + + // Check with MaterialAssetProcessingMode::DeferredBake, no validation occurs because the MaterialTypeAsset cannot be used and so the MaterialAsset is not finalized + if(!warningOccursBeforeFinalize) + { + auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); + EXPECT_TRUE(materialAssetOutcome.IsSuccess()); + } }; // Test property does not exist... - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", true); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", true); + }); - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", -10); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", -10); + }); - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", 25u); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", 25u); + }); - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", 1.5f); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", 1.5f); + }); - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", AZ::Color{ 0.1f, 0.2f, 0.3f, 0.4f }); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", AZ::Color{ 0.1f, 0.2f, 0.3f, 0.4f }); + }); - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "DoesNotExist", AZStd::string("@exefolder@/Temp/test.streamingimage")); - }); + expectWarning("\"general.DoesNotExist\" is not found in the material properties layout", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "DoesNotExist", AZStd::string("@exefolder@/Temp/test.streamingimage")); + }); // Missing image reference - expectWarning([](MaterialSourceData& materialSourceData) - { - AddProperty(materialSourceData, "general", "MyImage", AZStd::string("doesNotExist.streamingimage")); - }); - } - - - TEST_F(MaterialSourceDataTests, Load_MaterialTypeVersionUpdate) - { - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/test.materialtype", - "materialTypeVersion": 1, - "properties": { - "general": { - "testColorNameA": [0.1, 0.2, 0.3] - } - } - } - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - - // Initially, the loaded material data will match the .material file exactly. This gives us the accurate representation of - // what's actually saved on disk. - - EXPECT_NE(material.m_properties["general"].find("testColorNameA"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("testColorNameB"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("testColorNameC"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("MyColor"), material.m_properties["general"].end()); - - AZ::Color testColor = material.m_properties["general"]["testColorNameA"].m_value.GetValue(); - EXPECT_TRUE(AZ::Color(0.1f, 0.2f, 0.3f, 1.0f).IsClose(testColor, 0.01)); - - EXPECT_EQ(1, material.m_materialTypeVersion); - - // Then we force the material data to update to the latest material type version specification - ErrorMessageFinder warningFinder; // Note this finds errors and warnings, and we're looking for a warning. - warningFinder.AddExpectedErrorMessage("Automatic updates are available. Consider updating the .material source file"); - warningFinder.AddExpectedErrorMessage("This material is based on version '1'"); - warningFinder.AddExpectedErrorMessage("material type is now at version '10'"); - material.ApplyVersionUpdates(); - warningFinder.CheckExpectedErrorsFound(); - - // Now the material data should match the latest material type. - // Look for the property under the latest name in the material type, not the name used in the .material file. - - EXPECT_EQ(material.m_properties["general"].find("testColorNameA"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("testColorNameB"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("testColorNameC"), material.m_properties["general"].end()); - EXPECT_NE(material.m_properties["general"].find("MyColor"), material.m_properties["general"].end()); - - testColor = material.m_properties["general"]["MyColor"].m_value.GetValue(); - EXPECT_TRUE(AZ::Color(0.1f, 0.2f, 0.3f, 1.0f).IsClose(testColor, 0.01)); - - EXPECT_EQ(10, material.m_materialTypeVersion); - - // Calling ApplyVersionUpdates() again should not report the warning again, since the material has already been updated. - warningFinder.Reset(); - material.ApplyVersionUpdates(); - } - - TEST_F(MaterialSourceDataTests, Load_MaterialTypeVersionUpdate_MovePropertiesToAnotherGroup) - { - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/test.materialtype", - "materialTypeVersion": 3, - "properties": { - "oldGroup": { - "MyFloat": 1.2, - "MyIntOldName": 5 - } - } - } - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - - // Initially, the loaded material data will match the .material file exactly. This gives us the accurate representation of - // what's actually saved on disk. - - EXPECT_NE(material.m_properties["oldGroup"].find("MyFloat"), material.m_properties["oldGroup"].end()); - EXPECT_NE(material.m_properties["oldGroup"].find("MyIntOldName"), material.m_properties["oldGroup"].end()); - EXPECT_EQ(material.m_properties["general"].find("MyFloat"), material.m_properties["general"].end()); - EXPECT_EQ(material.m_properties["general"].find("MyInt"), material.m_properties["general"].end()); - - float myFloat = material.m_properties["oldGroup"]["MyFloat"].m_value.GetValue(); - EXPECT_EQ(myFloat, 1.2f); - - int32_t myInt = material.m_properties["oldGroup"]["MyIntOldName"].m_value.GetValue(); - EXPECT_EQ(myInt, 5); - - EXPECT_EQ(3, material.m_materialTypeVersion); - - // Then we force the material data to update to the latest material type version specification - ErrorMessageFinder warningFinder; // Note this finds errors and warnings, and we're looking for a warning. - warningFinder.AddExpectedErrorMessage("Automatic updates are available. Consider updating the .material source file"); - warningFinder.AddExpectedErrorMessage("This material is based on version '3'"); - warningFinder.AddExpectedErrorMessage("material type is now at version '10'"); - material.ApplyVersionUpdates(); - warningFinder.CheckExpectedErrorsFound(); - - // Now the material data should match the latest material type. - // Look for the property under the latest name in the material type, not the name used in the .material file. - - EXPECT_EQ(material.m_properties["oldGroup"].find("MyFloat"), material.m_properties["oldGroup"].end()); - EXPECT_EQ(material.m_properties["oldGroup"].find("MyIntOldName"), material.m_properties["oldGroup"].end()); - EXPECT_NE(material.m_properties["general"].find("MyFloat"), material.m_properties["general"].end()); - EXPECT_NE(material.m_properties["general"].find("MyInt"), material.m_properties["general"].end()); - - myFloat = material.m_properties["general"]["MyFloat"].m_value.GetValue(); - EXPECT_EQ(myFloat, 1.2f); - - myInt = material.m_properties["general"]["MyInt"].m_value.GetValue(); - EXPECT_EQ(myInt, 5); - - EXPECT_EQ(10, material.m_materialTypeVersion); - - // Calling ApplyVersionUpdates() again should not report the warning again, since the material has already been updated. - warningFinder.Reset(); - material.ApplyVersionUpdates(); - } - - TEST_F(MaterialSourceDataTests, Load_MaterialTypeVersionPartialUpdate) - { - // This case is similar to Load_MaterialTypeVersionUpdate but we start at a later - // version so only some of the version updates are applied. - - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/test.materialtype", - "materialTypeVersion": 3, - "properties": { - "general": { - "testColorNameB": [0.1, 0.2, 0.3] - } - } - } - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - - material.ApplyVersionUpdates(); - - AZ::Color testColor = material.m_properties["general"]["MyColor"].m_value.GetValue(); - EXPECT_TRUE(AZ::Color(0.1f, 0.2f, 0.3f, 1.0f).IsClose(testColor, 0.01)); - - EXPECT_EQ(10, material.m_materialTypeVersion); - } - - TEST_F(MaterialSourceDataTests, Load_Error_MaterialTypeVersionUpdateWithMismatchedVersion) - { - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/test.materialtype", - "materialTypeVersion": 3, // At this version, the property should be testColorNameB not testColorNameA - "properties": { - "general": { - "testColorNameA": [0.1, 0.2, 0.3] - } - } - } - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - loadResult.ContainsMessage("/properties/general/testColorNameA", "Property 'general.testColorNameA' not found in material type."); - - EXPECT_FALSE(material.m_properties["general"]["testColorNameA"].m_value.IsValid()); - - material.ApplyVersionUpdates(); - - EXPECT_FALSE(material.m_properties["general"]["MyColor"].m_value.IsValid()); + expectWarning("Could not find the image 'doesNotExist.streamingimage'", + [](MaterialSourceData& materialSourceData) + { + AddProperty(materialSourceData, "general", "MyImage", AZStd::string("doesNotExist.streamingimage")); + }, true); // In this case, the warning does happen even when the asset is not finalized, because the image path is checked earlier than that } } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialTests.cpp index 477978875b..569f8f6df0 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialTests.cpp @@ -85,7 +85,7 @@ namespace UnitTest m_testImage = StreamingImage::FindOrCreate(m_testImageAsset); MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialCreator.SetPropertyValue(Name{ "MyFloat2" }, Vector2{ 0.1f, 0.2f }); materialCreator.SetPropertyValue(Name{ "MyFloat3" }, Vector3{ 1.1f, 1.2f, 1.3f }); materialCreator.SetPropertyValue(Name{ "MyFloat4" }, Vector4{ 2.1f, 2.2f, 2.3f, 2.4f }); @@ -289,7 +289,7 @@ namespace UnitTest materialTypeCreator.End(materialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *materialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), materialTypeAsset, true); materialAssetCreator.End(materialAsset); Data::Instance material = Material::FindOrCreate(materialAsset); @@ -341,7 +341,7 @@ namespace UnitTest Data::Asset materialAssetWithEmptyImage; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialCreator.SetPropertyValue(Name{"MyFloat2"}, Vector2{0.1f, 0.2f}); materialCreator.SetPropertyValue(Name{"MyFloat3"}, Vector3{1.1f, 1.2f, 1.3f}); materialCreator.SetPropertyValue(Name{"MyFloat4"}, Vector4{2.1f, 2.2f, 2.3f, 2.4f}); @@ -379,7 +379,7 @@ namespace UnitTest Data::Asset emptyMaterialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *emptyMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), emptyMaterialTypeAsset, true); EXPECT_TRUE(materialCreator.End(emptyMaterialAsset)); Data::Instance material = Material::FindOrCreate(emptyMaterialAsset); @@ -450,7 +450,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialAssetCreator.End(m_testMaterialAsset); Data::Instance material = Material::FindOrCreate(m_testMaterialAsset); @@ -521,7 +521,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialAssetCreator.End(m_testMaterialAsset); Data::Instance material = Material::FindOrCreate(m_testMaterialAsset); @@ -591,7 +591,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialAssetCreator.End(m_testMaterialAsset); Data::Instance material = Material::FindOrCreate(m_testMaterialAsset); @@ -655,7 +655,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialAssetCreator.End(m_testMaterialAsset); Data::Instance material = Material::FindOrCreate(m_testMaterialAsset); @@ -669,7 +669,7 @@ namespace UnitTest { Data::Asset materialAsset; MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialCreator.SetPropertyValue(Name{ "MyFloat2" }, Vector2{ 0.1f, 0.2f }); materialCreator.SetPropertyValue(Name{ "MyFloat3" }, Vector3{ 1.1f, 1.2f, 1.3f }); materialCreator.SetPropertyValue(Name{ "MyFloat4" }, Vector4{ 2.1f, 2.2f, 2.3f, 2.4f }); @@ -778,7 +778,7 @@ namespace UnitTest materialTypeCreator.End(materialTypeAsset); MaterialAssetCreator materialAssetCreator; - materialAssetCreator.Begin(Uuid::CreateRandom(), *materialTypeAsset); + materialAssetCreator.Begin(Uuid::CreateRandom(), materialTypeAsset, true); materialAssetCreator.End(materialAsset); Data::Instance material = Material::FindOrCreate(materialAsset); @@ -859,7 +859,7 @@ namespace UnitTest materialTypeCreator.End(m_testMaterialTypeAsset); MaterialAssetCreator materialCreator; - materialCreator.Begin(Uuid::CreateRandom(), *m_testMaterialTypeAsset); + materialCreator.Begin(Uuid::CreateRandom(), m_testMaterialTypeAsset, true); materialCreator.End(m_testMaterialAsset); Data::Instance material = Material::FindOrCreate(m_testMaterialAsset); From 1fa1eaad158fae98e0339411e3fead04a6b120c9 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 28 Dec 2021 17:51:43 -0800 Subject: [PATCH 227/272] Added unit tests for the new functionality. I found a mistake where MaterialAssetCreator needs to clear the raw data when configured to finalize the material asset. Since MaterialSourceData no longer relies on the material type source file at all, I was able to change MaterialSourceDataTest to avoid saving the source data to disk. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Atom/RPI.Edit/Material/MaterialUtils.h | 1 - .../Atom/RPI.Reflect/Material/MaterialAsset.h | 1 - .../RPI.Edit/Material/MaterialUtils.cpp | 1 - .../Material/MaterialAssetCreator.cpp | 5 + .../Material/MaterialSourceDataTests.cpp | 248 ++++++++++++++++-- 5 files changed, 230 insertions(+), 26 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h index 2a992159b3..2fb55e5f40 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialUtils.h @@ -69,7 +69,6 @@ namespace AZ //! Finalizing during asset processing reduces load times and obfuscates the material data. //! Waiting to finalize at load time reduces dependencies on the material type data, resulting in fewer asset rebuilds and less time spent processing assets. bool BuildersShouldFinalizeMaterialAssets(); - } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 736d7c5b53..4cc6608225 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index 2fe30f632f..475c6ca219 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -150,7 +150,6 @@ namespace AZ return shouldFinalize; } - } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp index f05fb8d848..7d4ecf0b18 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp @@ -48,6 +48,11 @@ namespace AZ m_asset->Finalize( [this](const char* message) { ReportWarning("%s", message); }, [this](const char* message) { ReportError("%s", message); }); + + // Finalize() doesn't clear the raw property data because that's the same function used at runtime, which does need to maintain the raw data + // to support hot reload. But here we are pre-baking with the assumption that AP build dependencies will keep the material type + // and material asset in sync, so we can discard the raw property data and just rely on the data in the material type asset. + m_asset->m_rawPropertyValues.clear(); } return EndCommon(result); diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index 73aeacf818..e4d3cc9768 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -65,9 +66,29 @@ namespace UnitTest m_testShaderAsset = CreateTestShaderAsset(Uuid::CreateRandom(), m_testMaterialSrgLayout); m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.shader", m_testShaderAsset.GetId()); - // The MaterialSourceData relies on both MaterialTypeSourceData and MaterialTypeAsset. We have to make sure the - // .materialtype file is present on disk, and that the MaterialTypeAsset is available through the asset database stub... + m_testMaterialTypeAsset = CreateTestMaterialTypeAsset(Uuid::CreateRandom()); + // Since this test doesn't actually instantiate a Material, it won't need to instantiate this ImageAsset, so all we + // need is an asset reference with a valid ID. + m_testImageAsset = Data::Asset{ Data::AssetId{Uuid::CreateRandom(), StreamingImageAsset::GetImageAssetSubId()}, azrtti_typeid() }; + + // Register the test assets with the AssetSystemStub so CreateMaterialAsset() can use AssetUtils. + m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.materialtype", m_testMaterialTypeAsset.GetId()); + m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.streamingimage", m_testImageAsset.GetId()); + } + + void TearDown() override + { + m_testMaterialTypeAsset.Reset(); + m_testMaterialSrgLayout = nullptr; + m_testShaderAsset.Reset(); + m_testImageAsset.Reset(); + + RPITestFixture::TearDown(); + } + + Data::Asset CreateTestMaterialTypeAsset(Data::AssetId assetId) + { const char* materialTypeJson = R"( { "version": 10, @@ -122,29 +143,10 @@ namespace UnitTest } )"; - AZ::Utils::WriteFile(materialTypeJson, "@exefolder@/Temp/test.materialtype"); MaterialTypeSourceData materialTypeSourceData; LoadTestDataFromJson(materialTypeSourceData, materialTypeJson); - m_testMaterialTypeAsset = materialTypeSourceData.CreateMaterialTypeAsset(Uuid::CreateRandom()).TakeValue(); - - // Since this test doesn't actually instantiate a Material, it won't need to instantiate this ImageAsset, so all we - // need is an asset reference with a valid ID. - m_testImageAsset = Data::Asset{ Data::AssetId{Uuid::CreateRandom(), StreamingImageAsset::GetImageAssetSubId()}, azrtti_typeid() }; - - // Register the test assets with the AssetSystemStub so CreateMaterialAsset() can use AssetUtils. - m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.materialtype", m_testMaterialTypeAsset.GetId()); - m_assetSystemStub.RegisterSourceInfo("@exefolder@/Temp/test.streamingimage", m_testImageAsset.GetId()); - } - - void TearDown() override - { - m_testMaterialTypeAsset.Reset(); - m_testMaterialSrgLayout = nullptr; - m_testShaderAsset.Reset(); - m_testImageAsset.Reset(); - - RPITestFixture::TearDown(); + return materialTypeSourceData.CreateMaterialTypeAsset(assetId).TakeValue(); } }; @@ -180,7 +182,10 @@ namespace UnitTest Data::Asset materialAsset = materialAssetOutcome.GetValue(); - // The order here is based on the order in the MaterialTypeSourceData, as added to the the MaterialTypeAssetCreator. + EXPECT_TRUE(materialAsset->IsFinalized()); + EXPECT_EQ(0, materialAsset->GetRawPropertyValues().size()); // A pre-baked material has no need for the original raw property names and values + + // The order here is based on the order in the MaterialTypeSourceData, as added to the MaterialTypeAssetCreator. EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue(), true); EXPECT_EQ(materialAsset->GetPropertyValues()[1].GetValue(), -10); EXPECT_EQ(materialAsset->GetPropertyValues()[2].GetValue(), 25u); @@ -192,6 +197,105 @@ namespace UnitTest EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue>(), m_testImageAsset); EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue(), 1u); } + + TEST_F(MaterialSourceDataTests, CreateMaterialAsset_DeferredBake) + { + // This test is similar to CreateMaterialAsset_BasicProperties but uses MaterialAssetProcessingMode::DeferredBake instead of PreBake. + + Data::AssetId materialTypeAssetId = Uuid::CreateRandom(); + + // This material type asset will be known by the asset system (stub) but doesn't exist in the AssetManager. + // This demonstrates that the CreateMaterialAsset does not attempt to access the MaterialTypeAsset data in MaterialAssetProcessingMode::DeferredBake. + m_assetSystemStub.RegisterSourceInfo("testDeferredBake.materialtype", materialTypeAssetId); + + MaterialSourceData sourceData; + + sourceData.m_materialType = "testDeferredBake.materialtype"; + AddPropertyGroup(sourceData, "general"); + AddProperty(sourceData, "general", "MyBool" , true); + AddProperty(sourceData, "general", "MyInt" , -10); + AddProperty(sourceData, "general", "MyUInt" , 25u); + AddProperty(sourceData, "general", "MyFloat" , 1.5f); + AddProperty(sourceData, "general", "MyColor" , AZ::Color{0.1f, 0.2f, 0.3f, 0.4f}); + AddProperty(sourceData, "general", "MyFloat2", AZ::Vector2(2.1f, 2.2f)); + AddProperty(sourceData, "general", "MyFloat3", AZ::Vector3(3.1f, 3.2f, 3.3f)); + AddProperty(sourceData, "general", "MyFloat4", AZ::Vector4(4.1f, 4.2f, 4.3f, 4.4f)); + AddProperty(sourceData, "general", "MyImage" , AZStd::string("@exefolder@/Temp/test.streamingimage")); + AddProperty(sourceData, "general", "MyEnum" , AZStd::string("Enum1")); + + auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); + EXPECT_TRUE(materialAssetOutcome.IsSuccess()); + + Data::Asset materialAsset = materialAssetOutcome.GetValue(); + + EXPECT_FALSE(materialAsset->IsFinalized()); + // Note we avoid calling GetPropertyValues() because that will auto-finalize the material. We want to check its raw property values first. + + auto findRawPropertyValue = [materialAsset](const char* propertyId) + { + auto iter = AZStd::find_if(materialAsset->GetRawPropertyValues().begin(), materialAsset->GetRawPropertyValues().end(), [propertyId](const AZStd::pair& pair) + { + return pair.first == AZ::Name{propertyId}; + }); + + if (iter == materialAsset->GetRawPropertyValues().end()) + { + return MaterialPropertyValue{}; + } + else + { + return iter->second; + } + }; + + auto checkRawPropertyValues = [findRawPropertyValue, this]() + { + EXPECT_EQ(findRawPropertyValue("general.MyBool" ).GetValue(), true); + EXPECT_EQ(findRawPropertyValue("general.MyInt" ).GetValue(), -10); + EXPECT_EQ(findRawPropertyValue("general.MyUInt" ).GetValue(), 25u); + EXPECT_EQ(findRawPropertyValue("general.MyFloat" ).GetValue(), 1.5f); + EXPECT_EQ(findRawPropertyValue("general.MyFloat2").GetValue(), Vector2(2.1f, 2.2f)); + EXPECT_EQ(findRawPropertyValue("general.MyFloat3").GetValue(), Vector3(3.1f, 3.2f, 3.3f)); + EXPECT_EQ(findRawPropertyValue("general.MyFloat4").GetValue(), Vector4(4.1f, 4.2f, 4.3f, 4.4f)); + EXPECT_EQ(findRawPropertyValue("general.MyColor" ).GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); + EXPECT_EQ(findRawPropertyValue("general.MyImage" ).GetValue>(), m_testImageAsset); + // The raw value for an enum is the original string, not the numerical value, because the material type holds the necessary metadata to match the name to the value. + EXPECT_EQ(findRawPropertyValue("general.MyEnum" ).GetValue(), AZStd::string("Enum1")); + }; + + // We check the raw property values before the material type asset is even available + checkRawPropertyValues(); + + // Now we'll create the material type asset in memory so the material will have what it needs to finalize itself. + Data::Asset testMaterialTypeAsset = CreateTestMaterialTypeAsset(materialTypeAssetId); + + // The MaterialAsset is still holding an reference to an unloaded asset, so we run it through the serializer which causes the loaded MaterialAsset + // to have access to the testMaterialTypeAsset. This is similar to how the AP would save the MaterialAsset to the cache and the runtime would load it. + SerializeTester tester(GetSerializeContext()); + tester.SerializeOut(materialAsset.Get()); + materialAsset = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); + + // We check the raw property values again on the loaded data, showing that the same data is available in the original un-finalized state. + checkRawPropertyValues(); + + // The material will automatically finalize itself when the properties are accessed. + EXPECT_FALSE(materialAsset->IsFinalized()); + materialAsset->GetPropertyValues(); + EXPECT_TRUE(materialAsset->IsFinalized()); + + // Now all the property values should be available through the main GetPropertyValues() API. + EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue(), true); + EXPECT_EQ(materialAsset->GetPropertyValues()[1].GetValue(), -10); + EXPECT_EQ(materialAsset->GetPropertyValues()[2].GetValue(), 25u); + EXPECT_EQ(materialAsset->GetPropertyValues()[3].GetValue(), 1.5f); + EXPECT_EQ(materialAsset->GetPropertyValues()[4].GetValue(), Vector2(2.1f, 2.2f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[5].GetValue(), Vector3(3.1f, 3.2f, 3.3f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[6].GetValue(), Vector4(4.1f, 4.2f, 4.3f, 4.4f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[7].GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue>(), m_testImageAsset); + EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue(), 1u); + + } void CheckEqual(MaterialSourceData& a, MaterialSourceData& b) { @@ -546,16 +650,19 @@ namespace UnitTest auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel1.IsSuccess()); + EXPECT_TRUE(materialAssetLevel1.GetValue()->IsFinalized()); m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetValue().GetId()); auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel2.IsSuccess()); + EXPECT_TRUE(materialAssetLevel2.GetValue()->IsFinalized()); m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetValue().GetId()); auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel3.IsSuccess()); + EXPECT_TRUE(materialAssetLevel3.GetValue()->IsFinalized()); auto layout = m_testMaterialTypeAsset->GetMaterialPropertiesLayout(); MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat")); @@ -582,6 +689,101 @@ namespace UnitTest EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); } + + TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance_DeferredBake) + { + // This test is similar to CreateMaterialAsset_MultiLevelDataInheritance but uses MaterialAssetProcessingMode::DeferredBake instead of PreBake. + + Data::AssetId materialTypeAssetId = Uuid::CreateRandom(); + + // This material type asset will be known by the asset system (stub) but doesn't exist in the AssetManager. + // This demonstrates that the CreateMaterialAsset does not attempt to access the MaterialTypeAsset data in MaterialAssetProcessingMode::DeferredBake. + m_assetSystemStub.RegisterSourceInfo("testDeferredBake.materialtype", materialTypeAssetId); + + MaterialSourceData sourceDataLevel1; + sourceDataLevel1.m_materialType = "testDeferredBake.materialtype"; + AddPropertyGroup(sourceDataLevel1, "general"); + AddProperty(sourceDataLevel1, "general", "MyFloat", 1.5f); + AddProperty(sourceDataLevel1, "general", "MyColor", AZ::Color{0.1f, 0.2f, 0.3f, 0.4f}); + + MaterialSourceData sourceDataLevel2; + sourceDataLevel2.m_materialType = "testDeferredBake.materialtype"; + sourceDataLevel2.m_parentMaterial = "level1.material"; + AddPropertyGroup(sourceDataLevel2, "general"); + AddProperty(sourceDataLevel2, "general", "MyColor", AZ::Color{0.15f, 0.25f, 0.35f, 0.45f}); + AddProperty(sourceDataLevel2, "general", "MyFloat2", AZ::Vector2{4.1f, 4.2f}); + + MaterialSourceData sourceDataLevel3; + sourceDataLevel3.m_materialType = "testDeferredBake.materialtype"; + sourceDataLevel3.m_parentMaterial = "level2.material"; + AddPropertyGroup(sourceDataLevel3, "general"); + AddProperty(sourceDataLevel3, "general", "MyFloat", 3.5f); + + auto materialAssetLevel1Result = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); + EXPECT_TRUE(materialAssetLevel1Result.IsSuccess()); + Data::Asset materialAssetLevel1 = materialAssetLevel1Result.TakeValue(); + EXPECT_FALSE(materialAssetLevel1->IsFinalized()); + + m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetId()); + + auto materialAssetLevel2Result = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); + EXPECT_TRUE(materialAssetLevel2Result.IsSuccess()); + Data::Asset materialAssetLevel2 = materialAssetLevel2Result.TakeValue(); + EXPECT_FALSE(materialAssetLevel2->IsFinalized()); + + m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetId()); + + auto materialAssetLevel3Result = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); + EXPECT_TRUE(materialAssetLevel3Result.IsSuccess()); + Data::Asset materialAssetLevel3 = materialAssetLevel3Result.TakeValue(); + EXPECT_FALSE(materialAssetLevel3->IsFinalized()); + + // Now we'll create the material type asset in memory so the materials will have what they need to finalize. + Data::Asset testMaterialTypeAsset = CreateTestMaterialTypeAsset(materialTypeAssetId); + + auto layout = testMaterialTypeAsset->GetMaterialPropertiesLayout(); + MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat")); + MaterialPropertyIndex myFloat2 = layout->FindPropertyIndex(Name("general.MyFloat2")); + MaterialPropertyIndex myColor = layout->FindPropertyIndex(Name("general.MyColor")); + + + // The MaterialAsset is still holding an reference to an unloaded asset, so we run it through the serializer which causes the loaded MaterialAsset + // to have access to the testMaterialTypeAsset. This is similar to how the AP would save the MaterialAsset to the cache and the runtime would load it. + SerializeTester tester(GetSerializeContext()); + tester.SerializeOut(materialAssetLevel1.Get()); + materialAssetLevel1 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); + tester.SerializeOut(materialAssetLevel2.Get()); + materialAssetLevel2 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); + tester.SerializeOut(materialAssetLevel3.Get()); + materialAssetLevel3 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); + + + // The properties will finalize automatically when we call GetPropertyValues()... + + AZStd::array_view properties; + + // Check level 1 properties + properties = materialAssetLevel1->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(0.0f, 0.0f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); + + // Check level 2 properties + properties = materialAssetLevel2->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 1.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + + // Check level 3 properties + properties = materialAssetLevel3->GetPropertyValues(); + EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 3.5f); + EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); + EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); + + EXPECT_TRUE(materialAssetLevel1->IsFinalized()); + EXPECT_TRUE(materialAssetLevel2->IsFinalized()); + EXPECT_TRUE(materialAssetLevel3->IsFinalized()); + } TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance_Error_MaterialTypesDontMatch) { From 4ade6bc88a2432a0073c2edf521d6c8ab5cf0716 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 28 Dec 2021 17:52:13 -0800 Subject: [PATCH 228/272] Fixed compile errors in Material Editor. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../MaterialEditor/Code/Source/Document/MaterialDocument.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp index 93da118b5b..641d586ea7 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.cpp @@ -713,7 +713,7 @@ namespace MaterialEditor // Long term, the material document should not be concerned with assets at all. The viewport window should be the // only thing concerned with assets or instances. auto materialAssetResult = - m_materialSourceData.CreateMaterialAssetFromSourceData(Uuid::CreateRandom(), m_absolutePath, elevateWarnings, true, &m_sourceDependencies); + m_materialSourceData.CreateMaterialAssetFromSourceData(Uuid::CreateRandom(), m_absolutePath, elevateWarnings, &m_sourceDependencies); if (!materialAssetResult) { AZ_Error("MaterialDocument", false, "Material asset could not be created from source data: '%s'.", m_absolutePath.c_str()); @@ -753,7 +753,7 @@ namespace MaterialEditor } auto parentMaterialAssetResult = parentMaterialSourceData.CreateMaterialAssetFromSourceData( - parentMaterialAssetIdResult.GetValue(), m_materialSourceData.m_parentMaterial, true, true); + parentMaterialAssetIdResult.GetValue(), m_materialSourceData.m_parentMaterial, true); if (!parentMaterialAssetResult) { AZ_Error("MaterialDocument", false, "Material parent asset could not be created from source data: '%s'.", m_materialSourceData.m_parentMaterial.c_str()); From aafd34679af77484c949744964de6eb3fc6a4fb5 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Thu, 13 Jan 2022 12:48:32 -0800 Subject: [PATCH 229/272] Merged MaterialAssetCreatorCommon class into MaterialTypeAssetCreator because it is no longer needed for MaterialAssetCreator. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Material/MaterialAssetCreatorCommon.h | 64 ------------- .../RPI.Reflect/Material/MaterialTypeAsset.h | 1 - .../Material/MaterialTypeAssetCreator.h | 14 ++- .../RPI.Builders/Material/MaterialBuilder.cpp | 6 +- .../Model/MaterialAssetBuilderComponent.cpp | 2 +- .../Material/MaterialAssetCreatorCommon.cpp | 93 ------------------- .../Material/MaterialTypeAssetCreator.cpp | 61 +++++++++--- .../RPI/Code/atom_rpi_reflect_files.cmake | 2 - 8 files changed, 63 insertions(+), 180 deletions(-) delete mode 100644 Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h delete mode 100644 Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h deleted file mode 100644 index c7fa9c2a4c..0000000000 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include -#include -#include -#include -#include - -// These classes are not directly referenced in this header only because the SetPropertyValue() -// function is templatized. But the API is still specific to these data types so we include them here. -#include -#include -#include -#include - -namespace AZ -{ - namespace RPI - { - class StreamingImageAsset; - class AttachmentImageAsset; - - //! Provides common functionality to both MaterialTypeAssetCreator and MaterialAssetCreator. - class MaterialAssetCreatorCommon - { - public: - void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); - void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); - void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); - - //! Sets a property value using data in AZStd::variant-based MaterialPropertyValue. The contained data must match - //! the data type of the property. For type Image, the value must be a Data::Asset. - void SetPropertyValue(const Name& name, const MaterialPropertyValue& value); - - protected: - MaterialAssetCreatorCommon() = default; - - void OnBegin( - const MaterialPropertiesLayout* propertyLayout, - AZStd::vector* propertyValues, - const AZStd::function& warningFunc, - const AZStd::function& errorFunc); - void OnEnd(); - - private: - bool PropertyCheck(TypeId typeId, const Name& name); - - const MaterialPropertiesLayout* m_propertyLayout = nullptr; - //! Points to the m_propertyValues list in a MaterialAsset or MaterialTypeAsset - AZStd::vector* m_propertyValues = nullptr; - - AZStd::function m_reportWarning = nullptr; - AZStd::function m_reportError = nullptr; - }; - - } // namespace RPI -} // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAsset.h index f194d84263..9065b17254 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAsset.h @@ -54,7 +54,6 @@ namespace AZ { friend class MaterialTypeAssetCreator; friend class MaterialTypeAssetHandler; - friend class MaterialAssetCreatorCommon; public: AZ_RTTI(MaterialTypeAsset, "{CD7803AB-9C4C-4A33-9A14-7412F1665464}", AZ::Data::AssetData); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAssetCreator.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAssetCreator.h index 5e5f94da6d..6bd84b5546 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAssetCreator.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialTypeAssetCreator.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include @@ -27,7 +26,6 @@ namespace AZ //! which provides the MaterialTypeAsset and default property values. class MaterialTypeAssetCreator : public AssetCreator - , public MaterialAssetCreatorCommon { public: //! Begin creating a MaterialTypeAsset @@ -71,6 +69,14 @@ namespace AZ //! Finishes creating a material property. void EndMaterialProperty(); + + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + void SetPropertyValue(const Name& name, const Data::Asset& imageAsset); + + //! Sets a property value using data in AZStd::variant-based MaterialPropertyValue. The contained data must match + //! the data type of the property. For type Image, the value must be a Data::Asset. + void SetPropertyValue(const Name& name, const MaterialPropertyValue& value); //! Adds a MaterialFunctor. //! Material functors provide custom logic and calculations to configure shaders, render states, and more.See MaterialFunctor.h for details. @@ -101,7 +107,9 @@ namespace AZ private: void AddMaterialProperty(MaterialPropertyDescriptor&& materialProperty); - + + bool PropertyCheck(TypeId typeId, const Name& name); + //! The material type holds references to shader assets that contain SRGs that are supposed to be the same across all passes in the material. //! This function searches for an SRG given a @bindingSlot. If a valid one is found it makes sure it is the same across all shaders //! and records in srgShaderIndexToUpdate the index of the ShaderAsset in the ShaderCollection where it was found. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index 3aa8728e08..6e50e58dd3 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 112; // material dependency improvements + materialBuilderDescriptor.m_version = 113; // material dependency improvements materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); @@ -95,7 +95,7 @@ namespace AZ const bool currentFileIsMaterial = AzFramework::StringFunc::Path::IsExtension(currentFilePath.c_str(), MaterialSourceData::Extension); const bool referencedFileIsMaterialType = AzFramework::StringFunc::Path::IsExtension(referencedParentPath.c_str(), MaterialTypeSourceData::Extension); - const bool ShouldFinalizeMaterialAssets = MaterialUtils::BuildersShouldFinalizeMaterialAssets(); + const bool shouldFinalizeMaterialAssets = MaterialUtils::BuildersShouldFinalizeMaterialAssets(); AZStd::vector possibleDependencies = RPI::AssetUtils::GetPossibleDepenencyPaths(currentFilePath, referencedParentPath); for (auto& file : possibleDependencies) @@ -118,7 +118,7 @@ namespace AZ // If we aren't finalizing material assets, then a normal job dependency isn't needed because the MaterialTypeAsset data won't be used. // However, we do still need at least an OrderOnce dependency to ensure the Asset Processor knows about the material type asset so the builder can get it's AssetId. // This can significantly reduce AP processing time when a material type or its shaders are edited. - if (currentFileIsMaterial && referencedFileIsMaterialType && !ShouldFinalizeMaterialAssets) + if (currentFileIsMaterial && referencedFileIsMaterialType && !shouldFinalizeMaterialAssets) { jobDependency.m_type = AssetBuilderSDK::JobDependencyType::OrderOnce; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index 6f71fb70d4..1cc1925564 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -127,7 +127,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(18); // material dependency improvements + ->Version(19); // material dependency improvements } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp deleted file mode 100644 index 4b2f163f7c..0000000000 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -namespace AZ -{ - namespace RPI - { - void MaterialAssetCreatorCommon::OnBegin( - const MaterialPropertiesLayout* propertyLayout, - AZStd::vector* propertyValues, - const AZStd::function& warningFunc, - const AZStd::function& errorFunc) - { - m_propertyLayout = propertyLayout; - m_propertyValues = propertyValues; - m_reportWarning = warningFunc; - m_reportError = errorFunc; - } - - void MaterialAssetCreatorCommon::OnEnd() - { - m_propertyLayout = nullptr; - m_propertyValues = nullptr; - m_reportWarning = nullptr; - m_reportError = nullptr; - } - - bool MaterialAssetCreatorCommon::PropertyCheck(TypeId typeId, const Name& name) - { - if (!m_reportWarning || !m_reportError) - { - AZ_Assert(false, "Call Begin() on the AssetCreator before using it."); - return false; - } - - MaterialPropertyIndex propertyIndex = m_propertyLayout->FindPropertyIndex(name); - if (!propertyIndex.IsValid()) - { - m_reportWarning( - AZStd::string::format("Material property '%s' not found", - name.GetCStr() - ).data()); - return false; - } - - const MaterialPropertyDescriptor* materialPropertyDescriptor = m_propertyLayout->GetPropertyDescriptor(propertyIndex); - if (!materialPropertyDescriptor) - { - m_reportError("A material property index was found but the property descriptor was null"); - return false; - } - - if (!ValidateMaterialPropertyDataType(typeId, name, materialPropertyDescriptor, m_reportError)) - { - return false; - } - - return true; - } - - void MaterialAssetCreatorCommon::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) - { - return SetPropertyValue(name, MaterialPropertyValue(imageAsset)); - } - - void MaterialAssetCreatorCommon::SetPropertyValue(const Name& name, const MaterialPropertyValue& value) - { - if (PropertyCheck(value.GetTypeId(), name)) - { - MaterialPropertyIndex propertyIndex = m_propertyLayout->FindPropertyIndex(name); - (*m_propertyValues)[propertyIndex.GetIndex()] = value; - } - } - - void MaterialAssetCreatorCommon::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) - { - SetPropertyValue(name, Data::Asset(imageAsset)); - } - - void MaterialAssetCreatorCommon::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) - { - SetPropertyValue(name, Data::Asset(imageAsset)); - } - } // namespace RPI -} // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp index dd023c56b8..6746b57740 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialTypeAssetCreator.cpp @@ -22,17 +22,6 @@ namespace AZ { m_materialPropertiesLayout = aznew MaterialPropertiesLayout; m_asset->m_materialPropertiesLayout = m_materialPropertiesLayout; - - auto warningFunc = [this](const char* message) - { - ReportWarning("%s", message); - }; - auto errorFunc = [this](const char* message) - { - ReportError("%s", message); - }; - // Set empty for UV names as material type asset doesn't have overrides. - MaterialAssetCreatorCommon::OnBegin(m_materialPropertiesLayout, &(m_asset->m_propertyValues), warningFunc, errorFunc); } } @@ -48,8 +37,6 @@ namespace AZ m_materialShaderResourceGroupLayout = nullptr; m_materialPropertiesLayout = nullptr; - MaterialAssetCreatorCommon::OnEnd(); - return EndCommon(result); } @@ -499,6 +486,54 @@ namespace AZ m_wipMaterialProperty = MaterialPropertyDescriptor{}; } + + bool MaterialTypeAssetCreator::PropertyCheck(TypeId typeId, const Name& name) + { + MaterialPropertyIndex propertyIndex = m_materialPropertiesLayout->FindPropertyIndex(name); + if (!propertyIndex.IsValid()) + { + ReportWarning("Material property '%s' not found", name.GetCStr()); + return false; + } + + const MaterialPropertyDescriptor* materialPropertyDescriptor = m_materialPropertiesLayout->GetPropertyDescriptor(propertyIndex); + if (!materialPropertyDescriptor) + { + ReportError("A material property index was found but the property descriptor was null"); + return false; + } + + if (!ValidateMaterialPropertyDataType(typeId, name, materialPropertyDescriptor, [this](const char* message){ReportError("%s", message);})) + { + return false; + } + + return true; + } + + void MaterialTypeAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + return SetPropertyValue(name, MaterialPropertyValue(imageAsset)); + } + + void MaterialTypeAssetCreator::SetPropertyValue(const Name& name, const MaterialPropertyValue& value) + { + if (PropertyCheck(value.GetTypeId(), name)) + { + MaterialPropertyIndex propertyIndex = m_materialPropertiesLayout->FindPropertyIndex(name); + m_asset->m_propertyValues[propertyIndex.GetIndex()] = value; + } + } + + void MaterialTypeAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + SetPropertyValue(name, Data::Asset(imageAsset)); + } + + void MaterialTypeAssetCreator::SetPropertyValue(const Name& name, const Data::Asset& imageAsset) + { + SetPropertyValue(name, Data::Asset(imageAsset)); + } void MaterialTypeAssetCreator::AddMaterialFunctor(const Ptr& functor) { diff --git a/Gems/Atom/RPI/Code/atom_rpi_reflect_files.cmake b/Gems/Atom/RPI/Code/atom_rpi_reflect_files.cmake index df8f389c37..6e9cdfeb4e 100644 --- a/Gems/Atom/RPI/Code/atom_rpi_reflect_files.cmake +++ b/Gems/Atom/RPI/Code/atom_rpi_reflect_files.cmake @@ -51,7 +51,6 @@ set(FILES Include/Atom/RPI.Reflect/Image/StreamingImagePoolAssetCreator.h Include/Atom/RPI.Reflect/Material/LuaMaterialFunctor.h Include/Atom/RPI.Reflect/Material/MaterialAsset.h - Include/Atom/RPI.Reflect/Material/MaterialAssetCreatorCommon.h Include/Atom/RPI.Reflect/Material/MaterialAssetCreator.h Include/Atom/RPI.Reflect/Material/MaterialDynamicMetadata.h Include/Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h @@ -133,7 +132,6 @@ set(FILES Source/RPI.Reflect/Image/StreamingImagePoolAssetCreator.cpp Source/RPI.Reflect/Material/MaterialPropertyValue.cpp Source/RPI.Reflect/Material/MaterialAsset.cpp - Source/RPI.Reflect/Material/MaterialAssetCreatorCommon.cpp Source/RPI.Reflect/Material/MaterialAssetCreator.cpp Source/RPI.Reflect/Material/LuaMaterialFunctor.cpp Source/RPI.Reflect/Material/MaterialDynamicMetadata.cpp From 8084775d7adf384f96672e69fa227c81156e9262 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Thu, 13 Jan 2022 12:49:35 -0800 Subject: [PATCH 230/272] Updating code comments. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Atom/RPI.Reflect/Material/MaterialAsset.h | 13 ++++++++++--- .../Source/RPI.Edit/Material/MaterialSourceData.cpp | 3 +++ .../Source/RPI.Reflect/Material/MaterialAsset.cpp | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 4cc6608225..2a6c89a8fa 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -34,8 +34,6 @@ namespace AZ class MaterialAssetHandler; //! MaterialAsset defines a single material, which can be used to create a Material instance for rendering at runtime. - //! It fetches MaterialTypeSourceData from the MaterialTypeAsset it owned. - //! //! Use a MaterialAssetCreator to create a MaterialAsset. class MaterialAsset : public AZ::Data::AssetData @@ -46,7 +44,6 @@ namespace AZ friend class MaterialVersionUpdate; friend class MaterialAssetCreator; friend class MaterialAssetHandler; - friend class MaterialAssetCreatorCommon; friend class UnitTest::MaterialTests; friend class UnitTest::MaterialAssetTests; @@ -117,8 +114,18 @@ namespace AZ //! //! Note that even though material source data files contain only override values and inherit the rest from //! their parent material, they all get flattened at build time so every MaterialAsset has the full set of values. + //! + //! Calling GetPropertyValues() will automatically finalize the material asset if it isn't finalized already. The + //! MaterialTypeAsset must be loaded and ready. const AZStd::vector& GetPropertyValues() const; + //! Returns the list of raw values for all properties in this material, as listed in the source .material file(s), before the material asset was Finalized. + //! + //! The MaterialAsset can be created in a "half-baked" state (see MaterialUtils::BuildersShouldFinalizeMaterialAssets) where + //! minimal processing has been done because it did not yet have access to the MaterialTypeAsset. In that case, the list will + //! be populated with values copied from the source .material file with little or no validation or other processing. It includes + //! all parent .material files, with properties listed in low-to-high priority order. + //! This list will be empty however if the asset was finalized at build-time. const AZStd::vector>& GetRawPropertyValues() const; private: diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index 23657f4871..bc764ec7fb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -312,6 +312,9 @@ namespace AZ { materialAssetCreator.ReportWarning("Source data for material property value is invalid."); } + // If the source value type is a string, there are two possible property types: Image and Enum. If there is a "." in + // the string (for the extension) we assume it's an Image and look up the referenced Asset. Otherwise, we can assume + // it's an Enum value and just preserve the original string. else if (property.second.m_value.Is() && AzFramework::StringFunc::Contains(property.second.m_value.GetValue(), ".")) { Data::Asset imageAsset; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index ce5847d12f..a40fa77019 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -304,7 +304,7 @@ namespace AZ m_materialTypeAsset = newMaterialTypeAsset; // If the material asset was not finalized on disk, then we clear the previously finalized property values to force re-finalize. - // This + // This is necessary in case the property layout changed in some way. if (!m_wasPreFinalized) { m_isFinalized = false; From 2d6d14abf72d3db6fba0ab225e83bc23fb7e34ba Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:49:17 -0800 Subject: [PATCH 231/272] Changed MaterialAsset::GetPropertyValues to not auto-finalize. Client code must call Finalize manually. It's better to avoid unexpected side-effects from a const getter function. In some cases it may be acceptable to do non-const things in a const function as long as it is only manipulating internal data, and the public facing API returns the same values as before. But in this case, the IsFinalized function is a public facing API that would have a different result after GetPropertyValues was called. I also updated a couple other minor things from code review feedback. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../RPI.Edit/Material/MaterialSourceData.h | 2 +- .../Atom/RPI.Reflect/Material/MaterialAsset.h | 11 ++++--- .../RPI.Builders/Material/MaterialBuilder.cpp | 2 +- .../Model/MaterialAssetBuilderComponent.cpp | 5 ++-- .../Source/RPI.Public/Material/Material.cpp | 2 ++ .../RPI.Reflect/Material/MaterialAsset.cpp | 5 +--- .../Tests/Material/MaterialAssetTests.cpp | 6 ++-- .../Material/MaterialSourceDataTests.cpp | 30 +++++++++++-------- 8 files changed, 35 insertions(+), 28 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h index a5fb0214e6..0a9371f722 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceData.h @@ -33,7 +33,7 @@ namespace AZ class MaterialAsset; class MaterialAssetCreator; - enum MaterialAssetProcessingMode + enum class MaterialAssetProcessingMode { PreBake, //!< all material asset processing is done in the Asset Processor, producing a finalized material asset DeferredBake //!< some material asset processing is deferred, and the material asset is finalized at runtime after loading diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 2a6c89a8fa..941fcd0fe9 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -107,6 +107,11 @@ namespace AZ //! If false, property values can be accessed through GetRawPropertyValues(). bool IsFinalized() const; + //! If the material asset is not finalized yet, this does the final processing of the raw property values to + //! get the material asset ready to be used. + //! Note the MaterialTypeAsset must be valid before this is called. + void Finalize(AZStd::function reportWarning = nullptr, AZStd::function reportError = nullptr); + //! Returns the list of values for all properties in this material. //! The entries in this list align with the entries in the MaterialPropertiesLayout. Each AZStd::any is guaranteed //! to have a value of type that matches the corresponding MaterialPropertyDescriptor. @@ -131,12 +136,6 @@ namespace AZ private: bool PostLoadInit() override; - //! If the material asset is not finalized yet, this does the final processing of m_rawPropertyValues to - //! get the material asset ready to be used. - //! Note m_materialTypeAsset must be valid before this is called. - //! @param elevateWarnings Indicates whether to treat warnings as errors - void Finalize(AZStd::function reportWarning = nullptr, AZStd::function reportError = nullptr); - //! Checks the material type version and potentially applies a series of property changes (most common are simple property renames) //! based on the MaterialTypeAsset's version update procedure. void ApplyVersionUpdates(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index 6e50e58dd3..cedbb1df6e 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 113; // material dependency improvements + materialBuilderDescriptor.m_version = 114; // material dependency improvements materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index 1cc1925564..a44b47ee6c 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -45,7 +45,8 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(5) // <<<<< This probably is NOT the version number you want to bump. What you're looking for is MaterialAssetBuilderComponent::Reflect below + ->Version(5) // <<<<< If you have made changes to material code and need to force scene files to be reprocessed, this probably is + // NOT the version number you want to bump . What you're looking for is MaterialAssetBuilderComponent::Reflect below. ->Attribute(Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })); } } @@ -127,7 +128,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(19); // material dependency improvements + ->Version(20); // material dependency improvements } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp index 1f739c24f1..fe9dbef278 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp @@ -62,6 +62,8 @@ namespace AZ m_materialAsset = { &materialAsset, AZ::Data::AssetLoadBehavior::PreLoad }; + m_materialAsset->Finalize(); + // Cache off pointers to some key data structures from the material type... auto srgLayout = m_materialAsset->GetMaterialSrgLayout(); if (srgLayout) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index a40fa77019..569e2de81a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -199,10 +199,7 @@ namespace AZ const AZStd::vector& MaterialAsset::GetPropertyValues() const { - // This can't be done in MaterialAssetHandler::LoadAssetData because the MaterialTypeAsset isn't necessarily loaded at that point. - // And it can't be done in PostLoadInit() because that happens on the next frame which might be too late. So we finalize just-in-time - // when properties are accessed. - const_cast(this)->Finalize(); + AZ_Error(s_debugTraceName, IsFinalized(), "MaterialAsset must be finalized before its property values can be accessed"); return m_propertyValues; } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp index 633953cecc..fdb131d449 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp @@ -266,6 +266,10 @@ namespace UnitTest warningFinder.AddExpectedErrorMessage("Automatic updates are available. Consider updating the .material source file"); warningFinder.AddExpectedErrorMessage("This material is based on version '1'"); warningFinder.AddExpectedErrorMessage("material type is now at version '2'"); + + materialAsset->Finalize(); + + warningFinder.CheckExpectedErrorsFound(); // Even though this material was created using the old version of the material type, it's property values should get automatically // updated to align with the new property layout in the latest MaterialTypeAsset. @@ -273,8 +277,6 @@ namespace UnitTest EXPECT_EQ(2, myIntIndex.GetIndex()); EXPECT_EQ(7, materialAsset->GetPropertyValues()[myIntIndex.GetIndex()].GetValue()); - warningFinder.CheckExpectedErrorsFound(); - // Since the MaterialAsset has already been updated, and the warning reported once, we should not see the "consider updating" // warning reported again on subsequent property accesses. warningFinder.Reset(); diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index e4d3cc9768..29f0e7d101 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -228,8 +228,13 @@ namespace UnitTest Data::Asset materialAsset = materialAssetOutcome.GetValue(); + ErrorMessageFinder expectNotFinalizedError("MaterialAsset must be finalized"); + EXPECT_FALSE(materialAsset->IsFinalized()); - // Note we avoid calling GetPropertyValues() because that will auto-finalize the material. We want to check its raw property values first. + + expectNotFinalizedError.ResetCounts(); + EXPECT_TRUE(materialAsset->GetPropertyValues().empty()); + expectNotFinalizedError.CheckExpectedErrorsFound(); auto findRawPropertyValue = [materialAsset](const char* propertyId) { @@ -275,12 +280,14 @@ namespace UnitTest tester.SerializeOut(materialAsset.Get()); materialAsset = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); - // We check the raw property values again on the loaded data, showing that the same data is available in the original un-finalized state. - checkRawPropertyValues(); - - // The material will automatically finalize itself when the properties are accessed. + // We check that everything is still in the original un-finalized state after going through the serialization process. EXPECT_FALSE(materialAsset->IsFinalized()); - materialAsset->GetPropertyValues(); + checkRawPropertyValues(); + expectNotFinalizedError.ResetCounts(); + EXPECT_TRUE(materialAsset->GetPropertyValues().empty()); + expectNotFinalizedError.CheckExpectedErrorsFound(); + + materialAsset->Finalize(); EXPECT_TRUE(materialAsset->IsFinalized()); // Now all the property values should be available through the main GetPropertyValues() API. @@ -295,6 +302,8 @@ namespace UnitTest EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue>(), m_testImageAsset); EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue(), 1u); + // The raw property values are still available (because they are needed if a hot-reload of the MaterialTypeAsset occurs) + checkRawPropertyValues(); } void CheckEqual(MaterialSourceData& a, MaterialSourceData& b) @@ -757,8 +766,9 @@ namespace UnitTest tester.SerializeOut(materialAssetLevel3.Get()); materialAssetLevel3 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); - - // The properties will finalize automatically when we call GetPropertyValues()... + materialAssetLevel1->Finalize(); + materialAssetLevel2->Finalize(); + materialAssetLevel3->Finalize(); AZStd::array_view properties; @@ -779,10 +789,6 @@ namespace UnitTest EXPECT_EQ(properties[myFloat.GetIndex()].GetValue(), 3.5f); EXPECT_EQ(properties[myFloat2.GetIndex()].GetValue(), Vector2(4.1f, 4.2f)); EXPECT_EQ(properties[myColor.GetIndex()].GetValue(), Color(0.15f, 0.25f, 0.35f, 0.45f)); - - EXPECT_TRUE(materialAssetLevel1->IsFinalized()); - EXPECT_TRUE(materialAssetLevel2->IsFinalized()); - EXPECT_TRUE(materialAssetLevel3->IsFinalized()); } TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance_Error_MaterialTypesDontMatch) From c24546a85d1ba0d190fac9e424e9e9b87a9fe6a5 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 14 Jan 2022 10:57:03 -0800 Subject: [PATCH 232/272] Fixed unused variable warning. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 569e2de81a..310c10c39b 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -123,7 +123,7 @@ namespace AZ if (!reportWarning) { - reportWarning = [](const char* message) + reportWarning = []([[maybe_unused]] const char* message) { AZ_Warning(s_debugTraceName, false, "%s", message); }; From 5c2e69d6d07b76f3fbc19d83a66ccab56f49854c Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Tue, 18 Jan 2022 12:36:49 -0600 Subject: [PATCH 233/272] Atom Tools: move asset processor connection to fix thumbnails Thumbnails for the AtomLyIntegration common feature gem were no longer being rendered. The setup code was modified to initialize the thumbnail system after receiving a new event that critical assets finished compiling. This event was being sent and handled correctly in the main editor. This process was failing in other tools because the event was sent before systems were registered to listen for it. To resolve the problem, atom tools application now explicitly connects to the asset processor and processes critical assets after the base application StartCommon function is called. This ensures that the connection is established and the event gets sent after all of the system components have been activated. Signed-off-by: Guthrie Adams --- .../Application/AtomToolsApplication.h | 8 +------- .../Source/Application/AtomToolsApplication.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 9eaacbfa4f..9449c62de1 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -34,7 +33,6 @@ namespace AtomToolsFramework : public AzFramework::Application , public AzQtComponents::AzQtApplication , protected AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler - , protected AzFramework::AssetSystemStatusBus::Handler , protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler , protected AZ::UserSettingsOwnerRequestBus::Handler , protected AtomToolsMainWindowNotificationBus::Handler @@ -77,11 +75,6 @@ namespace AtomToolsFramework void Destroy() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AzFramework::AssetSystemStatusBus::Handler overrides... - void AssetSystemAvailable() override; - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // AZ::ComponentApplication overrides... void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; @@ -107,6 +100,7 @@ namespace AtomToolsFramework virtual void LoadSettings(); virtual void UnloadSettings(); + virtual void ConnectToAssetProcessor(); virtual void CompileCriticalAssets(); virtual void ProcessCommandLine(const AZ::CommandLine& commandLine); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 02248fffd4..791738a06e 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -171,7 +171,6 @@ namespace AtomToolsFramework void AtomToolsApplication::StartCommon(AZ::Entity* systemEntity) { - AzFramework::AssetSystemStatusBus::Handler::BusConnect(); AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); Base::StartCommon(systemEntity); @@ -179,6 +178,8 @@ namespace AtomToolsFramework const bool clearLogFile = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/ClearLogOnStart", false); m_traceLogger.OpenLogFile(GetBuildTargetName() + ".log", clearLogFile); + ConnectToAssetProcessor(); + AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect(); AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast( &AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); @@ -236,7 +237,7 @@ namespace AtomToolsFramework return AZStd::vector({}); } - void AtomToolsApplication::AssetSystemAvailable() + void AtomToolsApplication::ConnectToAssetProcessor() { bool connectedToAssetProcessor = false; @@ -245,18 +246,19 @@ namespace AtomToolsFramework // and able to negotiate a connection when running a debug build // and to negotiate a connection - auto targetName = GetBuildTargetName(); + const auto targetName = GetBuildTargetName(); AzFramework::AssetSystem::ConnectionSettings connectionSettings; AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; - connectionSettings.m_connectionIdentifier = GetBuildTargetName(); + connectionSettings.m_connectionIdentifier = targetName; connectionSettings.m_loggingCallback = [targetName]([[maybe_unused]] AZStd::string_view logData) { AZ_UNUSED(targetName); // Prevent unused warning in release builds AZ_TracePrintf(targetName.c_str(), "%.*s", aznumeric_cast(logData.size()), logData.data()); }; + AzFramework::AssetSystemRequestBus::BroadcastResult( connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); @@ -264,8 +266,6 @@ namespace AtomToolsFramework { CompileCriticalAssets(); } - - AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); } void AtomToolsApplication::CompileCriticalAssets() @@ -302,6 +302,7 @@ namespace AtomToolsFramework } AZ::ComponentApplicationLifecycle::SignalEvent(*m_settingsRegistry, "CriticalAssetsCompiled", R"({})"); + // Reload the assetcatalog.xml at this point again // Start Monitoring Asset changes over the network and load the AssetCatalog auto LoadCatalog = [settingsRegistry = m_settingsRegistry.get()](AZ::Data::AssetCatalogRequests* assetCatalogRequests) From 4af918a4a8895c553fe08264b96e05a1b65f3d28 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 18 Jan 2022 13:50:14 -0600 Subject: [PATCH 234/272] Skipping ShapeIntersectionFilter test (#6975) Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index 5b1e504442..af1c187817 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -131,6 +131,7 @@ class TestAutomation_PrefabNotEnabled(EditorTestSuite): class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module + @pytest.mark.skip("https://github.com/o3de/o3de/issues/6973") class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module From 2627b507d3081bf38248389b475e89e4192f0fd4 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 18 Jan 2022 12:01:19 -0800 Subject: [PATCH 235/272] Fixed unused variable warning Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 310c10c39b..0325c3ac38 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -131,7 +131,7 @@ namespace AZ if (!reportError) { - reportError = [](const char* message) + reportError = []([[maybe_unused]] const char* message) { AZ_Error(s_debugTraceName, false, "%s", message); }; From d9e636f77edf24f32985c48f7ecf638b53c90be0 Mon Sep 17 00:00:00 2001 From: AMZN-byrcolin <68035668+byrcolin@users.noreply.github.com> Date: Tue, 18 Jan 2022 12:12:55 -0800 Subject: [PATCH 236/272] fix edge case with deprecated pal functions (#6976) * fix edge case with deprecated pal functions Signed-off-by: byrcolin --- cmake/PAL.cmake | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index ef431ff92a..0359408200 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -298,21 +298,27 @@ function(ly_get_absolute_pal_filename out_name in_name) # parent relative path is optional if(${ARGC} GREATER 4) - set(parent_relative_path ${ARGV4}) + if(ARGV4) + set(parent_relative_path ${ARGV4}) + endif() endif() # The Default object path for path is the LY_ROOT_FOLDER cmake_path(SET object_path NORMALIZE "${LY_ROOT_FOLDER}") if(${ARGC} GREATER 3) - # The user has supplied an object restricted path, the object path for consideration - cmake_path(SET object_path NORMALIZE ${ARGV3}) + if(ARGV3) + # The user has supplied an object restricted path, the object path for consideration + cmake_path(SET object_path NORMALIZE ${ARGV3}) + endif() endif() # The default restricted object path is O3DE_ENGINE_RESTRICTED_PATH cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") if(${ARGC} GREATER 2) - # The user has supplied an object restricted path - cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + if(ARGV3) + # The user has supplied an object restricted path + cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + endif() endif() if(${ARGC} GREATER 4) @@ -394,27 +400,33 @@ function(ly_get_list_relative_pal_filename out_name in_name) # parent relative path is optional if(${ARGC} GREATER 4) - set(parent_relative_path ${ARGV4}) + if(ARGV4) + set(parent_relative_path ${ARGV4}) + endif() endif() # The Default object path for path is the LY_ROOT_FOLDER cmake_path(SET object_path NORMALIZE "${LY_ROOT_FOLDER}") if(${ARGC} GREATER 3) - # The user has supplied an object restricted path, the object path for consideration - cmake_path(SET object_path NORMALIZE ${ARGV3}) + if(ARGV3) + # The user has supplied an object restricted path, the object path for consideration + cmake_path(SET object_path NORMALIZE ${ARGV3}) + endif() endif() # The default restricted object path is O3DE_ENGINE_RESTRICTED_PATH cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") if(${ARGC} GREATER 2) - # The user has supplied an object restricted path - cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + if(ARGV2) + # The user has supplied an object restricted path + cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + endif() endif() if(${ARGC} GREATER 4) - o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path} ${parent_relative_path}) + o3de_pal_dir(abs_name ${in_name} "${object_restricted_path}" "${object_path}" "${parent_relative_path}") else() - o3de_pal_dir(abs_name ${in_name} ${object_restricted_path} ${object_path}) + o3de_pal_dir(abs_name ${in_name} "${object_restricted_path}" "${object_path}") endif() cmake_path(RELATIVE_PATH abs_name BASE_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE relative_name) From 3a3aa205451a41fc4e0ff3761cd98492d25688fa Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 18 Jan 2022 12:38:08 -0800 Subject: [PATCH 237/272] [development] added required runtime dependency Gem::PhysX.Editor to WhiteBox.Editor.Physics.Tests (#6871) Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- Gems/WhiteBox/Code/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/WhiteBox/Code/CMakeLists.txt b/Gems/WhiteBox/Code/CMakeLists.txt index 91536503ac..1a37a1ce34 100644 --- a/Gems/WhiteBox/Code/CMakeLists.txt +++ b/Gems/WhiteBox/Code/CMakeLists.txt @@ -198,6 +198,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTestShared AZ::AzManipulatorTestFramework.Static Gem::WhiteBox.Editor.Static + RUNTIME_DEPENDENCIES + Gem::PhysX.Editor ) ly_add_googletest( From 4b9e53e623856b852720c7c22e14d5bcd237b183 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 18 Jan 2022 15:05:17 -0600 Subject: [PATCH 238/272] Another batch of GetValues() overrides. (#6915) * Another batch of GetValues() overrides. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added missing headers. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Addressed PR feedback. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Components/MixedGradientComponent.h | 29 ++++++ .../Components/PosterizeGradientComponent.h | 34 +++++++ .../Components/ReferenceGradientComponent.h | 1 + .../Components/SmoothStepGradientComponent.h | 1 + .../SurfaceAltitudeGradientComponent.h | 19 +++- .../Components/SurfaceMaskGradientComponent.h | 16 ++++ .../SurfaceSlopeGradientComponent.h | 33 +++++++ .../Components/ThresholdGradientComponent.h | 1 + .../Include/GradientSignal/GradientSampler.h | 2 +- .../Code/Include/GradientSignal/SmoothStep.h | 40 +++++--- .../Components/MixedGradientComponent.cpp | 94 +++++++++++-------- .../Components/PosterizeGradientComponent.cpp | 44 ++++----- .../Components/ReferenceGradientComponent.cpp | 15 ++- .../SmoothStepGradientComponent.cpp | 16 +++- .../SurfaceAltitudeGradientComponent.cpp | 42 +++++++-- .../SurfaceMaskGradientComponent.cpp | 48 ++++++++-- .../SurfaceSlopeGradientComponent.cpp | 60 +++++++----- .../Components/ThresholdGradientComponent.cpp | 17 +++- 18 files changed, 386 insertions(+), 126 deletions(-) diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h index 9c9867cf1e..658118fca4 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h @@ -99,6 +99,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: @@ -110,6 +111,34 @@ namespace GradientSignal MixedGradientLayer* GetLayer(int layerIndex) override; private: + static float PerformMixingOperation(MixedGradientLayer::MixingOperation operation, float prevValue, float currentUnpremultiplied) + { + switch (operation) + { + case MixedGradientLayer::MixingOperation::Initialize: + return currentUnpremultiplied; + case MixedGradientLayer::MixingOperation::Multiply: + return prevValue * currentUnpremultiplied; + case MixedGradientLayer::MixingOperation::Add: + return prevValue + currentUnpremultiplied; + case MixedGradientLayer::MixingOperation::Subtract: + return prevValue - currentUnpremultiplied; + case MixedGradientLayer::MixingOperation::Min: + return AZStd::min(prevValue, currentUnpremultiplied); + case MixedGradientLayer::MixingOperation::Max: + return AZStd::max(prevValue, currentUnpremultiplied); + case MixedGradientLayer::MixingOperation::Average: + return (prevValue + currentUnpremultiplied) / 2.0f; + case MixedGradientLayer::MixingOperation::Normal: + return currentUnpremultiplied; + case MixedGradientLayer::MixingOperation::Overlay: + return (prevValue >= 0.5f) ? (1.0f - (2.0f * (1.0f - prevValue) * (1.0f - currentUnpremultiplied))) + : (2.0f * prevValue * currentUnpremultiplied); + default: + return currentUnpremultiplied; + } + } + MixedGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; }; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h index 9b0714b449..bff49ac619 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h @@ -73,6 +73,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: @@ -86,6 +87,39 @@ namespace GradientSignal GradientSampler& GetGradientSampler() override; private: + + static float PosterizeValue(float input, float bands, PosterizeGradientConfig::ModeType mode) + { + const float clampedInput = AZ::GetClamp(input, 0.0f, 1.0f); + float output = 0.0f; + + // "quantize" the input down to a number that goes from 0 to (bands-1) + const float band = AZ::GetMin(floorf(clampedInput * bands), bands - 1.0f); + + // Given our quantized band, produce the right output for that band range. + switch (mode) + { + default: + case PosterizeGradientConfig::ModeType::Floor: + // Floor: the output range should be the lowest value of each band, or (0 to bands-1) / bands + output = (band + 0.0f) / bands; + break; + case PosterizeGradientConfig::ModeType::Round: + // Round: the output range should be the midpoint of each band, or (0.5 to bands-0.5) / bands + output = (band + 0.5f) / bands; + break; + case PosterizeGradientConfig::ModeType::Ceiling: + // Ceiling: the output range should be the highest value of each band, or (1 to bands) / bands + output = (band + 1.0f) / bands; + break; + case PosterizeGradientConfig::ModeType::Ps: + // Ps: the output range should be equally distributed from 0-1, or (0 to bands-1) / (bands-1) + output = band / (bands - 1.0f); + break; + } + return AZ::GetMin(output, 1.0f); + } + PosterizeGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; }; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h index bf16b484fc..17c40865b3 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h @@ -64,6 +64,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h index 85947175af..03f629ab1e 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h @@ -71,6 +71,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h index 6ed841dafb..eb76fac292 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace LmbrCentral { @@ -89,6 +90,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// @@ -105,7 +107,22 @@ namespace GradientSignal void AddTag(AZStd::string tag) override; private: - mutable AZStd::recursive_mutex m_cacheMutex; + static float CalculateAltitudeRatio(const SurfaceData::SurfacePointList& points, float altitudeMin, float altitudeMax) + { + if (points.empty()) + { + return 0.0f; + } + + // GetSurfacePoints (which was used to populate the points list) always returns points in decreasing height order, so the + // first point in the list contains the highest altitude. + const float highestAltitude = points.front().m_position.GetZ(); + + // Turn the absolute altitude value into a 0-1 value by returning the % of the given altitude range that it falls at. + return GetRatio(altitudeMin, altitudeMax, highestAltitude); + } + + mutable AZStd::shared_mutex m_cacheMutex; SurfaceAltitudeGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; AZStd::atomic_bool m_dirty{ false }; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h index f5400719d0..3eafb8c115 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h @@ -70,6 +70,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// @@ -80,6 +81,21 @@ namespace GradientSignal void AddTag(AZStd::string tag) override; private: + static float GetMaxSurfaceWeight(const SurfaceData::SurfacePointList& points) + { + float result = 0.0f; + + for (const auto& point : points) + { + for (const auto& [maskId, weight] : point.m_masks) + { + result = AZ::GetMax(AZ::GetClamp(weight, 0.0f, 1.0f), result); + } + } + + return result; + } + SurfaceMaskGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; }; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h index b6805202f1..b464b6fb0f 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace LmbrCentral { @@ -91,6 +92,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// @@ -121,6 +123,37 @@ namespace GradientSignal void SetFallOffMidpoint(float midpoint) override; private: + float GetSlopeRatio(const SurfaceData::SurfacePointList& points, float angleMin, float angleMax) const + { + if (points.empty()) + { + return 0.0f; + } + + // Assuming our surface normal vector is actually normalized, we can get the slope + // by just grabbing the Z value. It's the same thing as normal.Dot(AZ::Vector3::CreateAxisZ()). + AZ_Assert( + points.front().m_normal.GetNormalized().IsClose(points.front().m_normal), + "Surface normals are expected to be normalized"); + const float slope = points.front().m_normal.GetZ(); + // Convert slope back to an angle so that we can lerp in "angular space", not "slope value space". + // (We want our 0-1 range to be linear across the range of angles) + const float slopeAngle = acosf(slope); + + switch (m_configuration.m_rampType) + { + case SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP: + return m_configuration.m_smoothStep.GetSmoothedValue(GetRatio(angleMin, angleMax, slopeAngle)); + case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_UP: + // For ramp up, linearly interpolate from min to max. + return GetRatio(angleMin, angleMax, slopeAngle); + case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_DOWN: + default: + // For ramp down, linearly interpolate from max to min. + return GetRatio(angleMax, angleMin, slopeAngle); + } + } + SurfaceSlopeGradientConfig m_configuration; }; } diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h index dbf211551c..96bc235ea8 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h @@ -65,6 +65,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h index c9aa7f680c..bf5c8d1ea0 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h @@ -152,7 +152,7 @@ namespace GradientSignal auto ClearOutputValues = [](AZStd::span outValues) { // If we don't have a valid gradient (or it is fully transparent), clear out all the output values. - memset(outValues.data(), 0, outValues.size() * sizeof(float)); + AZStd::fill(outValues.begin(), outValues.end(), 0.0f); }; if (m_opacity <= 0.0f || !m_gradientId.IsValid()) diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/SmoothStep.h b/Gems/GradientSignal/Code/Include/GradientSignal/SmoothStep.h index 0489fa4893..c8fc77ac60 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/SmoothStep.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/SmoothStep.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -26,29 +27,46 @@ namespace GradientSignal static void Reflect(AZ::ReflectContext* context); inline float GetSmoothedValue(float inputValue) const; + inline void GetSmoothedValues(AZStd::span inOutValues) const; float m_falloffMidpoint = 0.5f; float m_falloffRange = 0.5f; float m_falloffStrength = 0.25f; + + private: + inline float CalculateSmoothedValue(float min, float max, float valueFalloffStrength, float inputValue) const; }; - inline float SmoothStep::GetSmoothedValue(float inputValue) const + inline float SmoothStep::CalculateSmoothedValue(float min, float max, float valueFalloffStrength, float inputValue) const { - float output = 0.0f; - const float value = AZ::GetClamp(inputValue, 0.0f, 1.0f); - const float valueFalloffStrength = AZ::GetClamp(m_falloffStrength, 0.0f, 1.0f); - - float min = m_falloffMidpoint - m_falloffRange / 2.0f; - float max = m_falloffMidpoint + m_falloffRange / 2.0f; float result1 = GetRatio(min, min + valueFalloffStrength, value); result1 = GetSmoothStep(result1); float result2 = GetRatio(max - valueFalloffStrength, max, value); result2 = GetSmoothStep(result2); - output = result1 * (1.0f - result2); - - return output; + return result1 * (1.0f - result2); } -} + + inline float SmoothStep::GetSmoothedValue(float inputValue) const + { + const float min = m_falloffMidpoint - m_falloffRange / 2.0f; + const float max = m_falloffMidpoint + m_falloffRange / 2.0f; + const float valueFalloffStrength = AZ::GetClamp(m_falloffStrength, 0.0f, 1.0f); + + return CalculateSmoothedValue(min, max, valueFalloffStrength, inputValue); + } + + inline void SmoothStep::GetSmoothedValues(AZStd::span inOutValues) const + { + const float min = m_falloffMidpoint - m_falloffRange / 2.0f; + const float max = m_falloffMidpoint + m_falloffRange / 2.0f; + const float valueFalloffStrength = AZ::GetClamp(m_falloffStrength, 0.0f, 1.0f); + + for (auto& inOutValue : inOutValues) + { + inOutValue = CalculateSmoothedValue(min, max, valueFalloffStrength, inOutValue); + } + } +} // namespace GradientSignal diff --git a/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp index e042188f8a..23bdd379fe 100644 --- a/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp @@ -257,62 +257,80 @@ namespace GradientSignal float MixedGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - AZ_PROFILE_FUNCTION(Entity); - //accumulate the mixed/combined result of all layers and operations float result = 0.0f; - float operationResult = 0.0f; for (const auto& layer : m_configuration.m_layers) { // added check to prevent opacity of 0.0, which will bust when we unpremultiply the alpha out if (layer.m_enabled && layer.m_gradientSampler.m_opacity != 0.0f) { + // Precalculate the inverse opacity that we'll use for blending the current accumulated value with. + // In the one case of "Initialize" blending, force this value to 0 so that we erase any accumulated values. + const float inverseOpacity = (layer.m_operation == MixedGradientLayer::MixingOperation::Initialize) + ? 0.0f + : (1.0f - layer.m_gradientSampler.m_opacity); + // this includes leveling and opacity result, we need unpremultiplied opacity to combine properly float current = layer.m_gradientSampler.GetValue(sampleParams); // unpremultiplied alpha (we clamp the end result) - float currentUnpremultiplied = current / layer.m_gradientSampler.m_opacity; - switch (layer.m_operation) - { - default: - case MixedGradientLayer::MixingOperation::Initialize: - //reset the result of the mixed/combined layers to the current value - result = 0.0f; - operationResult = currentUnpremultiplied; - break; - case MixedGradientLayer::MixingOperation::Multiply: - operationResult = result * currentUnpremultiplied; - break; - case MixedGradientLayer::MixingOperation::Add: - operationResult = result + currentUnpremultiplied; - break; - case MixedGradientLayer::MixingOperation::Subtract: - operationResult = result - currentUnpremultiplied; - break; - case MixedGradientLayer::MixingOperation::Min: - operationResult = AZStd::min(currentUnpremultiplied, result); - break; - case MixedGradientLayer::MixingOperation::Max: - operationResult = AZStd::max(currentUnpremultiplied, result); - break; - case MixedGradientLayer::MixingOperation::Average: - operationResult = (result + currentUnpremultiplied) / 2.0f; - break; - case MixedGradientLayer::MixingOperation::Normal: - operationResult = currentUnpremultiplied; - break; - case MixedGradientLayer::MixingOperation::Overlay: - operationResult = (result >= 0.5f) ? (1.0f - (2.0f * (1.0f - result) * (1.0f - currentUnpremultiplied))) : (2.0f * result * currentUnpremultiplied); - break; - } + const float currentUnpremultiplied = current / layer.m_gradientSampler.m_opacity; + const float operationResult = PerformMixingOperation(layer.m_operation, result, currentUnpremultiplied); // blend layers (re-applying opacity, which is why we needed to use unpremultiplied) - result = (result * (1.0f - layer.m_gradientSampler.m_opacity)) + (operationResult * layer.m_gradientSampler.m_opacity); + result = (result * inverseOpacity) + (operationResult * layer.m_gradientSampler.m_opacity); } } return AZ::GetClamp(result, 0.0f, 1.0f); } + void MixedGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + // Initialize all of our output data to 0.0f. Layer blends will combine with this, so we need it to have an initial value. + AZStd::fill(outValues.begin(), outValues.end(), 0.0f); + + AZStd::vector layerValues(positions.size()); + + // accumulate the mixed/combined result of all layers and operations + for (const auto& layer : m_configuration.m_layers) + { + // added check to prevent opacity of 0.0, which will bust when we unpremultiply the alpha out + if (layer.m_enabled && layer.m_gradientSampler.m_opacity != 0.0f) + { + // Precalculate the inverse opacity that we'll use for blending the current accumulated value with. + // In the one case of "Initialize" blending, force this value to 0 so that we erase any accumulated values. + const float inverseOpacity = (layer.m_operation == MixedGradientLayer::MixingOperation::Initialize) + ? 0.0f + : (1.0f - layer.m_gradientSampler.m_opacity); + + // this includes leveling and opacity result, we need unpremultiplied opacity to combine properly + layer.m_gradientSampler.GetValues(positions, layerValues); + + for (size_t index = 0; index < outValues.size(); index++) + { + // unpremultiplied alpha (we clamp the end result) + const float currentUnpremultiplied = layerValues[index] / layer.m_gradientSampler.m_opacity; + const float operationResult = PerformMixingOperation(layer.m_operation, outValues[index], currentUnpremultiplied); + // blend layers (re-applying opacity, which is why we needed to use unpremultiplied) + outValues[index] = (outValues[index] * inverseOpacity) + (operationResult * layer.m_gradientSampler.m_opacity); + } + } + } + + for (auto& outValue : outValues) + { + outValue = AZ::GetClamp(outValue, 0.0f, 1.0f); + } + } + + + bool MixedGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const { for (const auto& layer : m_configuration.m_layers) diff --git a/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp index 21d321df13..4616e080f1 100644 --- a/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp @@ -151,34 +151,28 @@ namespace GradientSignal float PosterizeGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { const float bands = AZ::GetMax(static_cast(m_configuration.m_bands), 2.0f); - const float input = AZ::GetClamp(m_configuration.m_gradientSampler.GetValue(sampleParams), 0.0f, 1.0f); - float output = 0.0f; + const float input = m_configuration.m_gradientSampler.GetValue(sampleParams); + return PosterizeValue(input, bands, m_configuration.m_mode); + } - // "quantize" the input down to a number that goes from 0 to (bands-1) - const float band = AZ::GetClamp(floorf(input * bands), 0.0f, bands - 1.0f); - - // Given our quantized band, produce the right output for that band range. - switch (m_configuration.m_mode) + void PosterizeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) { - default: - case PosterizeGradientConfig::ModeType::Floor: - // Floor: the output range should be the lowest value of each band, or (0 to bands-1) / bands - output = (band + 0.0f) / bands; - break; - case PosterizeGradientConfig::ModeType::Round: - // Round: the output range should be the midpoint of each band, or (0.5 to bands-0.5) / bands - output = (band + 0.5f) / bands; - break; - case PosterizeGradientConfig::ModeType::Ceiling: - // Ceiling: the output range should be the highest value of each band, or (1 to bands) / bands - output = (band + 1.0f) / bands; - break; - case PosterizeGradientConfig::ModeType::Ps: - // Ps: the output range should be equally distributed from 0-1, or (0 to bands-1) / (bands-1) - output = band / (bands - 1.0f); - break; + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + const float bands = AZ::GetMax(static_cast(m_configuration.m_bands), 2.0f); + + // Fill in the outValues with all of the generated inupt gradient values. + m_configuration.m_gradientSampler.GetValues(positions, outValues); + + // Run through all the input values and posterize them. + for (auto& outValue : outValues) + { + outValue = PosterizeValue(outValue, bands, m_configuration.m_mode); } - return AZ::GetClamp(output, 0.0f, 1.0f); } bool PosterizeGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const diff --git a/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp index ea304a7eed..e135401ff5 100644 --- a/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp @@ -131,13 +131,18 @@ namespace GradientSignal float ReferenceGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - AZ_PROFILE_FUNCTION(Entity); + return m_configuration.m_gradientSampler.GetValue(sampleParams); + } - float output = 0.0f; + void ReferenceGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } - output = m_configuration.m_gradientSampler.GetValue(sampleParams); - - return output; + m_configuration.m_gradientSampler.GetValues(positions, outValues); } bool ReferenceGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const diff --git a/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp index 510ed41510..683f0a37fa 100644 --- a/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp @@ -168,12 +168,20 @@ namespace GradientSignal float SmoothStepGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - float output = 0.0f; + const float value = m_configuration.m_gradientSampler.GetValue(sampleParams); + return m_configuration.m_smoothStep.GetSmoothedValue(value); + } - const float value = AZ::GetClamp(m_configuration.m_gradientSampler.GetValue(sampleParams), 0.0f, 1.0f); - output = m_configuration.m_smoothStep.GetSmoothedValue(value); + void SmoothStepGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } - return output; + m_configuration.m_gradientSampler.GetValues(positions, outValues); + m_configuration.m_smoothStep.GetSmoothedValues(outValues); } bool SmoothStepGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp index 8b36182750..ee6c272e40 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp @@ -202,19 +202,49 @@ namespace GradientSignal float SurfaceAltitudeGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - AZStd::lock_guard lock(m_cacheMutex); + AZStd::shared_lock lock(m_cacheMutex); SurfaceData::SurfacePointList points; SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, sampleParams.m_position, m_configuration.m_surfaceTagsToSample, points); - if (points.empty()) + return CalculateAltitudeRatio(points, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); + } + + void SurfaceAltitudeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) { - return 0.0f; + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; } - const AZ::Vector3& position = points.front().m_position; - return GetRatio(m_configuration.m_altitudeMin, m_configuration.m_altitudeMax, position.GetZ()); + AZStd::shared_lock lock(m_cacheMutex); + bool valuesFound = false; + + // Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains + // the loop within it so that we can avoid the repeated EBus-calling overhead. + SurfaceData::SurfaceDataSystemRequestBus::Broadcast( + [this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests) + { + // It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results. + valuesFound = true; + SurfaceData::SurfacePointList points; + + // For each position, call GetSurfacePoints() and turn the height into a 0-1 value based on our min/max altitudes. + for (size_t index = 0; index < positions.size(); index++) + { + points.clear(); + surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagsToSample, points); + outValues[index] = CalculateAltitudeRatio(points, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); + } + }); + + if (!valuesFound) + { + // No surface data, so no output values. + AZStd::fill(outValues.begin(), outValues.end(), 0.0f); + } } void SurfaceAltitudeGradientComponent::OnCompositionChanged() @@ -246,7 +276,7 @@ namespace GradientSignal { AZ_PROFILE_FUNCTION(Entity); - AZStd::lock_guard lock(m_cacheMutex); + AZStd::unique_lock lock(m_cacheMutex); if (m_configuration.m_shapeEntityId.IsValid()) { diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp index df7a3f5787..f697050f56 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp @@ -161,8 +161,6 @@ namespace GradientSignal float SurfaceMaskGradientComponent::GetValue(const GradientSampleParams& params) const { - AZ_PROFILE_FUNCTION(Entity); - float result = 0.0f; if (!m_configuration.m_surfaceTagList.empty()) @@ -171,18 +169,50 @@ namespace GradientSignal SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, params.m_position, m_configuration.m_surfaceTagList, points); - for (const auto& point : points) - { - for (const auto& maskPair : point.m_masks) - { - result = AZ::GetMax(AZ::GetClamp(maskPair.second, 0.0f, 1.0f), result); - } - } + result = GetMaxSurfaceWeight(points); } return result; } + void SurfaceMaskGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + bool valuesFound = false; + + if (!m_configuration.m_surfaceTagList.empty()) + { + // Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains + // the loop within it so that we can avoid the repeated EBus-calling overhead. + SurfaceData::SurfaceDataSystemRequestBus::Broadcast( + [this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests) + { + // It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results. + valuesFound = true; + SurfaceData::SurfacePointList points; + + for (size_t index = 0; index < positions.size(); index++) + { + points.clear(); + surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagList, points); + outValues[index] = GetMaxSurfaceWeight(points); + } + }); + } + + if (!valuesFound) + { + // No surface tags, so no output values. + AZStd::fill(outValues.begin(), outValues.end(), 0.0f); + } + + } + size_t SurfaceMaskGradientComponent::GetNumTags() const { return m_configuration.GetNumTags(); diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp index 84e0b61a62..50105a862f 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp @@ -209,36 +209,50 @@ namespace GradientSignal SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, sampleParams.m_position, m_configuration.m_surfaceTagsToSample, points); - if (points.empty()) - { - return 0.0f; - } - - // Assuming our surface normal vector is actually normalized, we can get the slope - // by just grabbing the Z value. It's the same thing as normal.Dot(AZ::Vector3::CreateAxisZ()). - AZ_Assert(points.front().m_normal.GetNormalized().IsClose(points.front().m_normal), "Surface normals are expected to be normalized"); - const float slope = points.front().m_normal.GetZ(); - // Convert slope back to an angle so that we can lerp in "angular space", not "slope value space". - // (We want our 0-1 range to be linear across the range of angles) - const float slopeAngle = acosf(slope); - const float angleMin = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMin, 0.0f, 90.0f)); const float angleMax = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMax, 0.0f, 90.0f)); - switch (m_configuration.m_rampType) + return GetSlopeRatio(points, angleMin, angleMax); + } + + void SurfaceSlopeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) { - case SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP: - return m_configuration.m_smoothStep.GetSmoothedValue(GetRatio(angleMin, angleMax, slopeAngle)); - case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_UP: - // For ramp up, linearly interpolate from min to max. - return GetRatio(angleMin, angleMax, slopeAngle); - case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_DOWN: - default: - // For ramp down, linearly interpolate from max to min. - return GetRatio(angleMax, angleMin, slopeAngle); + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } + + bool valuesFound = false; + + // Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains + // the loop within it so that we can avoid the repeated EBus-calling overhead. + SurfaceData::SurfaceDataSystemRequestBus::Broadcast( + [this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests) + { + // It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results. + valuesFound = true; + SurfaceData::SurfacePointList points; + + const float angleMin = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMin, 0.0f, 90.0f)); + const float angleMax = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMax, 0.0f, 90.0f)); + + for (size_t index = 0; index < positions.size(); index++) + { + points.clear(); + surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagsToSample, points); + outValues[index] = GetSlopeRatio(points, angleMin, angleMax); + } + }); + + if (!valuesFound) + { + // No surface tags, so no output values. + AZStd::fill(outValues.begin(), outValues.end(), 0.0f); } } + float SurfaceSlopeGradientComponent::GetSlopeMin() const { return m_configuration.m_slopeMin; diff --git a/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp index a47ebdebe6..5df579576d 100644 --- a/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp @@ -138,11 +138,22 @@ namespace GradientSignal float ThresholdGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { - float output = 0.0f; + return (m_configuration.m_gradientSampler.GetValue(sampleParams) <= m_configuration.m_threshold) ? 0.0f : 1.0f; + } - output = m_configuration.m_gradientSampler.GetValue(sampleParams) <= m_configuration.m_threshold ? 0.0f : 1.0f; + void ThresholdGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) + { + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; + } - return output; + m_configuration.m_gradientSampler.GetValues(positions, outValues); + for (auto& outValue : outValues) + { + outValue = (outValue <= m_configuration.m_threshold) ? 0.0f : 1.0f; + } } bool ThresholdGradientComponent::IsEntityInHierarchy(const AZ::EntityId& entityId) const From b09caa5e7576af98b060f339308f779c9af1b6d5 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Tue, 18 Jan 2022 17:14:49 -0600 Subject: [PATCH 239/272] Atom Tools: disabling auto load of unused gems in some atom tools Atom tools are set up to inherit and automatically load all of the gems used by the game project. This is a great simplification that saves us from having to manually update cmake settings for every game project to push dependencies to every tool. The tradeoff is that some dependencies will be added to certain tools that have no relevance whatsoever, potentially wasting initialization time, memory utilization, and some processing. This change follows an existing example to update a couple of tools to forego initializing unused gems. They can easily be reenabled as needed. Signed-off-by: Guthrie Adams --- .../Include/AtomToolsFramework/Util/Util.h | 2 +- .../Code/Source/Util/Util.cpp | 6 +- .../EditorMaterialSystemComponent.cpp | 2 +- Registry/gem_autoload.materialeditor.setreg | 69 +++++++++++++++++++ ...em_autoload.shadermanagementconsole.setreg | 69 +++++++++++++++++++ 5 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 Registry/gem_autoload.materialeditor.setreg create mode 100644 Registry/gem_autoload.shadermanagementconsole.setreg diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Util/Util.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Util/Util.h index ab2b8b46c0..57355e4f56 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Util/Util.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Util/Util.h @@ -38,5 +38,5 @@ namespace AtomToolsFramework QFileInfo GetOpenFileInfo(const AZStd::vector& assetTypes); QFileInfo GetUniqueFileInfo(const QString& initialPath); QFileInfo GetDuplicationFileInfo(const QString& initialPath); - bool LaunchTool(const QString& baseName, const QString& extension, const QStringList& arguments); + bool LaunchTool(const QString& baseName, const QStringList& arguments); } // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Util/Util.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Util/Util.cpp index b45ff3c12f..89a5407260 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Util/Util.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Util/Util.cpp @@ -168,13 +168,13 @@ namespace AtomToolsFramework return duplicateFileInfo; } - bool LaunchTool(const QString& baseName, const QString& extension, const QStringList& arguments) + bool LaunchTool(const QString& baseName, const QStringList& arguments) { AZ::IO::FixedMaxPath engineRoot = AZ::Utils::GetEnginePath(); AZ_Assert(!engineRoot.empty(), "Cannot query Engine Path"); - AZ::IO::FixedMaxPath launchPath = AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) - / (baseName + extension).toUtf8().constData(); + AZ::IO::FixedMaxPath launchPath = + AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / (baseName + AZ_TRAIT_OS_EXECUTABLE_EXTENSION).toUtf8().constData(); return QProcess::startDetached(launchPath.c_str(), arguments, engineRoot.c_str()); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialSystemComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialSystemComponent.cpp index adaebfb889..e216606401 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialSystemComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialSystemComponent.cpp @@ -143,7 +143,7 @@ namespace AZ arguments.append(QString("--project-path=%1").arg(projectPath.c_str())); } - AtomToolsFramework::LaunchTool("MaterialEditor", AZ_TRAIT_OS_EXECUTABLE_EXTENSION, arguments); + AtomToolsFramework::LaunchTool("MaterialEditor", arguments); } void EditorMaterialSystemComponent::OpenMaterialInspector( diff --git a/Registry/gem_autoload.materialeditor.setreg b/Registry/gem_autoload.materialeditor.setreg new file mode 100644 index 0000000000..fd00ff05c7 --- /dev/null +++ b/Registry/gem_autoload.materialeditor.setreg @@ -0,0 +1,69 @@ +{ + "Amazon": { + "Gems": { + "ImGui.Editor": { + "AutoLoad": false + }, + "Gestures.Editor": { + "AutoLoad": false + }, + "GraphCanvas.Editor": { + "AutoLoad": false + }, + "GraphModel.Editor": { + "AutoLoad": false + }, + "PhysX.Editor": { + "AutoLoad": false + }, + "PhysXDebug.Editor": { + "AutoLoad": false + }, + "Blast.Editor": { + "AutoLoad": false + }, + "NVCloth.Editor": { + "AutoLoad": false + }, + "ScriptCanvas.Editor": { + "AutoLoad": false + }, + "ScriptCanvasPhysics": { + "AutoLoad": false + }, + "ScriptCanvasTesting.Editor": { + "AutoLoad": false + }, + "LandscapeCanvas.Editor": { + "AutoLoad": false + }, + "HttpRequestor.Editor": { + "AutoLoad": false + }, + "WhiteBox.Editor": { + "AutoLoad": false + }, + "PythonAssetBuilder.Editor": { + "AutoLoad": false + }, + "AWSCore": { + "AutoLoad": false + }, + "AWSCore.Editor": { + "AutoLoad": false + }, + "AWSClientAuth": { + "AutoLoad": false + }, + "AWSClientAuth.Editor": { + "AutoLoad": false + }, + "AWSMetrics": { + "AutoLoad": false + }, + "AWSMetrics.Editor": { + "AutoLoad": false + } + } + } +} diff --git a/Registry/gem_autoload.shadermanagementconsole.setreg b/Registry/gem_autoload.shadermanagementconsole.setreg new file mode 100644 index 0000000000..fd00ff05c7 --- /dev/null +++ b/Registry/gem_autoload.shadermanagementconsole.setreg @@ -0,0 +1,69 @@ +{ + "Amazon": { + "Gems": { + "ImGui.Editor": { + "AutoLoad": false + }, + "Gestures.Editor": { + "AutoLoad": false + }, + "GraphCanvas.Editor": { + "AutoLoad": false + }, + "GraphModel.Editor": { + "AutoLoad": false + }, + "PhysX.Editor": { + "AutoLoad": false + }, + "PhysXDebug.Editor": { + "AutoLoad": false + }, + "Blast.Editor": { + "AutoLoad": false + }, + "NVCloth.Editor": { + "AutoLoad": false + }, + "ScriptCanvas.Editor": { + "AutoLoad": false + }, + "ScriptCanvasPhysics": { + "AutoLoad": false + }, + "ScriptCanvasTesting.Editor": { + "AutoLoad": false + }, + "LandscapeCanvas.Editor": { + "AutoLoad": false + }, + "HttpRequestor.Editor": { + "AutoLoad": false + }, + "WhiteBox.Editor": { + "AutoLoad": false + }, + "PythonAssetBuilder.Editor": { + "AutoLoad": false + }, + "AWSCore": { + "AutoLoad": false + }, + "AWSCore.Editor": { + "AutoLoad": false + }, + "AWSClientAuth": { + "AutoLoad": false + }, + "AWSClientAuth.Editor": { + "AutoLoad": false + }, + "AWSMetrics": { + "AutoLoad": false + }, + "AWSMetrics.Editor": { + "AutoLoad": false + } + } + } +} From eb51cd4c06670380314c1a54a5b10a858749b354 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Tue, 18 Jan 2022 01:50:05 -0600 Subject: [PATCH 240/272] Atom Tools: moving custom asset browser code to common location Consolidated duplicate asset browser code from multiple tools into single class in atom tools framework Moved creation of asset browser and Python terminal windows into base main window class Fixed docked window orientations Added checks to asset browser to prevent crashes if tree state saver was null Signed-off-by: Guthrie Adams --- .../Views/AssetBrowserTreeView.cpp | 11 +- .../AssetBrowser/AtomToolsAssetBrowser.h} | 48 ++-- .../Window/AtomToolsMainWindow.h | 3 + .../AssetBrowser/AtomToolsAssetBrowser.cpp} | 215 +++++++++--------- .../AssetBrowser/AtomToolsAssetBrowser.qrc | 5 + .../AssetBrowser/AtomToolsAssetBrowser.ui} | 4 +- .../Code/Source/AssetBrowser/Icons/view.svg} | 0 .../Document/AtomToolsDocumentMainWindow.cpp | 2 + .../Source/Window/AtomToolsMainWindow.cpp | 6 + .../Code/atomtoolsframework_files.cmake | 4 + .../Code/Source/Window/MaterialEditor.qrc | 1 - .../Source/Window/MaterialEditorWindow.cpp | 36 ++- .../Code/Source/Window/MaterialEditorWindow.h | 5 +- .../Window/MaterialEditorWindowModule.cpp | 1 + .../Code/materialeditorwindow_files.cmake | 3 - .../Code/CMakeLists.txt | 1 - .../ShaderManagementConsoleBrowserWidget.h | 69 ------ .../ShaderManagementConsoleBrowserWidget.ui | 168 -------------- .../Window/ShaderManagementConsoleWindow.cpp | 19 +- .../Window/ShaderManagementConsoleWindow.h | 4 +- .../ShaderManagementConsoleWindowModule.cpp | 12 +- .../shadermanagementconsolewindow_files.cmake | 3 - 22 files changed, 212 insertions(+), 408 deletions(-) rename Gems/Atom/Tools/{MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h => AtomToolsFramework/Code/Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h} (54%) rename Gems/Atom/Tools/{MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp => AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp} (56%) create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.qrc rename Gems/Atom/Tools/{MaterialEditor/Code/Source/Window/MaterialBrowserWidget.ui => AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.ui} (98%) rename Gems/Atom/Tools/{MaterialEditor/Code/Source/Window/Icons/View.svg => AtomToolsFramework/Code/Source/AssetBrowser/Icons/view.svg} (100%) delete mode 100644 Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.h delete mode 100644 Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.ui diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp index 146eab9073..93a153cc16 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp @@ -230,7 +230,10 @@ namespace AzToolsFramework { QModelIndex curIndex = selectedIndexes[0]; m_expandToEntriesByDefault = true; - m_treeStateSaver->ApplySnapshot(); + if (m_treeStateSaver) + { + m_treeStateSaver->ApplySnapshot(); + } setCurrentIndex(curIndex); scrollTo(curIndex); @@ -240,8 +243,12 @@ namespace AzToolsFramework // Flag our default expansion state so that we expand down to source entries after filtering m_expandToEntriesByDefault = hasFilter; + // Then ask our state saver to apply its current snapshot again, falling back on asking us if entries should be expanded or not - m_treeStateSaver->ApplySnapshot(); + if (m_treeStateSaver) + { + m_treeStateSaver->ApplySnapshot(); + } // If we're filtering for a valid entry, select the first valid entry if (hasFilter && selectFirstValidEntry) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h similarity index 54% rename from Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h rename to Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h index 24a244bc3c..915387d7b1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h @@ -9,17 +9,14 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include -#include #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include #include AZ_POP_DISABLE_WARNING - #endif namespace AzToolsFramework @@ -27,49 +24,50 @@ namespace AzToolsFramework namespace AssetBrowser { class AssetBrowserFilterModel; - class CompositeFilter; - class AssetBrowserEntry; - class ProductAssetBrowserEntry; - class SourceAssetBrowserEntry; } -} +} // namespace AzToolsFramework namespace Ui { - class MaterialBrowserWidget; + class AtomToolsAssetBrowser; } -namespace MaterialEditor +namespace AtomToolsFramework { - //! Provides a tree view of all available materials and other assets exposed by the MaterialEditor. - class MaterialBrowserWidget + //! Extends the standard asset browser with custom filters and multiselect behavior + class AtomToolsAssetBrowser : public QWidget , protected AZ::TickBus::Handler - , protected AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler { Q_OBJECT public: - MaterialBrowserWidget(QWidget* parent = nullptr); - ~MaterialBrowserWidget(); + AtomToolsAssetBrowser(QWidget* parent = nullptr); + ~AtomToolsAssetBrowser(); - private: - AzToolsFramework::AssetBrowser::FilterConstType CreateFilter() const; + void SetFilterState(const AZStd::string& category, const AZStd::string& displayName, bool enabled); + void SetOpenHandler(AZStd::function openHandler); + + void SelectEntries(const AZStd::string& absolutePath); void OpenSelectedEntries(); + void OpenOptionsMenu(); - // AtomToolsDocumentNotificationBus::Handler implementation - void OnDocumentOpened(const AZ::Uuid& documentId) override; + protected: + AzToolsFramework::AssetBrowser::FilterConstType CreateFilter() const; + void UpdateFilter(); + void UpdatePreview(); + void TogglePreview(); // AZ::TickBus::Handler void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - void OpenOptionsMenu(); - - QScopedPointer m_ui; + QScopedPointer m_ui; AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_filterModel = nullptr; - //! if new asset is being created with this path it will automatically be selected + //! If an asset is opened with this path it will automatically be selected AZStd::string m_pathToSelect; - QByteArray m_materialBrowserState; + QByteArray m_browserState; + + AZStd::function m_openHandler; }; -} // namespace MaterialEditor +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Window/AtomToolsMainWindow.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Window/AtomToolsMainWindow.h index fab6e2fb01..92218d2542 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Window/AtomToolsMainWindow.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Window/AtomToolsMainWindow.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -53,6 +54,8 @@ namespace AtomToolsFramework QMenu* m_menuView = {}; QMenu* m_menuHelp = {}; + AtomToolsFramework::AtomToolsAssetBrowser* m_assetBrowser = {}; + AZStd::unordered_map m_dockWidgets; AZStd::unordered_map m_dockActions; }; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp similarity index 56% rename from Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp rename to Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp index 4df76b4dac..4270cb87fe 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.cpp @@ -6,13 +6,9 @@ * */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include #include @@ -21,41 +17,32 @@ #include #include #include -#include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include -#include #include -#include -#include #include #include #include -#include AZ_POP_DISABLE_WARNING -namespace MaterialEditor +namespace AtomToolsFramework { - MaterialBrowserWidget::MaterialBrowserWidget(QWidget* parent) + AtomToolsAssetBrowser::AtomToolsAssetBrowser(QWidget* parent) : QWidget(parent) - , m_ui(new Ui::MaterialBrowserWidget) + , m_ui(new Ui::AtomToolsAssetBrowser) { using namespace AzToolsFramework::AssetBrowser; m_ui->setupUi(this); m_ui->m_searchWidget->Setup(true, true); - m_ui->m_searchWidget->SetFilterState("", AZ::RPI::StreamingImageAsset::Group, true); - m_ui->m_searchWidget->SetFilterState("", AZ::RPI::MaterialAsset::Group, true); m_ui->m_searchWidget->setMinimumSize(QSize(150, 0)); - m_ui->m_viewOptionButton->setIcon(QIcon(":/Icons/View.svg")); + + m_ui->m_viewOptionButton->setIcon(QIcon(":/Icons/view.svg")); m_ui->m_splitter->setSizes(QList() << 400 << 200); m_ui->m_splitter->setStretchFactor(0, 1); - connect(m_ui->m_viewOptionButton, &QPushButton::clicked, this, &MaterialBrowserWidget::OpenOptionsMenu); - // Get the asset browser model AssetBrowserModel* assetBrowserModel = nullptr; AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel); @@ -73,38 +60,82 @@ namespace MaterialEditor // Maintains the tree expansion state between runs m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_main"); - connect(m_ui->m_searchWidget->GetFilter().data(), &AssetBrowserEntryFilter::updatedSignal, m_filterModel, &AssetBrowserFilterModel::filterUpdatedSlot); - connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, [this]() - { - const bool hasFilter = !m_ui->m_searchWidget->GetFilterString().isEmpty(); - constexpr bool selectFirstFilteredIndex = true; - m_ui->m_assetBrowserTreeViewWidget->UpdateAfterFilter(hasFilter, selectFirstFilteredIndex); - }); - connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::activated, this, &MaterialBrowserWidget::OpenSelectedEntries); - connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::selectionChangedSignal, [this]() { - const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets(); - if (!selectedAssets.empty()) - { - m_ui->m_previewerFrame->Display(selectedAssets.front()); - } - else - { - m_ui->m_previewerFrame->Clear(); - } - }); - - AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(); + connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AtomToolsAssetBrowser::UpdateFilter); + connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::activated, this, &AtomToolsAssetBrowser::OpenSelectedEntries); + connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::selectionChangedSignal, this, &AtomToolsAssetBrowser::UpdatePreview); + connect(m_ui->m_viewOptionButton, &QPushButton::clicked, this, &AtomToolsAssetBrowser::OpenOptionsMenu); + connect( + m_ui->m_searchWidget->GetFilter().data(), &AssetBrowserEntryFilter::updatedSignal, m_filterModel, + &AssetBrowserFilterModel::filterUpdatedSlot); } - MaterialBrowserWidget::~MaterialBrowserWidget() + AtomToolsAssetBrowser::~AtomToolsAssetBrowser() { // Maintains the tree expansion state between runs m_ui->m_assetBrowserTreeViewWidget->SaveState(); - AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusDisconnect(); AZ::TickBus::Handler::BusDisconnect(); } - AzToolsFramework::AssetBrowser::FilterConstType MaterialBrowserWidget::CreateFilter() const + void AtomToolsAssetBrowser::SetFilterState(const AZStd::string& category, const AZStd::string& displayName, bool enabled) + { + m_ui->m_searchWidget->SetFilterState(category.c_str(), displayName.c_str(), enabled); + } + + void AtomToolsAssetBrowser::SetOpenHandler(AZStd::function openHandler) + { + m_openHandler = openHandler; + } + + void AtomToolsAssetBrowser::SelectEntries(const AZStd::string& absolutePath) + { + if (!absolutePath.empty()) + { + // Selecting a new asset in the browser is not guaranteed to happen immediately. + // The asset browser model notifications are sent before the model is updated. + // Instead of relying on the notifications, queue the selection and process it on tick until this change occurs. + m_pathToSelect = absolutePath; + AzFramework::StringFunc::Path::Normalize(m_pathToSelect); + AZ::TickBus::Handler::BusConnect(); + } + } + + void AtomToolsAssetBrowser::OpenSelectedEntries() + { + const AZStd::vector entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets(); + + const int multiSelectPromptThreshold = 10; + if (entries.size() >= multiSelectPromptThreshold) + { + QMessageBox::StandardButton result = QMessageBox::question( + QApplication::activeWindow(), + tr("Attemptng to open %1 files").arg(entries.size()), + tr("Would you like to open anyway?"), + QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::No) + { + return; + } + } + + for (const AssetBrowserEntry* entry : entries) + { + if (entry && entry->GetEntryType() != AssetBrowserEntry::AssetEntryType::Folder && m_openHandler) + { + m_openHandler(entry->GetFullPath().c_str()); + } + } + } + + void AtomToolsAssetBrowser::OpenOptionsMenu() + { + QMenu menu; + QAction* action = menu.addAction(tr("Show Asset Preview"), this, &AtomToolsAssetBrowser::TogglePreview); + action->setCheckable(true); + action->setChecked(m_ui->m_previewerFrame->isVisible()); + menu.exec(QCursor::pos()); + } + + AzToolsFramework::AssetBrowser::FilterConstType AtomToolsAssetBrowser::CreateFilter() const { using namespace AzToolsFramework::AssetBrowser; @@ -125,59 +156,42 @@ namespace MaterialEditor return finalFilter; } - void MaterialBrowserWidget::OpenSelectedEntries() + void AtomToolsAssetBrowser::UpdateFilter() { - const AZStd::vector entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets(); + const bool hasFilter = !m_ui->m_searchWidget->GetFilterString().isEmpty(); + constexpr bool selectFirstFilteredIndex = true; + m_ui->m_assetBrowserTreeViewWidget->UpdateAfterFilter(hasFilter, selectFirstFilteredIndex); + } - const int multiSelectPromptThreshold = 10; - if (entries.size() >= multiSelectPromptThreshold) + void AtomToolsAssetBrowser::UpdatePreview() + { + const auto& selectedAssets = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets(); + if (!selectedAssets.empty()) { - if (QMessageBox::question( - QApplication::activeWindow(), - QString("Attemptng to open %1 files").arg(entries.size()), - "Would you like to open anyway?", - QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - { - return; - } + m_ui->m_previewerFrame->Display(selectedAssets.front()); } - - for (const AssetBrowserEntry* entry : entries) + else { - if (entry) - { - if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), AZ::RPI::MaterialSourceData::Extension)) - { - AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, entry->GetFullPath()); - } - else if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), AZ::RPI::MaterialTypeSourceData::Extension)) - { - //ignore AZ::RPI::MaterialTypeSourceData::Extension - } - else - { - QDesktopServices::openUrl(QUrl::fromLocalFile(entry->GetFullPath().c_str())); - } - } + m_ui->m_previewerFrame->Clear(); } } - void MaterialBrowserWidget::OnDocumentOpened(const AZ::Uuid& documentId) + void AtomToolsAssetBrowser::TogglePreview() { - AZStd::string absolutePath; - AtomToolsFramework::AtomToolsDocumentRequestBus::EventResult(absolutePath, documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::GetAbsolutePath); - if (!absolutePath.empty()) + const bool isPreviewFrameVisible = m_ui->m_previewerFrame->isVisible(); + m_ui->m_previewerFrame->setVisible(!isPreviewFrameVisible); + if (isPreviewFrameVisible) { - // Selecting a new asset in the browser is not guaranteed to happen immediately. - // The asset browser model notifications are sent before the model is updated. - // Instead of relying on the notifications, queue the selection and process it on tick until this change occurs. - m_pathToSelect = absolutePath; - AzFramework::StringFunc::Path::Normalize(m_pathToSelect); - AZ::TickBus::Handler::BusConnect(); + m_browserState = m_ui->m_splitter->saveState(); + m_ui->m_splitter->setSizes(QList({ 1, 0 })); + } + else + { + m_ui->m_splitter->restoreState(m_browserState); } } - void MaterialBrowserWidget::OnTick(float deltaTime, AZ::ScriptTimePoint time) + void AtomToolsAssetBrowser::OnTick(float deltaTime, AZ::ScriptTimePoint time) { AZ_UNUSED(time); AZ_UNUSED(deltaTime); @@ -188,7 +202,7 @@ namespace MaterialEditor AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast( &AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Events::SelectFileAtPath, m_pathToSelect); - // Iterate over the selected entries to verify if the selection was made + // Iterate over the selected entries to verify if the selection was made for (const AssetBrowserEntry* entry : m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets()) { if (entry) @@ -205,31 +219,6 @@ namespace MaterialEditor } } } +} // namespace AtomToolsFramework - void MaterialBrowserWidget::OpenOptionsMenu() - { - QMenu menu; - - QAction* action = new QAction("Show Asset Preview", this); - action->setCheckable(true); - action->setChecked(m_ui->m_previewerFrame->isVisible()); - connect(action, &QAction::triggered, [this]() { - bool isPreviewFrameVisible = m_ui->m_previewerFrame->isVisible(); - m_ui->m_previewerFrame->setVisible(!isPreviewFrameVisible); - if (isPreviewFrameVisible) - { - m_materialBrowserState = m_ui->m_splitter->saveState(); - m_ui->m_splitter->setSizes(QList({ 1, 0 })); - } - else - { - m_ui->m_splitter->restoreState(m_materialBrowserState); - } - }); - menu.addAction(action); - menu.exec(QCursor::pos()); - } - -} // namespace MaterialEditor - -#include +#include diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.qrc b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.qrc new file mode 100644 index 0000000000..c24968e78a --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.qrc @@ -0,0 +1,5 @@ + + + Icons/view.svg + + diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.ui b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.ui similarity index 98% rename from Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.ui rename to Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.ui index 9e5344bea2..9b68b3edc9 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.ui +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/AtomToolsAssetBrowser.ui @@ -1,7 +1,7 @@ - MaterialBrowserWidget - + AtomToolsAssetBrowser + 0 diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/View.svg b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/Icons/view.svg similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/View.svg rename to Gems/Atom/Tools/AtomToolsFramework/Code/Source/AssetBrowser/Icons/view.svg diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentMainWindow.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentMainWindow.cpp index 0d62adc9ee..e8be20097f 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentMainWindow.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentMainWindow.cpp @@ -414,6 +414,8 @@ namespace AtomToolsFramework m_actionPreviousTab->setEnabled(m_tabWidget->count() > 1); m_actionNextTab->setEnabled(m_tabWidget->count() > 1); + m_assetBrowser->SelectEntries(absolutePath); + activateWindow(); raise(); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Window/AtomToolsMainWindow.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Window/AtomToolsMainWindow.cpp index f07fd9c536..6a30ffc421 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Window/AtomToolsMainWindow.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Window/AtomToolsMainWindow.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -40,6 +41,11 @@ namespace AtomToolsFramework centralWidget->setLayout(centralWidgetLayout); setCentralWidget(centralWidget); + m_assetBrowser = new AtomToolsFramework::AtomToolsAssetBrowser(this); + AddDockWidget("Asset Browser", m_assetBrowser, Qt::BottomDockWidgetArea, Qt::Horizontal); + AddDockWidget("Python Terminal", new AzToolsFramework::CScriptTermDialog, Qt::BottomDockWidgetArea, Qt::Horizontal); + SetDockWidgetVisible("Python Terminal", false); + AtomToolsMainWindowRequestBus::Handler::BusConnect(); } diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index 3ddcc05245..3de1bb65e2 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -8,6 +8,7 @@ set(FILES Include/AtomToolsFramework/Application/AtomToolsApplication.h + Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h Include/AtomToolsFramework/Communication/LocalServer.h Include/AtomToolsFramework/Communication/LocalSocket.h Include/AtomToolsFramework/Debug/TraceRecorder.h @@ -36,6 +37,9 @@ set(FILES Include/AtomToolsFramework/Window/AtomToolsMainWindowFactoryRequestBus.h Include/AtomToolsFramework/Window/AtomToolsMainWindowNotificationBus.h Source/Application/AtomToolsApplication.cpp + Source/AssetBrowser/AtomToolsAssetBrowser.cpp + Source/AssetBrowser/AtomToolsAssetBrowser.qrc + Source/AssetBrowser/AtomToolsAssetBrowser.ui Source/Communication/LocalServer.cpp Source/Communication/LocalSocket.cpp Source/Debug/TraceRecorder.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc index 902201e792..73b55f2f39 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc @@ -21,6 +21,5 @@ Icons/shadow.svg Icons/skybox.svg Icons/toneMapping.svg - Icons/View.svg diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 0388af0134..44adda432d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -8,15 +8,16 @@ #include #include +#include +#include #include +#include #include #include #include -#include #include #include #include -#include #include #include #include @@ -27,14 +28,16 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnin #include #include #include +#include #include +#include #include AZ_POP_DISABLE_WARNING namespace MaterialEditor { MaterialEditorWindow::MaterialEditorWindow(QWidget* parent /* = 0 */) - : AtomToolsFramework::AtomToolsDocumentMainWindow(parent) + : Base(parent) { resize(1280, 1024); @@ -72,15 +75,30 @@ namespace MaterialEditor m_materialViewport->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); centralWidget()->layout()->addWidget(m_materialViewport); - AddDockWidget("Asset Browser", new MaterialBrowserWidget, Qt::BottomDockWidgetArea, Qt::Vertical); - AddDockWidget("Inspector", new MaterialInspector, Qt::RightDockWidgetArea, Qt::Horizontal); - AddDockWidget("Viewport Settings", new ViewportSettingsInspector, Qt::LeftDockWidgetArea, Qt::Horizontal); - AddDockWidget("Performance Monitor", new PerformanceMonitorWidget, Qt::RightDockWidgetArea, Qt::Horizontal); - AddDockWidget("Python Terminal", new AzToolsFramework::CScriptTermDialog, Qt::BottomDockWidgetArea, Qt::Horizontal); + m_assetBrowser->SetFilterState("", AZ::RPI::StreamingImageAsset::Group, true); + m_assetBrowser->SetFilterState("", AZ::RPI::MaterialAsset::Group, true); + m_assetBrowser->SetOpenHandler([](const AZStd::string& absolutePath) { + if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::MaterialSourceData::Extension)) + { + AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( + &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, absolutePath); + return; + } + + if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::MaterialTypeSourceData::Extension)) + { + return; + } + + QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str())); + }); + + AddDockWidget("Inspector", new MaterialInspector, Qt::RightDockWidgetArea, Qt::Vertical); + AddDockWidget("Viewport Settings", new ViewportSettingsInspector, Qt::LeftDockWidgetArea, Qt::Vertical); + AddDockWidget("Performance Monitor", new PerformanceMonitorWidget, Qt::BottomDockWidgetArea, Qt::Horizontal); SetDockWidgetVisible("Viewport Settings", false); SetDockWidgetVisible("Performance Monitor", false); - SetDockWidgetVisible("Python Terminal", false); // Restore geometry and show the window mainWindowWrapper->showFromSettings(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h index bed2aa34e4..8ad294c529 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h @@ -21,7 +21,6 @@ namespace MaterialEditor { //! MaterialEditorWindow is the main class. Its responsibility is limited to initializing and connecting //! its panels, managing selection of assets, and performing high-level actions like saving. It contains... - //! 1) MaterialBrowser - The user browses for Material (.material) assets. //! 2) MaterialViewport - The user can see the selected Material applied to a model. //! 3) MaterialPropertyInspector - The user edits the properties of the selected Material. class MaterialEditorWindow @@ -48,7 +47,7 @@ namespace MaterialEditor void closeEvent(QCloseEvent* closeEvent) override; - MaterialViewportWidget* m_materialViewport = nullptr; - MaterialEditorToolBar* m_toolBar = nullptr; + MaterialViewportWidget* m_materialViewport = {}; + MaterialEditorToolBar* m_toolBar = {}; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp index c761c85556..1562d11647 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp @@ -14,6 +14,7 @@ void InitMaterialEditorResources() //Must register qt resources from other modules Q_INIT_RESOURCE(MaterialEditor); Q_INIT_RESOURCE(InspectorWidget); + Q_INIT_RESOURCE(AtomToolsAssetBrowser); } namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake index b814ad3f47..3d21e71294 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake @@ -15,9 +15,6 @@ set(FILES Source/Window/MaterialEditorWindow.cpp Source/Window/MaterialEditorWindowModule.cpp Source/Window/MaterialEditorWindowSettings.cpp - Source/Window/MaterialBrowserWidget.h - Source/Window/MaterialBrowserWidget.cpp - Source/Window/MaterialBrowserWidget.ui Source/Window/MaterialEditor.qrc Source/Window/MaterialEditor.qss Source/Window/MaterialEditorWindowComponent.h diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt b/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt index 3f7788418a..c5ceab5360 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/CMakeLists.txt @@ -42,7 +42,6 @@ ly_add_target( NAME ShaderManagementConsole.Window STATIC NAMESPACE Gem AUTOMOC - AUTOUIC AUTORCC FILES_CMAKE shadermanagementconsolewindow_files.cmake diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.h deleted file mode 100644 index 73a2a24aa9..0000000000 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include - -AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT -#include -AZ_POP_DISABLE_WARNING - -#endif - -namespace AzToolsFramework -{ - namespace AssetBrowser - { - class AssetBrowserFilterModel; - class CompositeFilter; - class AssetBrowserEntry; - class ProductAssetBrowserEntry; - class SourceAssetBrowserEntry; - } -} - -namespace Ui -{ - class ShaderManagementConsoleBrowserWidget; -} - -namespace ShaderManagementConsole -{ - //! Provides a tree view of all available assets - class ShaderManagementConsoleBrowserWidget - : public QWidget - , public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler - , public AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler - { - Q_OBJECT - public: - ShaderManagementConsoleBrowserWidget(QWidget* parent = nullptr); - ~ShaderManagementConsoleBrowserWidget(); - - private: - AzToolsFramework::AssetBrowser::FilterConstType CreateFilter() const; - void OpenSelectedEntries(); - - QScopedPointer m_ui; - AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_filterModel = nullptr; - - //! if new asset is being created with this path it will automatically be selected - AZStd::string m_pathToSelect; - - // AssetBrowserModelNotificationBus::Handler implementation - void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override; - - // AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler implementation - void OnDocumentOpened(const AZ::Uuid& documentId) override; - }; -} // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.ui b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.ui deleted file mode 100644 index cf8a714273..0000000000 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleBrowserWidget.ui +++ /dev/null @@ -1,168 +0,0 @@ - - - ShaderManagementConsoleBrowserWidget - - - - 0 - 0 - 691 - 554 - - - - Asset Browser - - - - 0 - - - - - - 1 - 1 - - - - true - - - - - 0 - 0 - 671 - 534 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 0 - - - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - false - - - - - 0 - 0 - - - - vertical-align: top - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 1 - 0 - - - - QAbstractItemView::DragOnly - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - - - - - - - - AzToolsFramework::AssetBrowser::SearchWidget - QWidget -
AzToolsFramework/AssetBrowser/Search/SearchWidget.h
- 1 -
- - AzToolsFramework::AssetBrowser::AssetBrowserTreeView - QTreeView -
AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h
-
- - AzToolsFramework::AssetBrowser::PreviewerFrame - QFrame -
AzToolsFramework/AssetBrowser/Previewer/PreviewerFrame.h
- 1 -
-
- - -
diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp index 29dafe99fe..8e8e047e83 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp @@ -7,23 +7,25 @@ */ #include +#include #include #include #include -#include #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT +#include #include #include #include +#include #include AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { ShaderManagementConsoleWindow::ShaderManagementConsoleWindow(QWidget* parent /* = 0 */) - : AtomToolsFramework::AtomToolsDocumentMainWindow(parent) + : Base(parent) { resize(1280, 1024); @@ -41,10 +43,17 @@ namespace ShaderManagementConsole m_toolBar->setObjectName("ToolBar"); addToolBar(m_toolBar); - AddDockWidget("Asset Browser", new ShaderManagementConsoleBrowserWidget, Qt::BottomDockWidgetArea, Qt::Vertical); - AddDockWidget("Python Terminal", new AzToolsFramework::CScriptTermDialog, Qt::BottomDockWidgetArea, Qt::Horizontal); + m_assetBrowser->SetFilterState("", AZ::RPI::ShaderAsset::Group, true); + m_assetBrowser->SetOpenHandler([](const AZStd::string& absolutePath) { + if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) + { + AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( + &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, absolutePath); + return; + } - SetDockWidgetVisible("Python Terminal", false); + QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str())); + }); // Restore geometry and show the window mainWindowWrapper->showFromSettings(); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h index 3ba122674a..1c7479e526 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h @@ -14,9 +14,7 @@ #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT -#include #include - #include AZ_POP_DISABLE_WARNING #endif @@ -40,6 +38,6 @@ namespace ShaderManagementConsole protected: QWidget* CreateDocumentTabView(const AZ::Uuid& documentId) override; - ShaderManagementConsoleToolBar* m_toolBar = nullptr; + ShaderManagementConsoleToolBar* m_toolBar = {}; }; } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowModule.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowModule.cpp index 3db5b236d6..a13b873aee 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowModule.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowModule.cpp @@ -9,10 +9,20 @@ #include #include +void InitShaderManagementConsoleResources() +{ + // Must register qt resources from other modules + Q_INIT_RESOURCE(ShaderManagementConsole); + Q_INIT_RESOURCE(InspectorWidget); + Q_INIT_RESOURCE(AtomToolsAssetBrowser); +} + namespace ShaderManagementConsole { ShaderManagementConsoleWindowModule::ShaderManagementConsoleWindowModule() { + InitShaderManagementConsoleResources(); + // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { ShaderManagementConsoleWindowComponent::CreateDescriptor(), @@ -25,4 +35,4 @@ namespace ShaderManagementConsole azrtti_typeid(), }; } -} +} // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsolewindow_files.cmake b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsolewindow_files.cmake index 0d33d990a4..fb5cc0dad6 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsolewindow_files.cmake +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsolewindow_files.cmake @@ -14,9 +14,6 @@ set(FILES Source/Window/ShaderManagementConsoleWindow.h Source/Window/ShaderManagementConsoleWindow.cpp Source/Window/ShaderManagementConsoleWindowModule.cpp - Source/Window/ShaderManagementConsoleBrowserWidget.h - Source/Window/ShaderManagementConsoleBrowserWidget.cpp - Source/Window/ShaderManagementConsoleBrowserWidget.ui Source/Window/ShaderManagementConsole.qrc Source/Window/ShaderManagementConsoleWindowComponent.h Source/Window/ShaderManagementConsoleWindowComponent.cpp From 54de15b0ecd555a481c24f569e382d8a1e514ad0 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 18 Jan 2022 16:34:58 -0800 Subject: [PATCH 241/272] Adding '.network.spawnable' as a network constant Signed-off-by: Gene Walters --- .../Code/Include/Multiplayer/MultiplayerConstants.h | 1 + .../Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp | 3 ++- .../Code/Source/Pipeline/NetworkPrefabProcessor.cpp | 3 ++- Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerConstants.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerConstants.h index 4471aa0c2b..3a4a9b1f58 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerConstants.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerConstants.h @@ -20,6 +20,7 @@ namespace Multiplayer constexpr AZStd::string_view MpNetworkInterfaceName("MultiplayerNetworkInterface"); constexpr AZStd::string_view MpEditorInterfaceName("MultiplayerEditorNetworkInterface"); constexpr AZStd::string_view LocalHost("127.0.0.1"); + constexpr AZStd::string_view NetworkSpawnableFileExtension(".network.spawnable"); constexpr uint16_t DefaultServerPort = 33450; constexpr uint16_t DefaultServerEditorPort = 33451; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp index 7fb7bfdc39..e668d43267 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace Multiplayer { @@ -42,7 +43,7 @@ namespace Multiplayer auto enumerateCallback = [this](const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info) { if (info.m_assetType == AZ::AzTypeInfo::Uuid() && - info.m_relativePath.ends_with(".network.spawnable")) + info.m_relativePath.ends_with(NetworkSpawnableFileExtension)) { ProcessSpawnableAsset(info.m_relativePath, id); } diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index a797523bc0..9d6c47bb00 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -95,7 +96,7 @@ namespace Multiplayer using namespace AzToolsFramework::Prefab; AZStd::string uniqueName = prefab.GetName(); - uniqueName += ".network.spawnable"; + uniqueName += NetworkSpawnableFileExtension; auto serializer = [serializationFormat](AZStd::vector& output, const ProcessedObjectStore& object) -> bool { AZ::IO::ByteContainerStream stream(&output); diff --git a/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp b/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp index aef13fbfe2..32be828686 100644 --- a/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp +++ b/Gems/Multiplayer/Code/Tests/PrefabProcessingTests.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace UnitTest @@ -92,7 +93,7 @@ namespace UnitTest // Verify the name and the type of the spawnable asset const AZ::Data::AssetData& spawnableAsset = processedObjects[0].GetAsset(); - EXPECT_EQ(prefabName + ".network.spawnable", processedObjects[0].GetId()); + EXPECT_EQ(prefabName + Multiplayer::NetworkSpawnableFileExtension.data(), processedObjects[0].GetId()); EXPECT_EQ(spawnableAsset.GetType(), azrtti_typeid()); // Verify we have only the networked entity in the network spawnable and not the static one From 45429872d60d79c1daa8b7957e967cc2526e642a Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Tue, 18 Jan 2022 17:39:44 -0800 Subject: [PATCH 242/272] Switched back to making MaterialAsset::GetPropertyValues automatically finalize the material asset. I realized that it's too burdensome to expect client code to call Finalize on the MaterialAsset; every code that calls GetPropertyValues would have to call Finalize(). Instead of using const_cast in GetPropertyValues like I was doing before, I just changed GetPropertyValues to be a non-const function. There were a few places in Decal code I had to update to pass non-const MaterialAsset pointers. This isn't ideal, but I think it's better than the alternatives. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Code/Source/Decals/DecalTextureArray.cpp | 6 +- .../Code/Source/Decals/DecalTextureArray.h | 2 +- .../DecalTextureArrayFeatureProcessor.cpp | 6 +- .../DecalTextureArrayFeatureProcessor.h | 2 +- .../Atom/RPI.Reflect/Material/MaterialAsset.h | 29 ++++----- .../RPI.Builders/Material/MaterialBuilder.cpp | 2 +- .../Model/MaterialAssetBuilderComponent.cpp | 2 +- .../Source/RPI.Public/Material/Material.cpp | 2 - .../RPI.Reflect/Material/MaterialAsset.cpp | 33 ++++++---- .../Material/MaterialAssetCreator.cpp | 2 + .../Tests/Material/MaterialAssetTests.cpp | 61 +++++++++++++++++-- .../Material/MaterialSourceDataTests.cpp | 41 +++++-------- 12 files changed, 117 insertions(+), 71 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.cpp index 36a59bd07f..56ff1648d4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.cpp @@ -49,7 +49,7 @@ namespace AZ } // Extract exactly which texture asset we need to load from the given material and map type (diffuse, normal, etc). - static AZ::Data::Asset GetStreamingImageAsset(const AZ::RPI::MaterialAsset& materialAsset, const AZ::Name& propertyName) + static AZ::Data::Asset GetStreamingImageAsset(AZ::RPI::MaterialAsset& materialAsset, const AZ::Name& propertyName) { if (!materialAsset.IsReady()) { @@ -84,7 +84,7 @@ namespace AZ static AZ::Data::Asset GetStreamingImageAsset(const AZ::Data::Asset materialAssetData, const AZ::Name& propertyName) { AZ_Assert(materialAssetData->IsReady(), "GetStreamingImageAsset() called with AssetData that is not ready."); - const AZ::RPI::MaterialAsset* materialAsset = materialAssetData.GetAs(); + AZ::RPI::MaterialAsset* materialAsset = materialAssetData.GetAs(); return GetStreamingImageAsset(*materialAsset, propertyName); } } @@ -141,7 +141,7 @@ namespace AZ return m_textureArrayPacked[mapType]; } - bool DecalTextureArray::IsValidDecalMaterial(const AZ::RPI::MaterialAsset& materialAsset) + bool DecalTextureArray::IsValidDecalMaterial(AZ::RPI::MaterialAsset& materialAsset) { return GetStreamingImageAsset(materialAsset, GetMapName(DecalMapType_Diffuse)).IsReady(); } diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.h index 97bd8b9cbe..39e66176fd 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArray.h @@ -57,7 +57,7 @@ namespace AZ // often different (BC5 for normals, BC7 for diffuse, etc) const Data::Instance& GetPackedTexture(const DecalMapType mapType) const; - static bool IsValidDecalMaterial(const RPI::MaterialAsset& materialAsset); + static bool IsValidDecalMaterial(RPI::MaterialAsset& materialAsset); private: diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp index 393104907a..c6b4d4e754 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp @@ -25,7 +25,7 @@ namespace AZ { namespace { - static AZ::RHI::Size GetTextureSizeFromMaterialAsset(const AZ::RPI::MaterialAsset* materialAsset) + static AZ::RHI::Size GetTextureSizeFromMaterialAsset(AZ::RPI::MaterialAsset* materialAsset) { for (const auto& elem : materialAsset->GetPropertyValues()) { @@ -375,7 +375,7 @@ namespace AZ } } - AZStd::optional DecalTextureArrayFeatureProcessor::AddMaterialToTextureArrays(const AZ::RPI::MaterialAsset* materialAsset) + AZStd::optional DecalTextureArrayFeatureProcessor::AddMaterialToTextureArrays(AZ::RPI::MaterialAsset* materialAsset) { const RHI::Size textureSize = GetTextureSizeFromMaterialAsset(materialAsset); @@ -410,7 +410,7 @@ namespace AZ AZ_PROFILE_SCOPE(AzRender, "DecalTextureArrayFeatureProcessor: OnAssetReady"); const Data::AssetId& assetId = asset->GetId(); - const RPI::MaterialAsset* materialAsset = asset.GetAs(); + RPI::MaterialAsset* materialAsset = asset.GetAs(); const bool validDecalMaterial = materialAsset && DecalTextureArray::IsValidDecalMaterial(*materialAsset); if (validDecalMaterial) { diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h index fd535bbe64..bdd1739ebb 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h @@ -111,7 +111,7 @@ namespace AZ void CacheShaderIndices(); // This call could fail (returning nullopt) if we run out of texture arrays - AZStd::optional AddMaterialToTextureArrays(const AZ::RPI::MaterialAsset* materialAsset); + AZStd::optional AddMaterialToTextureArrays(AZ::RPI::MaterialAsset* materialAsset); int FindTextureArrayWithSize(const RHI::Size& size) const; void RemoveMaterialFromDecal(const uint16_t decalIndex); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h index 941fcd0fe9..b7cc51dcc4 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Material/MaterialAsset.h @@ -102,16 +102,6 @@ namespace AZ //! Returns a layout that includes a list of MaterialPropertyDescriptors for each material property. const MaterialPropertiesLayout* GetMaterialPropertiesLayout() const; - //! Returns whether the material's properties are fully processed or not. - //! If true, property values can be accessed through GetPropertyValues(). - //! If false, property values can be accessed through GetRawPropertyValues(). - bool IsFinalized() const; - - //! If the material asset is not finalized yet, this does the final processing of the raw property values to - //! get the material asset ready to be used. - //! Note the MaterialTypeAsset must be valid before this is called. - void Finalize(AZStd::function reportWarning = nullptr, AZStd::function reportError = nullptr); - //! Returns the list of values for all properties in this material. //! The entries in this list align with the entries in the MaterialPropertiesLayout. Each AZStd::any is guaranteed //! to have a value of type that matches the corresponding MaterialPropertyDescriptor. @@ -122,19 +112,26 @@ namespace AZ //! //! Calling GetPropertyValues() will automatically finalize the material asset if it isn't finalized already. The //! MaterialTypeAsset must be loaded and ready. - const AZStd::vector& GetPropertyValues() const; - + const AZStd::vector& GetPropertyValues(); + + //! Returns true if material was created in a finalize state, as opposed to being finalized after loading from disk. + bool WasPreFinalized() const; + //! Returns the list of raw values for all properties in this material, as listed in the source .material file(s), before the material asset was Finalized. //! //! The MaterialAsset can be created in a "half-baked" state (see MaterialUtils::BuildersShouldFinalizeMaterialAssets) where //! minimal processing has been done because it did not yet have access to the MaterialTypeAsset. In that case, the list will //! be populated with values copied from the source .material file with little or no validation or other processing. It includes //! all parent .material files, with properties listed in low-to-high priority order. - //! This list will be empty however if the asset was finalized at build-time. + //! This list will be empty however if the asset was finalized at build-time (i.e. WasPreFinalized() returns true). const AZStd::vector>& GetRawPropertyValues() const; private: bool PostLoadInit() override; + + //! If the material asset is not finalized yet, this does the final processing of the raw property values to get the material asset ready to be used. + //! MaterialTypeAsset must be valid before this is called. + void Finalize(AZStd::function reportWarning = nullptr, AZStd::function reportError = nullptr); //! Checks the material type version and potentially applies a series of property changes (most common are simple property renames) //! based on the MaterialTypeAsset's version update procedure. @@ -159,7 +156,7 @@ namespace AZ //! Holds values for each material property, used to initialize Material instances. //! This is indexed by MaterialPropertyIndex and aligns with entries in m_materialPropertiesLayout. - AZStd::vector m_propertyValues; + mutable AZStd::vector m_propertyValues; //! The MaterialAsset can be created in a "half-baked" state where minimal processing has been done because it does //! not yet have access to the MaterialTypeAsset. In that case, this list will be populated with values copied from @@ -175,10 +172,10 @@ namespace AZ AZStd::vector> m_rawPropertyValues; //! Tracks whether Finalize() has been called, meaning m_propertyValues is populated with data matching the material type's property layout. - bool m_isFinalized = false; + //! (This value is intentionally not serialized, it is set by the Finalize() function) + mutable bool m_isFinalized = false; //! Tracks whether the MaterialAsset was already in a finalized state when it was loaded. - //! (This value is intentionally not serialized) bool m_wasPreFinalized = false; //! The materialTypeVersion this materialAsset was based off. If the versions do not match at runtime when a diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index cedbb1df6e..768890a29b 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 114; // material dependency improvements + materialBuilderDescriptor.m_version = 115; // material dependency improvements updated materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index a44b47ee6c..9a92e7b762 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -128,7 +128,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(20); // material dependency improvements + ->Version(21); // material dependency improvements updated } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp index fe9dbef278..1f739c24f1 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp @@ -62,8 +62,6 @@ namespace AZ m_materialAsset = { &materialAsset, AZ::Data::AssetLoadBehavior::PreLoad }; - m_materialAsset->Finalize(); - // Cache off pointers to some key data structures from the material type... auto srgLayout = m_materialAsset->GetMaterialSrgLayout(); if (srgLayout) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 0325c3ac38..309daf8b62 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -33,12 +33,12 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(13) // added m_rawPropertyValues + ->Version(14) // added m_rawPropertyValues ->Field("materialTypeAsset", &MaterialAsset::m_materialTypeAsset) ->Field("materialTypeVersion", &MaterialAsset::m_materialTypeVersion) ->Field("propertyValues", &MaterialAsset::m_propertyValues) ->Field("rawPropertyValues", &MaterialAsset::m_rawPropertyValues) - ->Field("isFinalized", &MaterialAsset::m_isFinalized) + ->Field("finalized", &MaterialAsset::m_wasPreFinalized) ; } } @@ -104,19 +104,19 @@ namespace AZ return m_materialTypeAsset->GetMaterialPropertiesLayout(); } - bool MaterialAsset::IsFinalized() const + bool MaterialAsset::WasPreFinalized() const { - if (m_isFinalized) - { - AZ_Assert(GetMaterialPropertiesLayout() && m_propertyValues.size() == GetMaterialPropertiesLayout()->GetPropertyCount(), "MaterialAsset is marked as Finalized but does not have the right number of property values."); - } - - return m_isFinalized; + return m_wasPreFinalized; } void MaterialAsset::Finalize(AZStd::function reportWarning, AZStd::function reportError) { - if (IsFinalized()) + if (m_wasPreFinalized) + { + m_isFinalized = true; + } + + if (m_isFinalized) { return; } @@ -197,10 +197,18 @@ namespace AZ m_isFinalized = true; } - const AZStd::vector& MaterialAsset::GetPropertyValues() const + const AZStd::vector& MaterialAsset::GetPropertyValues() { - AZ_Error(s_debugTraceName, IsFinalized(), "MaterialAsset must be finalized before its property values can be accessed"); + // This can't be done in MaterialAssetHandler::LoadAssetData because the MaterialTypeAsset isn't necessarily loaded at that point. + // And it can't be done in PostLoadInit() because that happens on the next frame which might be too late. + // And overriding AssetHandler::InitAsset in MaterialAssetHandler didn't work, because there seems to be non-determinism on the order + // of InitAsset calls when a ModelAsset references a MaterialAsset, the model gets initialized first and then fails to use the material. + // So we finalize just-in-time when properties are accessed. + // If we could solve the problem with InitAsset, that would be the ideal place to call Finalize() and we could make GetPropertyValues() const again. + Finalize(); + AZ_Assert(GetMaterialPropertiesLayout() && m_propertyValues.size() == GetMaterialPropertiesLayout()->GetPropertyCount(), "MaterialAsset should be finalized but does not have the right number of property values."); + return m_propertyValues; } @@ -334,7 +342,6 @@ namespace AZ if (Base::LoadAssetData(asset, stream, assetLoadFilterCB) == Data::AssetHandler::LoadResult::LoadComplete) { asset.GetAs()->AssetInitBus::Handler::BusConnect(); - asset.GetAs()->m_wasPreFinalized = asset.GetAs()->m_isFinalized; return Data::AssetHandler::LoadResult::LoadComplete; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp index 7d4ecf0b18..872e4ad754 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAssetCreator.cpp @@ -49,6 +49,8 @@ namespace AZ [this](const char* message) { ReportWarning("%s", message); }, [this](const char* message) { ReportError("%s", message); }); + m_asset->m_wasPreFinalized = true; + // Finalize() doesn't clear the raw property data because that's the same function used at runtime, which does need to maintain the raw data // to support hot reload. But here we are pre-baking with the assumption that AP build dependencies will keep the material type // and material asset in sync, so we can discard the raw property data and just rely on the data in the material type asset. diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp index fdb131d449..61e1283f52 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp @@ -111,6 +111,10 @@ namespace UnitTest EXPECT_EQ(assetId, materialAsset->GetId()); EXPECT_EQ(Data::AssetData::AssetStatus::Ready, materialAsset->GetStatus()); + + EXPECT_TRUE(materialAsset->WasPreFinalized()); + EXPECT_EQ(0, materialAsset->GetRawPropertyValues().size()); + validate(materialAsset); // Also test serialization... @@ -123,6 +127,57 @@ namespace UnitTest Data::Asset serializedAsset = tester.SerializeIn(Data::AssetId(Uuid::CreateRandom()), noAssets); validate(serializedAsset); } + + TEST_F(MaterialAssetTests, DeferredFinalize) + { + Data::AssetId assetId(Uuid::CreateRandom()); + + MaterialAssetCreator creator; + bool shouldFinalize = false; + creator.Begin(assetId, m_testMaterialTypeAsset, shouldFinalize); + + creator.SetPropertyValue(Name{ "MyFloat2" }, Vector2{ 0.1f, 0.2f }); + creator.SetPropertyValue(Name{ "MyFloat3" }, Vector3{ 1.1f, 1.2f, 1.3f }); + creator.SetPropertyValue(Name{ "MyFloat4" }, Vector4{ 2.1f, 2.2f, 2.3f, 2.4f }); + creator.SetPropertyValue(Name{ "MyColor" }, Color{ 1.0f, 1.0f, 1.0f, 1.0f }); + creator.SetPropertyValue(Name{ "MyInt" }, -2); + creator.SetPropertyValue(Name{ "MyUInt" }, 12u); + creator.SetPropertyValue(Name{ "MyFloat" }, 1.5f); + creator.SetPropertyValue(Name{ "MyBool" }, true); + creator.SetPropertyValue(Name{ "MyImage" }, m_testImageAsset); + creator.SetPropertyValue(Name{ "MyEnum" }, 1u); + + Data::Asset materialAsset; + EXPECT_TRUE(creator.End(materialAsset)); + + EXPECT_FALSE(materialAsset->WasPreFinalized()); + EXPECT_EQ(10, materialAsset->GetRawPropertyValues().size()); + + // Also test serialization... + + SerializeTester tester(GetSerializeContext()); + tester.SerializeOut(materialAsset.Get()); + + // Using a filter that skips loading assets because we are using a dummy image asset + ObjectStream::FilterDescriptor noAssets{ AZ::Data::AssetFilterNoAssetLoading }; + Data::Asset serializedAsset = tester.SerializeIn(Data::AssetId(Uuid::CreateRandom()), noAssets); + + EXPECT_FALSE(materialAsset->WasPreFinalized()); + EXPECT_EQ(10, materialAsset->GetRawPropertyValues().size()); + + // GetPropertyValues() will automatically finalize the material asset, so we can go ahead and check the property values. + EXPECT_EQ(materialAsset->GetPropertyValues().size(), 10); + EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue(), true); + EXPECT_EQ(materialAsset->GetPropertyValues()[1].GetValue(), -2); + EXPECT_EQ(materialAsset->GetPropertyValues()[2].GetValue(), 12); + EXPECT_EQ(materialAsset->GetPropertyValues()[3].GetValue(), 1.5f); + EXPECT_EQ(materialAsset->GetPropertyValues()[4].GetValue(), Vector2(0.1f, 0.2f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[5].GetValue(), Vector3(1.1f, 1.2f, 1.3f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[6].GetValue(), Vector4(2.1f, 2.2f, 2.3f, 2.4f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[7].GetValue(), Color(1.0f, 1.0f, 1.0f, 1.0f)); + EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue>(), m_testImageAsset); + EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue(), 1u); + } TEST_F(MaterialAssetTests, PropertyDefaultValuesComeFromParentMaterial) { @@ -267,15 +322,13 @@ namespace UnitTest warningFinder.AddExpectedErrorMessage("This material is based on version '1'"); warningFinder.AddExpectedErrorMessage("material type is now at version '2'"); - materialAsset->Finalize(); - - warningFinder.CheckExpectedErrorsFound(); - // Even though this material was created using the old version of the material type, it's property values should get automatically // updated to align with the new property layout in the latest MaterialTypeAsset. MaterialPropertyIndex myIntIndex = materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(Name{"MyIntRenamed"}); EXPECT_EQ(2, myIntIndex.GetIndex()); EXPECT_EQ(7, materialAsset->GetPropertyValues()[myIntIndex.GetIndex()].GetValue()); + + warningFinder.CheckExpectedErrorsFound(); // Since the MaterialAsset has already been updated, and the warning reported once, we should not see the "consider updating" // warning reported again on subsequent property accesses. diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index 29f0e7d101..ef89e0138c 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -182,7 +182,7 @@ namespace UnitTest Data::Asset materialAsset = materialAssetOutcome.GetValue(); - EXPECT_TRUE(materialAsset->IsFinalized()); + EXPECT_TRUE(materialAsset->WasPreFinalized()); EXPECT_EQ(0, materialAsset->GetRawPropertyValues().size()); // A pre-baked material has no need for the original raw property names and values // The order here is based on the order in the MaterialTypeSourceData, as added to the MaterialTypeAssetCreator. @@ -227,14 +227,10 @@ namespace UnitTest EXPECT_TRUE(materialAssetOutcome.IsSuccess()); Data::Asset materialAsset = materialAssetOutcome.GetValue(); - - ErrorMessageFinder expectNotFinalizedError("MaterialAsset must be finalized"); - EXPECT_FALSE(materialAsset->IsFinalized()); + EXPECT_FALSE(materialAsset->WasPreFinalized()); - expectNotFinalizedError.ResetCounts(); - EXPECT_TRUE(materialAsset->GetPropertyValues().empty()); - expectNotFinalizedError.CheckExpectedErrorsFound(); + // Note we avoid calling GetPropertyValues() because that will auto-finalize the material. We want to check its raw property values first. auto findRawPropertyValue = [materialAsset](const char* propertyId) { @@ -279,16 +275,10 @@ namespace UnitTest SerializeTester tester(GetSerializeContext()); tester.SerializeOut(materialAsset.Get()); materialAsset = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); - - // We check that everything is still in the original un-finalized state after going through the serialization process. - EXPECT_FALSE(materialAsset->IsFinalized()); - checkRawPropertyValues(); - expectNotFinalizedError.ResetCounts(); - EXPECT_TRUE(materialAsset->GetPropertyValues().empty()); - expectNotFinalizedError.CheckExpectedErrorsFound(); - materialAsset->Finalize(); - EXPECT_TRUE(materialAsset->IsFinalized()); + // We check that the asset is still in the original un-finalized state after going through the serialization process. + EXPECT_FALSE(materialAsset->WasPreFinalized()); + checkRawPropertyValues(); // Now all the property values should be available through the main GetPropertyValues() API. EXPECT_EQ(materialAsset->GetPropertyValues()[0].GetValue(), true); @@ -301,8 +291,9 @@ namespace UnitTest EXPECT_EQ(materialAsset->GetPropertyValues()[7].GetValue(), Color(0.1f, 0.2f, 0.3f, 0.4f)); EXPECT_EQ(materialAsset->GetPropertyValues()[8].GetValue>(), m_testImageAsset); EXPECT_EQ(materialAsset->GetPropertyValues()[9].GetValue(), 1u); - + // The raw property values are still available (because they are needed if a hot-reload of the MaterialTypeAsset occurs) + EXPECT_FALSE(materialAsset->WasPreFinalized()); checkRawPropertyValues(); } @@ -659,19 +650,19 @@ namespace UnitTest auto materialAssetLevel1 = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel1.IsSuccess()); - EXPECT_TRUE(materialAssetLevel1.GetValue()->IsFinalized()); + EXPECT_TRUE(materialAssetLevel1.GetValue()->WasPreFinalized()); m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetValue().GetId()); auto materialAssetLevel2 = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel2.IsSuccess()); - EXPECT_TRUE(materialAssetLevel2.GetValue()->IsFinalized()); + EXPECT_TRUE(materialAssetLevel2.GetValue()->WasPreFinalized()); m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetValue().GetId()); auto materialAssetLevel3 = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::PreBake, true); EXPECT_TRUE(materialAssetLevel3.IsSuccess()); - EXPECT_TRUE(materialAssetLevel3.GetValue()->IsFinalized()); + EXPECT_TRUE(materialAssetLevel3.GetValue()->WasPreFinalized()); auto layout = m_testMaterialTypeAsset->GetMaterialPropertiesLayout(); MaterialPropertyIndex myFloat = layout->FindPropertyIndex(Name("general.MyFloat")); @@ -731,21 +722,21 @@ namespace UnitTest auto materialAssetLevel1Result = sourceDataLevel1.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); EXPECT_TRUE(materialAssetLevel1Result.IsSuccess()); Data::Asset materialAssetLevel1 = materialAssetLevel1Result.TakeValue(); - EXPECT_FALSE(materialAssetLevel1->IsFinalized()); + EXPECT_FALSE(materialAssetLevel1->WasPreFinalized()); m_assetSystemStub.RegisterSourceInfo("level1.material", materialAssetLevel1.GetId()); auto materialAssetLevel2Result = sourceDataLevel2.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); EXPECT_TRUE(materialAssetLevel2Result.IsSuccess()); Data::Asset materialAssetLevel2 = materialAssetLevel2Result.TakeValue(); - EXPECT_FALSE(materialAssetLevel2->IsFinalized()); + EXPECT_FALSE(materialAssetLevel2->WasPreFinalized()); m_assetSystemStub.RegisterSourceInfo("level2.material", materialAssetLevel2.GetId()); auto materialAssetLevel3Result = sourceDataLevel3.CreateMaterialAsset(Uuid::CreateRandom(), "", MaterialAssetProcessingMode::DeferredBake, true); EXPECT_TRUE(materialAssetLevel3Result.IsSuccess()); Data::Asset materialAssetLevel3 = materialAssetLevel3Result.TakeValue(); - EXPECT_FALSE(materialAssetLevel3->IsFinalized()); + EXPECT_FALSE(materialAssetLevel3->WasPreFinalized()); // Now we'll create the material type asset in memory so the materials will have what they need to finalize. Data::Asset testMaterialTypeAsset = CreateTestMaterialTypeAsset(materialTypeAssetId); @@ -766,9 +757,7 @@ namespace UnitTest tester.SerializeOut(materialAssetLevel3.Get()); materialAssetLevel3 = tester.SerializeIn(Uuid::CreateRandom(), ObjectStream::FilterDescriptor{AZ::Data::AssetFilterNoAssetLoading}); - materialAssetLevel1->Finalize(); - materialAssetLevel2->Finalize(); - materialAssetLevel3->Finalize(); + // The properties will finalize automatically when we call GetPropertyValues()... AZStd::array_view properties; From a896ff11bc3aa8f13696e078e66fee1dbcf269ae Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 14 Jan 2022 12:57:52 -0800 Subject: [PATCH 243/272] Changed .material serialization to avoid loading the .materialtype file, since the .material builder doesn't declare a source dependency on the .materialtype. Otherwise there can be ambiguous edge cases where changes to the .materialtype might or might not impact the baked MaterialAsset. Note that another option would have been to add a the appropriate source dependency, but that would hurt iteration time as any change to the .materialtype file would cause every .material file and .fbx to rebuild. These changes have the added benefit of simplifying some of the serialization code. MaterialSourceDataSerializer is no longer needed, as its main purpose was to pass the MaterialTypeSourceData down to the MaterialPropertyValueSerializer. Before, the JSON serialization system gave a lot of data flexibility because it did best-effort conversions, like allowing a float to be loaded as an int for example. But now the material serialization code doesn't know target data type, so it has to assume the data type based on what's in the .material file, and then the MaterialAsset will convert the data to the appropriate type later when Finalize() is called. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../MaterialPropertyValueSerializer.h | 7 - .../MaterialPropertyValueSourceData.h | 2 +- .../Material/MaterialSourceDataSerializer.h | 40 -- .../Material/MaterialTypeSourceData.h | 6 +- .../MaterialPropertyValueSerializer.cpp | 106 +++-- .../RPI.Edit/Material/MaterialSourceData.cpp | 21 +- .../Material/MaterialSourceDataSerializer.cpp | 162 ------- .../Material/MaterialTypeSourceData.cpp | 11 +- .../RPI.Reflect/Material/MaterialAsset.cpp | 132 +++++- .../Tests/Material/MaterialAssetTests.cpp | 32 +- .../Material/MaterialSourceDataTests.cpp | 410 ++++++++++-------- Gems/Atom/RPI/Code/atom_rpi_edit_files.cmake | 2 - 12 files changed, 450 insertions(+), 481 deletions(-) delete mode 100644 Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h delete mode 100644 Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSerializer.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSerializer.h index 29371618cf..befbb7c990 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSerializer.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSerializer.h @@ -24,13 +24,6 @@ namespace AZ AZ_RTTI(AZ::RPI::JsonMaterialPropertyValueSerializer, "{A52B1ED8-C849-4269-9AA7-9D0814D2EC59}", BaseJsonSerializer); AZ_CLASS_ALLOCATOR_DECL; - //! A LoadContext object must be passed down to the serializer via JsonDeserializerContext::GetMetadata().Add(...) - struct LoadContext - { - AZ_TYPE_INFO(JsonMaterialPropertyValueSerializer::LoadContext, "{5E0A891A-27F6-4AD7-88A5-B9EA50F88B45}"); - uint32_t m_materialTypeVersion; //!< The version number from the .materialtype file - }; - JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h index 178cacba15..a0640a1522 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h @@ -54,7 +54,7 @@ namespace AZ //! The resolved value with a valid type of a property. It needs to be mutable to allow post-resolving when parent objects are declared as const. mutable MaterialPropertyValue m_resolvedValue; //! Candidate values from serialization. - AZStd::map m_possibleValues; + AZStd::map m_possibleValues; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h deleted file mode 100644 index 301b80ed82..0000000000 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -namespace AZ -{ - class ReflectContext; - - namespace RPI - { - //! This custom serializer is needed to load the material type file and saves its data in the - //! JsonDeserializerSettings for JsonMaterialPropertyValueSerializer to use. - //! (Note we could have made a custom serializer specifically for the 'materialType' field but that - //! would require 'materialType' to appear before 'properties'. By having a custom serializer for the common - //! parent of 'materialType' and 'properties', we can avoid an order dependency within the JSON file). - class JsonMaterialSourceDataSerializer - : public BaseJsonSerializer - { - public: - AZ_RTTI(AZ::RPI::JsonMaterialSourceDataSerializer, "{008A7423-8DF6-4BA3-BF5E-B0C189CCBE58}", BaseJsonSerializer); - AZ_CLASS_ALLOCATOR_DECL; - - JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, - JsonDeserializerContext& context) override; - - JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, - const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; - }; - - } // namespace RPI -} // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h index f5336807c7..9333880594 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialTypeSourceData.h @@ -186,9 +186,8 @@ namespace AZ //! Searches for a specific property. //! Note this function can find properties using old versions of the property name; in that case, //! the name in the returned PropertyDefinition* will not match the @propertyName that was searched for. - //! @param materialTypeVersion indicates the version number of the property name being passed in. Only renames above this version number will be applied. //! @return the requested property, or null if it could not be found - const PropertyDefinition* FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName, uint32_t materialTypeVersion = 0) const; + const PropertyDefinition* FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName) const; //! Construct a complete list of group definitions, including implicit groups, arranged in the same order as the source data //! Groups with the same name will be consolidated into a single entry @@ -212,9 +211,8 @@ namespace AZ Outcome> CreateMaterialTypeAsset(Data::AssetId assetId, AZStd::string_view materialTypeSourceFilePath = "", bool elevateWarnings = true) const; //! Possibly renames @propertyId based on the material version update steps. - //! @param materialTypeVersion indicates the version number of the property name being passed in. Only renames above this version number will be applied. //! @return true if the property was renamed - bool ApplyPropertyRenames(MaterialPropertyId& propertyId, uint32_t materialTypeVersion = 0) const; + bool ApplyPropertyRenames(MaterialPropertyId& propertyId) const; }; //! The wrapper class for derived material functors. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp index 5e04365ffb..10b45ca8df 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -55,15 +54,6 @@ namespace AZ MaterialSourceData::Property* property = reinterpret_cast(outputValue); AZ_Assert(property, "Output value for JsonMaterialPropertyValueSerializer can't be null."); - const MaterialTypeSourceData* materialType = context.GetMetadata().Find(); - if (!materialType) - { - AZ_Assert(false, "Material type reference not found"); - return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Catastrophic, "Material type reference not found."); - } - - const JsonMaterialPropertyValueSerializer::LoadContext* loadContext = context.GetMetadata().Find(); - // Construct the full property name (groupName.propertyName) by parsing it from the JSON path string. size_t startPropertyName = context.GetPath().Get().rfind('/'); size_t startGroupName = context.GetPath().Get().rfind('/', startPropertyName-1); @@ -72,47 +62,69 @@ namespace AZ JSR::ResultCode result(JSR::Tasks::ReadField); - auto propertyDefinition = materialType->FindProperty(groupName, propertyName, loadContext->m_materialTypeVersion); - if (!propertyDefinition) + if (inputValue.IsBool()) { - AZStd::string message = AZStd::string::format("Property '%.*s.%.*s' not found in material type.", AZ_STRING_ARG(groupName), AZ_STRING_ARG(propertyName)); - return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, message); + result.Combine(LoadVariant(property->m_value, false, inputValue, context)); + } + else if (inputValue.IsInt() || inputValue.IsInt64()) + { + result.Combine(LoadVariant(property->m_value, 0, inputValue, context)); + } + else if (inputValue.IsUint() || inputValue.IsUint64()) + { + result.Combine(LoadVariant(property->m_value, 0u, inputValue, context)); + } + else if (inputValue.IsFloat() || inputValue.IsDouble()) + { + result.Combine(LoadVariant(property->m_value, 0.0f, inputValue, context)); + } + else if (inputValue.IsArray() && inputValue.Size() == 4) + { + result.Combine(LoadVariant(property->m_value, Vector4{0.0f, 0.0f, 0.0f, 0.0f}, inputValue, context)); + } + else if (inputValue.IsArray() && inputValue.Size() == 3) + { + result.Combine(LoadVariant(property->m_value, Vector3{0.0f, 0.0f, 0.0f}, inputValue, context)); + } + else if (inputValue.IsArray() && inputValue.Size() == 2) + { + result.Combine(LoadVariant(property->m_value, Vector2{0.0f, 0.0f}, inputValue, context)); + } + else if (inputValue.IsObject()) + { + JsonSerializationResult::ResultCode resultCode = LoadVariant(property->m_value, Color::CreateZero(), inputValue, context); + + if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) + { + resultCode = LoadVariant(property->m_value, Vector4::CreateZero(), inputValue, context); + } + + if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) + { + resultCode = LoadVariant(property->m_value, Vector3::CreateZero(), inputValue, context); + } + + if(resultCode.GetProcessing() != JsonSerializationResult::Processing::Completed) + { + resultCode = LoadVariant(property->m_value, Vector2::CreateZero(), inputValue, context); + } + + if(resultCode.GetProcessing() == JsonSerializationResult::Processing::Completed) + { + result.Combine(resultCode); + } + else + { + return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, "Unknown data type"); + } + } + else if (inputValue.IsString()) + { + result.Combine(LoadVariant(property->m_value, AZStd::string{}, inputValue, context)); } else { - switch (propertyDefinition->m_dataType) - { - case MaterialPropertyDataType::Bool: - result.Combine(LoadVariant(property->m_value, false, inputValue, context)); - break; - case MaterialPropertyDataType::Int: - result.Combine(LoadVariant(property->m_value, 0, inputValue, context)); - break; - case MaterialPropertyDataType::UInt: - result.Combine(LoadVariant(property->m_value, 0u, inputValue, context)); - break; - case MaterialPropertyDataType::Float: - result.Combine(LoadVariant(property->m_value, 0.0f, inputValue, context)); - break; - case MaterialPropertyDataType::Vector2: - result.Combine(LoadVariant(property->m_value, Vector2{0.0f, 0.0f}, inputValue, context)); - break; - case MaterialPropertyDataType::Vector3: - result.Combine(LoadVariant(property->m_value, Vector3{0.0f, 0.0f, 0.0f}, inputValue, context)); - break; - case MaterialPropertyDataType::Vector4: - result.Combine(LoadVariant(property->m_value, Vector4{0.0f, 0.0f, 0.0f, 0.0f}, inputValue, context)); - break; - case MaterialPropertyDataType::Color: - result.Combine(LoadVariant(property->m_value, AZ::Colors::White, inputValue, context)); - break; - case MaterialPropertyDataType::Image: - case MaterialPropertyDataType::Enum: - result.Combine(LoadVariant(property->m_value, AZStd::string{}, inputValue, context)); - break; - default: - return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, "Unknown data type"); - } + return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Unsupported, "Unknown data type"); } if (result.GetProcessing() == JsonSerializationResult::Processing::Completed) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index bc764ec7fb..b921b186c0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -45,13 +44,17 @@ namespace AZ { if (JsonRegistrationContext* jsonContext = azrtti_cast(context)) { - jsonContext->Serializer()->HandlesType(); jsonContext->Serializer()->HandlesType(); } else if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(1) + ->Version(2) + ->Field("description", &MaterialSourceData::m_description) + ->Field("materialType", &MaterialSourceData::m_materialType) + ->Field("materialTypeVersion", &MaterialSourceData::m_materialTypeVersion) + ->Field("parentMaterial", &MaterialSourceData::m_parentMaterial) + ->Field("properties", &MaterialSourceData::m_properties) ; serializeContext->RegisterGenericType(); @@ -80,6 +83,12 @@ namespace AZ MaterialAssetCreator materialAssetCreator; materialAssetCreator.SetElevateWarnings(elevateWarnings); + if (m_materialType.empty()) + { + AZ_Error("MaterialSourceData", false, "materialType was not specified"); + return Failure(); + } + Outcome materialTypeAssetId = AssetUtils::MakeAssetId(materialSourceFilePath, m_materialType, 0); if (!materialTypeAssetId) { @@ -194,6 +203,12 @@ namespace AZ bool elevateWarnings, AZStd::unordered_set* sourceDependencies) const { + if (m_materialType.empty()) + { + AZ_Error("MaterialSourceData", false, "materialType was not specified"); + return Failure(); + } + const auto materialTypeSourcePath = AssetUtils::ResolvePathReference(materialSourceFilePath, m_materialType); const auto materialTypeAssetId = AssetUtils::MakeAssetId(materialTypeSourcePath, 0); if (!materialTypeAssetId.IsSuccess()) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp deleted file mode 100644 index 2a504fc345..0000000000 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AZ -{ - namespace RPI - { - AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialSourceDataSerializer, SystemAllocator, 0); - - JsonSerializationResult::Result JsonMaterialSourceDataSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, - const rapidjson::Value& inputValue, JsonDeserializerContext& context) - { - namespace JSR = JsonSerializationResult; - - AZ_Assert(azrtti_typeid() == outputValueTypeId, - "Unable to deserialize material to json because the provided type is %s", - outputValueTypeId.ToString().c_str()); - AZ_UNUSED(outputValueTypeId); - - MaterialSourceData* materialSourceData = reinterpret_cast(outputValue); - AZ_Assert(materialSourceData, "Output value for JsonMaterialSourceDataSerializer can't be null."); - - JSR::ResultCode result(JSR::Tasks::ReadField); - - if (!inputValue.IsObject()) - { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Material data must be a JSON object"); - } - - result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_description, azrtti_typeid(), inputValue, "description", context)); - result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_parentMaterial, azrtti_typeid(), inputValue, "parentMaterial", context)); - result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_materialType, azrtti_typeid(), inputValue, "materialType", context)); - result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_materialTypeVersion, azrtti_typeid(), inputValue, "materialTypeVersion", context)); - - if (materialSourceData->m_materialType.empty()) - { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Required field 'materialType' is missing or invalid"); - } - - JsonFileLoadContext* jsonFileLoadContext = context.GetMetadata().Find(); - - if (!jsonFileLoadContext) - { - // Go ahead and create a JsonFileLoadContext because we'll need to use it below when loading the material type - context.GetMetadata().Add(JsonFileLoadContext{}); - jsonFileLoadContext = context.GetMetadata().Find(); - } - - // Load the material type file because we need the property type information in order to know how to read the property values - MaterialTypeSourceData materialTypeData; - { - AZStd::string materialTypePath = AssetUtils::ResolvePathReference(jsonFileLoadContext->GetFilePath(), materialSourceData->m_materialType); - - auto materialTypeJson = JsonSerializationUtils::ReadJsonFile(materialTypePath, AZ::RPI::JsonUtils::DefaultMaxFileSize); - if (!materialTypeJson.IsSuccess()) - { - AZStd::string failureMessage; - failureMessage = AZStd::string::format("Failed to load material-type file '%s': %s", materialTypePath.c_str(), materialTypeJson.GetError().c_str()); - ScopedContextPath subPath{context, "materialType"}; - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, failureMessage); - } - else - { - // Since we're about to load a different file the JsonFileLoadContext needs to be changed to reflect the file that's being loaded. - jsonFileLoadContext->PushFilePath(materialTypePath); - - // We also need a special reporting function for the material type, to note the fact that the issue is in the material type not this file. - auto reportingPrev = context.GetReporter(); - context.PushReporter([materialTypePath, reportingPrev](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view path) -> JSR::ResultCode - { - AZStd::string materialTypeFilename; - if (!AzFramework::StringFunc::Path::GetFullFileName(materialTypePath.c_str(), materialTypeFilename)) - { - materialTypeFilename = materialTypePath; - } - - AZStd::string newPath = AZStd::string::format("[%.*s]%.*s", AZ_STRING_ARG(materialTypeFilename), AZ_STRING_ARG(path)); - return reportingPrev(message, result, newPath); - }); - - JsonDeserializerSettings settings; - settings.m_metadata = context.GetMetadata(); - settings.m_reporting = context.GetReporter(); - settings.m_registrationContext = context.GetRegistrationContext(); - settings.m_serializeContext = context.GetSerializeContext(); - settings.m_clearContainers = context.ShouldClearContainers(); - - JsonSerializationResult::ResultCode materialTypeLoadResult = JsonSerialization::Load(materialTypeData, materialTypeJson.GetValue(), settings); - materialTypeData.ResolveUvEnums(); - - // Restore prior configuration - context.PopReporter(); - jsonFileLoadContext->PopFilePath(); - - // Even though results from the material type file is a separate JSON serialization, we combine the results to make sure - // any issues are bubbled up. I'm not sure if this is the most desirable approach, but better to over-report issues than - // under-report them. - result.Combine(materialTypeLoadResult); - } - } - - context.GetMetadata().Add(AZStd::move(materialTypeData)); - - JsonMaterialPropertyValueSerializer::LoadContext materialPropertyValueLoadContext; - materialPropertyValueLoadContext.m_materialTypeVersion = materialSourceData->m_materialTypeVersion; - context.GetMetadata().Add(materialPropertyValueLoadContext); - - result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_properties, azrtti_typeid(), inputValue, "properties", context)); - - if (result.GetProcessing() == JsonSerializationResult::Processing::Completed) - { - return context.Report(result, "Successfully loaded material."); - } - else - { - return context.Report(result, "Partially loaded material."); - } - } - - - JsonSerializationResult::Result JsonMaterialSourceDataSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, - [[maybe_unused]] const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) - { - namespace JSR = JsonSerializationResult; - - AZ_Assert(azrtti_typeid() == valueTypeId, - "Unable to serialize material to json because the provided type is %s", - valueTypeId.ToString().c_str()); - AZ_UNUSED(valueTypeId); - - const MaterialSourceData* materialSourceData = reinterpret_cast(inputValue); - AZ_Assert(materialSourceData, "Input value for JsonMaterialSourceDataSerializer can't be null."); - - JSR::ResultCode resultCode(JSR::Tasks::ReadField); - resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "description", &materialSourceData->m_description, nullptr, azrtti_typeid(), context)); - resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "parentMaterial", &materialSourceData->m_parentMaterial, nullptr, azrtti_typeid(), context)); - resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "materialType", &materialSourceData->m_materialType, nullptr, azrtti_typeid(), context)); - resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "materialTypeVersion", &materialSourceData->m_materialTypeVersion, nullptr, azrtti_typeid(), context)); - resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "properties", &materialSourceData->m_properties, nullptr, azrtti_typeid(), context)); - - return context.Report(resultCode, "Processed material."); - } - } // namespace RPI -} // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp index d8e6c156be..87c064f571 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp @@ -130,17 +130,12 @@ namespace AZ return nullptr; } - bool MaterialTypeSourceData::ApplyPropertyRenames(MaterialPropertyId& propertyId, uint32_t materialTypeVersion) const + bool MaterialTypeSourceData::ApplyPropertyRenames(MaterialPropertyId& propertyId) const { bool renamed = false; for (const VersionUpdateDefinition& versionUpdate : m_versionUpdates) { - if (materialTypeVersion >= versionUpdate.m_toVersion) - { - continue; - } - for (const VersionUpdatesRenameOperationDefinition& action : versionUpdate.m_actions) { if (action.m_operation == "rename") @@ -161,7 +156,7 @@ namespace AZ return renamed; } - const MaterialTypeSourceData::PropertyDefinition* MaterialTypeSourceData::FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName, uint32_t materialTypeVersion) const + const MaterialTypeSourceData::PropertyDefinition* MaterialTypeSourceData::FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName) const { auto groupIter = m_propertyLayout.m_properties.find(groupName); if (groupIter != m_propertyLayout.m_properties.end()) @@ -178,7 +173,7 @@ namespace AZ // Property has not been found, try looking for renames in the version history MaterialPropertyId propertyId = MaterialPropertyId{groupName, propertyName}; - ApplyPropertyRenames(propertyId, materialTypeVersion); + ApplyPropertyRenames(propertyId); // Do the search again with the new names diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 309daf8b62..8bf975fd82 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -109,6 +109,77 @@ namespace AZ return m_wasPreFinalized; } + template + MaterialPropertyValue CastNumericMaterialPropertyValue(const MaterialPropertyValue& value) + { + TypeId typeId = value.GetTypeId(); + + if (typeId == azrtti_typeid()) + { + return aznumeric_cast(value.GetValue()); + } + else if (typeId == azrtti_typeid()) + { + return aznumeric_cast(value.GetValue()); + } + else if (typeId == azrtti_typeid()) + { + return aznumeric_cast(value.GetValue()); + } + else if (typeId == azrtti_typeid()) + { + return aznumeric_cast(value.GetValue()); + } + else + { + return value; + } + } + + + + template + MaterialPropertyValue CastVectorMaterialPropertyValue(const MaterialPropertyValue& value) + { + float values[4] = {}; + + TypeId typeId = value.GetTypeId(); + if (typeId == azrtti_typeid()) + { + value.GetValue().StoreToFloat2(values); + } + else if (typeId == azrtti_typeid()) + { + value.GetValue().StoreToFloat3(values); + } + else if (typeId == azrtti_typeid()) + { + value.GetValue().StoreToFloat4(values); + } + else + { + return value; + } + + typeId = azrtti_typeid(); + if (typeId == azrtti_typeid()) + { + return Vector2::CreateFromFloat2(values); + } + else if (typeId == azrtti_typeid()) + { + return Vector3::CreateFromFloat3(values); + } + else if (typeId == azrtti_typeid()) + { + return Vector4::CreateFromFloat4(values); + } + else + { + return value; + } + } + void MaterialAsset::Finalize(AZStd::function reportWarning, AZStd::function reportError) { if (m_wasPreFinalized) @@ -180,9 +251,66 @@ namespace AZ } else { - if (ValidateMaterialPropertyDataType(value.GetTypeId(), name, propertyDescriptor, reportError)) + // The material asset could be finalized sometime after the original JSON is loaded, and the material type might not have been available + // at that time, so the data type would not be known for each property. So each raw property's type could be based on what appeared in the JSON + // and this is the first opportunity we have to resolve that value with the actual type. For example, a float property could have been specified in + // the JSON as 7 instead of 7.0, which is valid. Similarly, a Color and a Vector3 can both be specified as "[0.0,0.0,0.0]" in the JSON file. + + MaterialPropertyValue finalValue = value; + + switch (propertyDescriptor->GetDataType()) { - finalizedPropertyValues[propertyIndex.GetIndex()] = value; + case MaterialPropertyDataType::Bool: + finalValue = CastNumericMaterialPropertyValue(value); + break; + case MaterialPropertyDataType::Int: + finalValue = CastNumericMaterialPropertyValue(value); + break; + case MaterialPropertyDataType::UInt: + finalValue = CastNumericMaterialPropertyValue(value); + break; + case MaterialPropertyDataType::Float: + finalValue = CastNumericMaterialPropertyValue(value); + break; + case MaterialPropertyDataType::Color: + if (value.GetTypeId() == azrtti_typeid()) + { + finalValue = Color::CreateFromVector3(value.GetValue()); + } + else if (value.GetTypeId() == azrtti_typeid()) + { + Vector4 vector4 = value.GetValue(); + finalValue = Color::CreateFromVector3AndFloat(vector4.GetAsVector3(), vector4.GetW()); + } + break; + case MaterialPropertyDataType::Vector2: + finalValue = CastVectorMaterialPropertyValue(value); + break; + case MaterialPropertyDataType::Vector3: + if (value.GetTypeId() == azrtti_typeid()) + { + finalValue = value.GetValue().GetAsVector3(); + } + else + { + finalValue = CastVectorMaterialPropertyValue(value); + } + break; + case MaterialPropertyDataType::Vector4: + if (value.GetTypeId() == azrtti_typeid()) + { + finalValue = value.GetValue().GetAsVector4(); + } + else + { + finalValue = CastVectorMaterialPropertyValue(value); + } + break; + } + + if (ValidateMaterialPropertyDataType(finalValue.GetTypeId(), name, propertyDescriptor, reportError)) + { + finalizedPropertyValues[propertyIndex.GetIndex()] = finalValue; } } } diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp index 61e1283f52..ea637fb17d 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialAssetTests.cpp @@ -449,37 +449,7 @@ namespace UnitTest expectCreatorError("Type mismatch", [](MaterialAssetCreator& creator) { - creator.SetPropertyValue(Name{ "MyInt" }, 0.0f); - }); - - expectCreatorError("Type mismatch", - [](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyUInt" }, -1); - }); - - expectCreatorError("Type mismatch", - [](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat" }, 10u); - }); - - expectCreatorError("Type mismatch", - [](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat2" }, 1.0f); - }); - - expectCreatorError("Type mismatch", - [](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat3" }, AZ::Vector4{}); - }); - - expectCreatorError("Type mismatch", - [](MaterialAssetCreator& creator) - { - creator.SetPropertyValue(Name{ "MyFloat4" }, AZ::Vector3{}); + creator.SetPropertyValue(Name{ "MyFloat" }, AZ::Vector4{}); }); expectCreatorError("Type mismatch", diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp index ef89e0138c..5e09fe6612 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialSourceDataTests.cpp @@ -297,6 +297,63 @@ namespace UnitTest checkRawPropertyValues(); } + // Can return a Vector4 or a Color as a Vector4 + Vector4 GetAsVector4(const MaterialPropertyValue& value) + { + if (value.GetTypeId() == azrtti_typeid()) + { + return value.GetValue(); + } + else if (value.GetTypeId() == azrtti_typeid()) + { + return value.GetValue().GetAsVector4(); + } + else + { + return Vector4::CreateZero(); + } + } + + // Can return a Int or a UInt as a Int + int32_t GetAsInt(const MaterialPropertyValue& value) + { + if (value.GetTypeId() == azrtti_typeid()) + { + return value.GetValue(); + } + else if (value.GetTypeId() == azrtti_typeid()) + { + return aznumeric_cast(value.GetValue()); + } + else + { + return 0; + } + } + + template + bool AreTypesCompatible(const MaterialPropertyValue& a, const MaterialPropertyValue& b) + { + auto fixupType = [](TypeId t) + { + if (t == azrtti_typeid()) + { + return azrtti_typeid(); + } + + if (t == azrtti_typeid()) + { + return azrtti_typeid(); + } + + return t; + }; + + TypeId targetTypeId = azrtti_typeid(); + + return fixupType(a.GetTypeId()) == fixupType(targetTypeId) && fixupType(b.GetTypeId()) == fixupType(targetTypeId); + } + void CheckEqual(MaterialSourceData& a, MaterialSourceData& b) { EXPECT_STREQ(a.m_materialType.data(), b.m_materialType.data()); @@ -334,27 +391,41 @@ namespace UnitTest auto& propertyA = propertyIterA.second; auto& propertyB = propertyIterB->second; - bool typesMatch = propertyA.m_value.GetTypeId() == propertyB.m_value.GetTypeId(); - EXPECT_TRUE(typesMatch); - if (typesMatch) + AZStd::string propertyReference = AZStd::string::format(" for property '%s.%s'", groupName.c_str(), propertyName.c_str()); + + // We allow some types like Vector4 and Color or Int and UInt to be interchangeable since they serialize the same and can be converted when the MaterialAsset is finalized. + + if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) { - AZStd::string propertyReference = AZStd::string::format(" for property '%s.%s'", groupName.c_str(), propertyName.c_str()); - - auto typeId = propertyA.m_value.GetTypeId(); - - if (typeId == azrtti_typeid()) { EXPECT_EQ(propertyA.m_value.GetValue(), propertyB.m_value.GetValue()) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_EQ(propertyA.m_value.GetValue(), propertyB.m_value.GetValue()) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_EQ(propertyA.m_value.GetValue(), propertyB.m_value.GetValue()) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_NEAR(propertyA.m_value.GetValue(), propertyB.m_value.GetValue(), 0.01) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); } - else if (typeId == azrtti_typeid()) { EXPECT_STREQ(propertyA.m_value.GetValue().c_str(), propertyB.m_value.GetValue().c_str()) << propertyReference.c_str(); } - else - { - ADD_FAILURE(); - } + EXPECT_EQ(propertyA.m_value.GetValue(), propertyB.m_value.GetValue()) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_EQ(GetAsInt(propertyA.m_value), GetAsInt(propertyB.m_value)) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_NEAR(propertyA.m_value.GetValue(), propertyB.m_value.GetValue(), 0.01) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_TRUE(propertyA.m_value.GetValue().IsClose(propertyB.m_value.GetValue())) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_TRUE(GetAsVector4(propertyA.m_value).IsClose(GetAsVector4(propertyB.m_value))) << propertyReference.c_str(); + } + else if (AreTypesCompatible(propertyA.m_value, propertyB.m_value)) + { + EXPECT_STREQ(propertyA.m_value.GetValue().c_str(), propertyB.m_value.GetValue().c_str()) << propertyReference.c_str(); + } + else + { + ADD_FAILURE(); } } } @@ -363,42 +434,8 @@ namespace UnitTest TEST_F(MaterialSourceDataTests, TestJsonRoundTrip) { - const char* materialTypeJson = - "{ \n" - " \"propertyLayout\": { \n" - " \"version\": 1, \n" - " \"groups\": [ \n" - " { \"name\": \"groupA\" }, \n" - " { \"name\": \"groupB\" }, \n" - " { \"name\": \"groupC\" } \n" - " ], \n" - " \"properties\": { \n" - " \"groupA\": [ \n" - " {\"name\": \"MyBool\", \"type\": \"bool\"}, \n" - " {\"name\": \"MyInt\", \"type\": \"int\"}, \n" - " {\"name\": \"MyUInt\", \"type\": \"uint\"} \n" - " ], \n" - " \"groupB\": [ \n" - " {\"name\": \"MyFloat\", \"type\": \"float\"}, \n" - " {\"name\": \"MyFloat2\", \"type\": \"vector2\"}, \n" - " {\"name\": \"MyFloat3\", \"type\": \"vector3\"} \n" - " ], \n" - " \"groupC\": [ \n" - " {\"name\": \"MyFloat4\", \"type\": \"vector4\"}, \n" - " {\"name\": \"MyColor\", \"type\": \"color\"}, \n" - " {\"name\": \"MyImage\", \"type\": \"image\"} \n" - " ] \n" - " } \n" - " } \n" - "} \n"; - const char* materialTypeFilePath = "@exefolder@/Temp/roundTripTest.materialtype"; - AZ::IO::FileIOStream file; - EXPECT_TRUE(file.Open(materialTypeFilePath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeCreatePath)); - file.Write(strlen(materialTypeJson), materialTypeJson); - file.Close(); - MaterialSourceData sourceDataOriginal; sourceDataOriginal.m_materialType = materialTypeFilePath; sourceDataOriginal.m_parentMaterial = materialTypeFilePath; @@ -434,8 +471,8 @@ namespace UnitTest "properties": { "general": [ { - "name": "testColor", - "type": "color" + "name": "testValue", + "type": "Float" } ] } @@ -456,7 +493,7 @@ namespace UnitTest { "properties": { "general": { - "testColor": [0.1,0.2,0.3] + "testValue": 1.2 } }, "materialType": "@exefolder@/Temp/simpleMaterialType.materialtype" @@ -469,27 +506,11 @@ namespace UnitTest EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - AZ::Color testColor = material.m_properties["general"]["testColor"].m_value.GetValue(); - EXPECT_TRUE(AZ::Color(0.1f, 0.2f, 0.3f, 1.0f).IsClose(testColor, 0.01)); + float testValue = material.m_properties["general"]["testValue"].m_value.GetValue(); + EXPECT_FLOAT_EQ(1.2f, testValue); } - - TEST_F(MaterialSourceDataTests, Load_Error_NotAnObject) - { - const AZStd::string inputJson = R"( - [] - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Altered, loadResult.m_jsonResultCode.GetProcessing()); - EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Unsupported, loadResult.m_jsonResultCode.GetOutcome()); - - EXPECT_TRUE(loadResult.ContainsMessage("", "Material data must be a JSON object")); - } - - TEST_F(MaterialSourceDataTests, Load_Error_NoMaterialType) + + TEST_F(MaterialSourceDataTests, CreateMaterialAsset_NoMaterialType) { const AZStd::string inputJson = R"( { @@ -505,14 +526,29 @@ namespace UnitTest MaterialSourceData material; JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Halted, loadResult.m_jsonResultCode.GetProcessing()); - EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Catastrophic, loadResult.m_jsonResultCode.GetOutcome()); + const bool elevateWarnings = false; - EXPECT_TRUE(loadResult.ContainsMessage("", "Required field 'materialType' is missing")); + ErrorMessageFinder errorMessageFinder; + + errorMessageFinder.AddExpectedErrorMessage("materialType was not specified"); + auto result = material.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::DeferredBake, elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); + + errorMessageFinder.Reset(); + errorMessageFinder.AddExpectedErrorMessage("materialType was not specified"); + result = material.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::PreBake, elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); + + errorMessageFinder.Reset(); + errorMessageFinder.AddExpectedErrorMessage("materialType was not specified"); + result = material.CreateMaterialAssetFromSourceData(AZ::Uuid::CreateRandom(), "test.material", elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); } - - TEST_F(MaterialSourceDataTests, Load_Error_MaterialTypeDoesNotExist) + + TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MaterialTypeDoesNotExist) { const AZStd::string inputJson = R"( { @@ -529,102 +565,43 @@ namespace UnitTest MaterialSourceData material; JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Halted, loadResult.m_jsonResultCode.GetProcessing()); - EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Catastrophic, loadResult.m_jsonResultCode.GetOutcome()); + const bool elevateWarnings = false; - EXPECT_TRUE(loadResult.ContainsMessage("/materialType", "Failed to load material-type file")); + ErrorMessageFinder errorMessageFinder; + + errorMessageFinder.AddExpectedErrorMessage("Could not find asset [DoesNotExist.materialtype]"); + auto result = material.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::DeferredBake, elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); + + errorMessageFinder.Reset(); + errorMessageFinder.AddExpectedErrorMessage("Could not find asset [DoesNotExist.materialtype]"); + result = material.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::PreBake, elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); + + errorMessageFinder.Reset(); + errorMessageFinder.AddExpectedErrorMessage("Could not find asset [DoesNotExist.materialtype]"); + errorMessageFinder.AddIgnoredErrorMessage("Failed to create material type asset ID", true); + result = material.CreateMaterialAssetFromSourceData(AZ::Uuid::CreateRandom(), "test.material", elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); } - - TEST_F(MaterialSourceDataTests, Load_MaterialTypeMessagesAreReported) + + TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MaterialPropertyNotFound) { - const AZStd::string simpleMaterialTypeJson = R"( - { - "propertyLayout": { - "properties": { - "general": [ - { - "name": "testColor", - "type": "color" - } - ] - } - } - } - )"; - - const char* materialTypeFilePath = "@exefolder@/Temp/simpleMaterialType.materialtype"; - - AZ::IO::FileIOStream file; - EXPECT_TRUE(file.Open(materialTypeFilePath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeCreatePath)); - file.Write(simpleMaterialTypeJson.size(), simpleMaterialTypeJson.data()); - file.Close(); - - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/simpleMaterialType.materialtype", - "materialTypeVersion": 1, - "properties": { - "general": { - "testColor": [1.0,1.0,1.0] - } - } - } - )"; - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); + material.m_materialType = "@exefolder@/Temp/test.materialtype"; + AddPropertyGroup(material, "general"); + AddProperty(material, "general", "FieldDoesNotExist", 1.5f); + + const bool elevateWarnings = true; - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing()); - - // propertyLayout is a field in the material type, not the material - EXPECT_TRUE(loadResult.ContainsMessage("[simpleMaterialType.materialtype]/propertyLayout/properties", "Successfully read")); - } - - TEST_F(MaterialSourceDataTests, Load_Error_PropertyNotFound) - { - const AZStd::string simpleMaterialTypeJson = R"( - { - "propertyLayout": { - "properties": { - "general": [ - { - "name": "testColor", - "type": "color" - } - ] - } - } - } - )"; - - const char* materialTypeFilePath = "@exefolder@/Temp/simpleMaterialType.materialtype"; - - AZ::IO::FileIOStream file; - EXPECT_TRUE(file.Open(materialTypeFilePath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeCreatePath)); - file.Write(simpleMaterialTypeJson.size(), simpleMaterialTypeJson.data()); - file.Close(); - - const AZStd::string inputJson = R"( - { - "materialType": "@exefolder@/Temp/simpleMaterialType.materialtype", - "materialTypeVersion": 1, - "properties": { - "general": { - "doesNotExist": [1.0,1.0,1.0] - } - } - } - )"; - - MaterialSourceData material; - JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); - - EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask()); - EXPECT_EQ(AZ::JsonSerializationResult::Processing::PartialAlter, loadResult.m_jsonResultCode.GetProcessing()); - - EXPECT_TRUE(loadResult.ContainsMessage("/properties/general/doesNotExist", "Property 'general.doesNotExist' not found in material type.")); + ErrorMessageFinder errorMessageFinder("\"general.FieldDoesNotExist\" is not found"); + errorMessageFinder.AddIgnoredErrorMessage("Failed to build MaterialAsset", true); + auto result = material.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::PreBake, elevateWarnings); + EXPECT_FALSE(result.IsSuccess()); + errorMessageFinder.CheckExpectedErrorsFound(); } TEST_F(MaterialSourceDataTests, CreateMaterialAsset_MultiLevelDataInheritance) @@ -896,7 +873,92 @@ namespace UnitTest AddProperty(materialSourceData, "general", "MyImage", AZStd::string("doesNotExist.streamingimage")); }, true); // In this case, the warning does happen even when the asset is not finalized, because the image path is checked earlier than that } + + template + void CheckSimilar(PropertyTypeT a, PropertyTypeT b); + + template<> void CheckSimilar(float a, float b) { EXPECT_FLOAT_EQ(a, b); } + template<> void CheckSimilar(Vector2 a, Vector2 b) { EXPECT_TRUE(a.IsClose(b)); } + template<> void CheckSimilar(Vector3 a, Vector3 b) { EXPECT_TRUE(a.IsClose(b)); } + template<> void CheckSimilar(Vector4 a, Vector4 b) { EXPECT_TRUE(a.IsClose(b)); } + template<> void CheckSimilar(Color a, Color b) { EXPECT_TRUE(a.IsClose(b)); } + template void CheckSimilar(PropertyTypeT a, PropertyTypeT b) { EXPECT_EQ(a, b); } + + template + void CheckEndToEndDataTypeResolution(const char* propertyName, const char* jsonValue, PropertyTypeT expectedFinalValue) + { + const char* groupName = "general"; + + const AZStd::string inputJson = AZStd::string::format(R"( + { + "materialType": "@exefolder@/Temp/test.materialtype", + "properties": { + "%s": { + "%s": %s + } + } + } + )", groupName, propertyName, jsonValue); + + MaterialSourceData material; + JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson); + auto materialAssetResult = material.CreateMaterialAsset(Uuid::CreateRandom(), "test.material", AZ::RPI::MaterialAssetProcessingMode::PreBake); + EXPECT_TRUE(materialAssetResult); + MaterialPropertyIndex propertyIndex = materialAssetResult.GetValue()->GetMaterialPropertiesLayout()->FindPropertyIndex(MaterialPropertyId{groupName, propertyName}.GetFullName()); + CheckSimilar(expectedFinalValue, materialAssetResult.GetValue()->GetPropertyValues()[propertyIndex.GetIndex()].GetValue()); + } + + TEST_F(MaterialSourceDataTests, TestEndToEndDataTypeResolution) + { + // Data types in .material files don't have to exactly match the types in .materialtype files as specified in the properties layout. + // The exact location of the data type resolution has moved around over the life of the project, but the important thing is that + // the data type in the source .material file gets applied correctly by the time a finalized MaterialAsset comes out the other side. + + CheckEndToEndDataTypeResolution("MyBool", "true", true); + CheckEndToEndDataTypeResolution("MyBool", "false", false); + CheckEndToEndDataTypeResolution("MyBool", "1", true); + CheckEndToEndDataTypeResolution("MyBool", "0", false); + CheckEndToEndDataTypeResolution("MyBool", "1.0", true); + CheckEndToEndDataTypeResolution("MyBool", "0.0", false); + + CheckEndToEndDataTypeResolution("MyInt", "5", 5); + CheckEndToEndDataTypeResolution("MyInt", "-6", -6); + CheckEndToEndDataTypeResolution("MyInt", "-7.0", -7); + CheckEndToEndDataTypeResolution("MyInt", "false", 0); + CheckEndToEndDataTypeResolution("MyInt", "true", 1); + + CheckEndToEndDataTypeResolution("MyUInt", "8", 8u); + CheckEndToEndDataTypeResolution("MyUInt", "9.0", 9u); + CheckEndToEndDataTypeResolution("MyUInt", "false", 0u); + CheckEndToEndDataTypeResolution("MyUInt", "true", 1u); + + CheckEndToEndDataTypeResolution("MyFloat", "2", 2.0f); + CheckEndToEndDataTypeResolution("MyFloat", "-2", -2.0f); + CheckEndToEndDataTypeResolution("MyFloat", "2.1", 2.1f); + CheckEndToEndDataTypeResolution("MyFloat", "false", 0.0f); + CheckEndToEndDataTypeResolution("MyFloat", "true", 1.0f); + + CheckEndToEndDataTypeResolution("MyColor", "[0.1,0.2,0.3]", Color{0.1f, 0.2f, 0.3f, 1.0}); + CheckEndToEndDataTypeResolution("MyColor", "[0.1, 0.2, 0.3, 0.5]", Color{0.1f, 0.2f, 0.3f, 0.5f}); + CheckEndToEndDataTypeResolution("MyColor", "{\"RGB8\": [255, 0, 255, 0]}", Color{1.0f, 0.0f, 1.0f, 0.0f}); + + CheckEndToEndDataTypeResolution("MyFloat2", "[0.1,0.2]", Vector2{0.1f, 0.2f}); + CheckEndToEndDataTypeResolution("MyFloat2", "{\"y\":0.2, \"x\":0.1}", Vector2{0.1f, 0.2f}); + CheckEndToEndDataTypeResolution("MyFloat2", "{\"y\":0.2, \"x\":0.1, \"Z\":0.3}", Vector2{0.1f, 0.2f}); + CheckEndToEndDataTypeResolution("MyFloat2", "{\"y\":0.2, \"W\":0.4, \"x\":0.1, \"Z\":0.3}", Vector2{0.1f, 0.2f}); + + CheckEndToEndDataTypeResolution("MyFloat3", "[0.1,0.2,0.3]", Vector3{0.1f, 0.2f, 0.3f}); + CheckEndToEndDataTypeResolution("MyFloat3", "{\"y\":0.2, \"x\":0.1}", Vector3{0.1f, 0.2f, 0.0f}); + CheckEndToEndDataTypeResolution("MyFloat3", "{\"y\":0.2, \"x\":0.1, \"Z\":0.3}", Vector3{0.1f, 0.2f, 0.3f}); + CheckEndToEndDataTypeResolution("MyFloat3", "{\"y\":0.2, \"W\":0.4, \"x\":0.1, \"Z\":0.3}", Vector3{0.1f, 0.2f, 0.3f}); + + CheckEndToEndDataTypeResolution("MyFloat4", "[0.1,0.2,0.3,0.4]", Vector4{0.1f, 0.2f, 0.3f, 0.4f}); + CheckEndToEndDataTypeResolution("MyFloat4", "{\"y\":0.2, \"x\":0.1}", Vector4{0.1f, 0.2f, 0.0f, 0.0f}); + CheckEndToEndDataTypeResolution("MyFloat4", "{\"y\":0.2, \"x\":0.1, \"Z\":0.3}", Vector4{0.1f, 0.2f, 0.3f, 0.0f}); + CheckEndToEndDataTypeResolution("MyFloat4", "{\"y\":0.2, \"W\":0.4, \"x\":0.1, \"Z\":0.3}", Vector4{0.1f, 0.2f, 0.3f, 0.4f}); + } + } diff --git a/Gems/Atom/RPI/Code/atom_rpi_edit_files.cmake b/Gems/Atom/RPI/Code/atom_rpi_edit_files.cmake index e32d19ffd7..3c345cc00b 100644 --- a/Gems/Atom/RPI/Code/atom_rpi_edit_files.cmake +++ b/Gems/Atom/RPI/Code/atom_rpi_edit_files.cmake @@ -25,7 +25,6 @@ set(FILES Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h Include/Atom/RPI.Edit/Material/MaterialPropertyValueSourceDataSerializer.h Include/Atom/RPI.Edit/Material/MaterialSourceData.h - Include/Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h Include/Atom/RPI.Edit/Material/MaterialFunctorSourceData.h Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.h @@ -45,7 +44,6 @@ set(FILES Source/RPI.Edit/Material/MaterialPropertyValueSourceData.cpp Source/RPI.Edit/Material/MaterialPropertyValueSourceDataSerializer.cpp Source/RPI.Edit/Material/MaterialSourceData.cpp - Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp Source/RPI.Edit/Material/MaterialFunctorSourceData.cpp Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp Source/RPI.Edit/Material/MaterialFunctorSourceDataRegistration.cpp From 638fc027f5ea03c2a86a0e454022ccebd640eaa8 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 14 Jan 2022 13:05:59 -0800 Subject: [PATCH 244/272] Updated material builder version numbers in case my prior changes were impactful (it might not be necessary but I'm not sure, so just in case) Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp | 2 +- .../Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index 768890a29b..cadb182d03 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -52,7 +52,7 @@ namespace AZ { AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor; materialBuilderDescriptor.m_name = JobKey; - materialBuilderDescriptor.m_version = 115; // material dependency improvements updated + materialBuilderDescriptor.m_version = 116; // more material dependency improvements materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); materialBuilderDescriptor.m_busId = azrtti_typeid(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index 9a92e7b762..35a903dac0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -128,7 +128,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(21); // material dependency improvements updated + ->Version(22); // more material dependency improvements } } From f87d0f83869426b584d4ef9c0b83749e7c27850c Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Fri, 14 Jan 2022 16:18:26 -0800 Subject: [PATCH 245/272] Updated all .material files to have materialTypeVersion instead of propertyLayoutVersion. This was renamed in code at some point but we forgot to rename in the files. Before this was silently ignored but since I removed MaterialSourceDataSerializer, this started being reported as a warning. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../TestData/Test_Sponza_Material_Conversion_black.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_green.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_arch.material | 2 +- .../Test_Sponza_Material_Conversion_mat_bricks.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_floor.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_roof.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_phong5.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_red.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_white.material | 2 +- .../Gem/Sponza/Assets/objects/lightBlocker_lambert1.material | 2 +- .../Levels/Graphics/PbrMaterialChart/materials/basic.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r00.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r01.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r02.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r03.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r04.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r05.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r06.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r07.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r08.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r09.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m00_r10.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r00.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r01.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r02.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r03.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r04.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r05.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r06.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r07.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r08.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r09.material | 2 +- .../Graphics/PbrMaterialChart/materials/basic_m10_r10.material | 2 +- AutomatedTesting/Materials/DefaultPBRTransparent.material | 2 +- AutomatedTesting/Materials/basic_grey.material | 2 +- .../Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material | 2 +- .../OcclusionCullingPlaneTransparentVisualization.material | 2 +- .../OcclusionCullingPlaneVisualization.material | 2 +- .../Common/Assets/Materials/Presets/PBR/default_grid.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_aluminum.material | 2 +- .../Assets/Materials/Presets/PBR/metal_aluminum_matte.material | 2 +- .../Materials/Presets/PBR/metal_aluminum_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_brass.material | 2 +- .../Assets/Materials/Presets/PBR/metal_brass_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_brass_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_chrome.material | 2 +- .../Assets/Materials/Presets/PBR/metal_chrome_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_chrome_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_cobalt.material | 2 +- .../Assets/Materials/Presets/PBR/metal_cobalt_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_cobalt_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_copper.material | 2 +- .../Assets/Materials/Presets/PBR/metal_copper_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_copper_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_gold.material | 2 +- .../Assets/Materials/Presets/PBR/metal_gold_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_gold_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_iron.material | 2 +- .../Assets/Materials/Presets/PBR/metal_iron_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_iron_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_mercury.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_nickel.material | 2 +- .../Assets/Materials/Presets/PBR/metal_nickel_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_nickel_polished.material | 2 +- .../Assets/Materials/Presets/PBR/metal_palladium.material | 2 +- .../Assets/Materials/Presets/PBR/metal_palladium_matte.material | 2 +- .../Materials/Presets/PBR/metal_palladium_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_platinum.material | 2 +- .../Assets/Materials/Presets/PBR/metal_platinum_matte.material | 2 +- .../Materials/Presets/PBR/metal_platinum_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_silver.material | 2 +- .../Assets/Materials/Presets/PBR/metal_silver_matte.material | 2 +- .../Assets/Materials/Presets/PBR/metal_silver_polished.material | 2 +- .../Common/Assets/Materials/Presets/PBR/metal_titanium.material | 2 +- .../Assets/Materials/Presets/PBR/metal_titanium_matte.material | 2 +- .../Materials/Presets/PBR/metal_titanium_polished.material | 2 +- .../ReflectionProbe/ReflectionProbeVisualization.material | 2 +- Gems/Atom/Feature/Common/Assets/Materials/basic_grey.material | 2 +- Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material | 2 +- Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material | 2 +- Gems/Atom/TestData/TestData/Materials/ParallaxRock.material | 2 +- .../SkinTestCases/001_hermanubis_regression_test.material | 2 +- .../SkinTestCases/002_wrinkle_regression_test.material | 2 +- .../StandardMultilayerPbrTestCases/001_ManyFeatures.material | 2 +- .../001_ManyFeatures_Layer2Off.material | 2 +- .../001_ManyFeatures_Layer3Off.material | 2 +- .../StandardMultilayerPbrTestCases/002_ParallaxPdo.material | 2 +- .../StandardMultilayerPbrTestCases/003_Debug_BlendMask.material | 2 +- .../003_Debug_BlendWeights.material | 2 +- .../003_Debug_Displacement.material | 2 +- .../StandardMultilayerPbrTestCases/004_UseVertexColors.material | 2 +- .../StandardMultilayerPbrTestCases/005_UseDisplacement.material | 2 +- .../005_UseDisplacement_Layer2Off.material | 2 +- .../005_UseDisplacement_Layer3Off.material | 2 +- .../005_UseDisplacement_With_BlendMaskTexture.material | 2 +- ...UseDisplacement_With_BlendMaskTexture_AllSameHeight.material | 2 +- ..._UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material | 2 +- .../005_UseDisplacement_With_BlendMaskVertexColors.material | 2 +- .../Materials/StandardPbrTestCases/001_DefaultWhite.material | 2 +- .../Materials/StandardPbrTestCases/002_BaseColorLerp.material | 2 +- .../StandardPbrTestCases/002_BaseColorLinearLight.material | 2 +- .../StandardPbrTestCases/002_BaseColorMultiply.material | 2 +- .../Materials/StandardPbrTestCases/003_MetalMatte.material | 2 +- .../Materials/StandardPbrTestCases/003_MetalPolished.material | 2 +- .../Materials/StandardPbrTestCases/004_MetalMap.material | 2 +- .../Materials/StandardPbrTestCases/005_RoughnessMap.material | 2 +- .../Materials/StandardPbrTestCases/006_SpecularF0Map.material | 2 +- .../007_MultiscatteringCompensationOff.material | 2 +- .../007_MultiscatteringCompensationOn.material | 2 +- .../Materials/StandardPbrTestCases/008_NormalMap.material | 2 +- .../StandardPbrTestCases/008_NormalMap_Bevels.material | 2 +- .../Materials/StandardPbrTestCases/009_Opacity_Blended.material | 2 +- .../009_Opacity_Blended_Alpha_Affects_Specular.material | 2 +- .../009_Opacity_Cutout_PackedAlpha_DoubleSided.material | 2 +- .../009_Opacity_Cutout_SplitAlpha_DoubleSided.material | 2 +- .../009_Opacity_Cutout_SplitAlpha_SingleSided.material | 2 +- .../009_Opacity_Opaque_DoubleSided.material | 2 +- .../StandardPbrTestCases/009_Opacity_TintedTransparent.material | 2 +- .../StandardPbrTestCases/010_AmbientOcclusion.material | 2 +- .../Materials/StandardPbrTestCases/010_BothOcclusion.material | 2 +- .../Materials/StandardPbrTestCases/010_OcclusionBase.material | 2 +- .../StandardPbrTestCases/010_SpecularOcclusion.material | 2 +- .../Materials/StandardPbrTestCases/011_Emissive.material | 2 +- .../Materials/StandardPbrTestCases/012_Parallax_POM.material | 2 +- .../StandardPbrTestCases/012_Parallax_POM_Cutout.material | 2 +- .../Materials/StandardPbrTestCases/013_SpecularAA_Off.material | 2 +- .../Materials/StandardPbrTestCases/013_SpecularAA_On.material | 2 +- .../Materials/StandardPbrTestCases/014_ClearCoat.material | 2 +- .../StandardPbrTestCases/014_ClearCoat_NormalMap.material | 2 +- .../StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material | 2 +- .../StandardPbrTestCases/014_ClearCoat_RoughnessMap.material | 2 +- .../StandardPbrTestCases/015_SubsurfaceScattering.material | 2 +- .../015_SubsurfaceScattering_Transmission.material | 2 +- .../StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material | 2 +- .../StandardPbrTestCases/100_UvTiling_BaseColor.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Emissive.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Metallic.material | 2 +- .../Materials/StandardPbrTestCases/100_UvTiling_Normal.material | 2 +- .../100_UvTiling_Normal_Dome_Rotate20.material | 2 +- .../100_UvTiling_Normal_Dome_Rotate90.material | 2 +- .../100_UvTiling_Normal_Dome_ScaleOnlyU.material | 2 +- .../100_UvTiling_Normal_Dome_ScaleOnlyV.material | 2 +- .../100_UvTiling_Normal_Dome_ScaleUniform.material | 2 +- .../100_UvTiling_Normal_Dome_TransformAll.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Opacity.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Parallax_A.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Parallax_B.material | 2 +- .../StandardPbrTestCases/100_UvTiling_Roughness.material | 2 +- .../StandardPbrTestCases/100_UvTiling_SpecularF0.material | 2 +- .../101_DetailMaps_BaseNoDetailMaps.material | 2 +- .../Materials/StandardPbrTestCases/102_DetailMaps_All.material | 2 +- .../StandardPbrTestCases/103_DetailMaps_BaseColor.material | 2 +- .../103_DetailMaps_BaseColorWithMask.material | 2 +- .../StandardPbrTestCases/104_DetailMaps_Normal.material | 2 +- .../StandardPbrTestCases/104_DetailMaps_NormalWithMask.material | 2 +- .../105_DetailMaps_BlendMaskUsingDetailUVs.material | 2 +- .../Materials/StandardPbrTestCases/UvTilingBase.material | 2 +- .../TestData/Objects/ModelHotReload/DisplayVertexColor.material | 2 +- .../Assets/Materials/AnodizedMetal/anodized_metal.material | 2 +- .../Assets/Materials/Asphalt/asphalt.material | 2 +- .../Assets/Materials/BasicFabric/basic_fabric.material | 2 +- .../Assets/Materials/BrushedSteel/brushed_steel.material | 2 +- .../Assets/Materials/CarPaint/car_paint.material | 2 +- .../ReferenceMaterials/Assets/Materials/Coal/coal.material | 2 +- .../Assets/Materials/ConcreteStucco/concrete_stucco.material | 2 +- .../ReferenceMaterials/Assets/Materials/Copper/copper.material | 2 +- .../ReferenceMaterials/Assets/Materials/Fabric/fabric.material | 2 +- .../Assets/Materials/GalvanizedSteel/galvanized_steel.material | 2 +- .../Assets/Materials/GlazedClay/glazed_clay.material | 2 +- .../ReferenceMaterials/Assets/Materials/Gloss/gloss.material | 2 +- .../ReferenceMaterials/Assets/Materials/Gold/gold.material | 2 +- .../ReferenceMaterials/Assets/Materials/Ground/ground.material | 2 +- .../ReferenceMaterials/Assets/Materials/Iron/iron.material | 2 +- .../Assets/Materials/Leather/dark_leather.material | 2 +- .../Assets/Materials/Light_Leather/light_leather.material | 2 +- .../Materials/MicrofiberFabric/microfiber_fabric.material | 2 +- .../Assets/Materials/MixedStones/mixed_stones.material | 2 +- .../ReferenceMaterials/Assets/Materials/Nickle/nickle.material | 2 +- .../Assets/Materials/Plaster/plaster.material | 2 +- .../Assets/Materials/Plastic_01/plastic_01.material | 2 +- .../Assets/Materials/Plastic_02/plastic_02.material | 2 +- .../Assets/Materials/Plastic_03/plastic_03.material | 2 +- .../Assets/Materials/Platinum/platinum.material | 2 +- .../Assets/Materials/Porcelain/porcelain.material | 2 +- .../Materials/RotaryBrushedSteel/rotary_brushed_steel.material | 2 +- .../ReferenceMaterials/Assets/Materials/Rust/rust.material | 2 +- .../ReferenceMaterials/Assets/Materials/Suede/suede.material | 2 +- .../Assets/Materials/TireRubber/tire_rubber.material | 2 +- .../Assets/Materials/WoodPlanks/wood_planks.material | 2 +- .../Assets/Materials/WornMetal/warn_metal.material | 2 +- .../ReferenceMaterials/Assets/Materials/black.material | 2 +- .../ReferenceMaterials/Assets/Materials/blue.material | 2 +- .../ReferenceMaterials/Assets/Materials/green.material | 2 +- .../ReferenceMaterials/Assets/Materials/grey.material | 2 +- .../ReferenceMaterials/Assets/Materials/red.material | 2 +- .../ReferenceMaterials/Assets/Materials/white.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_black.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_green.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_arch.material | 2 +- .../Test_Sponza_Material_Conversion_mat_bricks.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_floor.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_mat_roof.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_phong5.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_red.material | 2 +- .../TestData/Test_Sponza_Material_Conversion_white.material | 2 +- .../Sponza/Assets/objects/lightBlocker_lambert1.material | 2 +- .../Atom/Scripts/Python/DCC_Materials/maya_materials_export.py | 2 +- .../SDK/Atom/Scripts/Python/DCC_Materials/pbr.material | 2 +- .../SDK/Maya/Scripts/Python/dcc_materials/main.py | 2 +- .../SDK/Maya/Scripts/Python/dcc_materials/materials_export.py | 2 +- .../SDK/Maya/Scripts/Python/dcc_materials/pbr.material | 2 +- .../Python/kitbash_converter/standardPBR.template.material | 2 +- .../Python/legacy_asset_converter/standardPBR.template.material | 2 +- .../Scripts/Python/maya_dcc_materials/maya_materials_export.py | 2 +- .../Python/maya_dcc_materials/standardpbr.template.material | 2 +- .../stingraypbs_converter/StandardPBR_AllProperties.material | 2 +- .../Substance/resources/atom/StandardPBR_AllProperties.material | 2 +- .../SDK/Substance/resources/atom/atom.material | 2 +- .../SDK/Substance/resources/atom/atom_variant00.material | 2 +- .../Tools/Resources/Atom/StandardPBR_AllProperties.material | 2 +- .../cloth/Chicken/Actor/chicken_chicken_body_mat.material | 2 +- .../cloth/Chicken/Actor/chicken_chicken_eye_mat.material | 2 +- .../Assets/Objects/cloth/Environment/cloth_blinds.material | 2 +- .../Objects/cloth/Environment/cloth_blinds_broken.material | 2 +- .../cloth/Environment/cloth_locked_corners_four.material | 2 +- .../Objects/cloth/Environment/cloth_locked_corners_two.material | 2 +- .../Assets/Objects/cloth/Environment/cloth_locked_edge.material | 2 +- .../Assets/Objects/_Primitives/_Box_1x1_MiddleGrey.material | 2 +- .../Objects/_Primitives/_Cylinder_1x1_MiddleGrey.material | 2 +- .../Assets/Objects/_Primitives/_Sphere_1x1_MiddleGrey.material | 2 +- .../Terrain/Assets/Materials/Terrain/DefaultPbrTerrain.material | 2 +- 231 files changed, 231 insertions(+), 231 deletions(-) diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material index cc2c9e785b..d15aa620c7 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material index a4bfb73d12..579359b085 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material index fe9c54bc02..88d5fc0fc6 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material index a19afa33e2..7244397ee9 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material index 0c1208d8fb..8a3f289c26 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material index 6aad4d644a..7bc193978f 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material index 302589dc85..a53cbef4e4 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material index 5217a4e4be..6ddb645319 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material index dba44f7b49..e3d310cd15 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material +++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material index c8e9f1f8f7..35677a81c6 100644 --- a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material +++ b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material index 32ac8dfd10..6af3ceb0c1 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic.material @@ -1,6 +1,6 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 1.0, 1.0, 1.0 ], diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material index 1c1096bf12..541bd83981 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r00.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material index 33148f3f73..19691258e0 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r01.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material index 38339454cb..46fda2aab1 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r02.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material index e21ab5775a..79cf4bf401 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r03.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material index 0272e66081..9aabf3e158 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r04.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material index 67d51777a4..8b02f225fc 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r05.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material index 3136f654e6..5b089da4bd 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r06.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material index a79744ea11..25741cf689 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r07.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material index 1372283500..04103273f2 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r08.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material index d1c951e53c..74eb68da99 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r09.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material index d34fc46530..3533ca6676 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m00_r10.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 0.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material index 92ddfec7c4..d2ce0fadc9 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r00.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material index 874422384a..8d96ea6217 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r01.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material index b017add10b..e8feb87283 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r02.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material index 5353d651c8..c14591bd52 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r03.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material index 6dd47e4e3b..60a3167f02 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r04.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material index 04912cbfd4..d71ff06961 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r05.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material index 27f7f6ff42..6fa8cfe1a6 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r06.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material index e2b5df681c..773cc66f03 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r07.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material index 5418f9c855..6971597d1d 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r08.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material index dd1ec3489a..c2d8cc47bd 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r09.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material index 5f9317d2cc..906879b0ea 100644 --- a/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material +++ b/AutomatedTesting/Levels/Graphics/PbrMaterialChart/materials/basic_m10_r10.material @@ -1,7 +1,7 @@ { "parentMaterial": "./basic.material", "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "metallic": { "factor": 1.0 diff --git a/AutomatedTesting/Materials/DefaultPBRTransparent.material b/AutomatedTesting/Materials/DefaultPBRTransparent.material index 7c8aa6cf94..a7000d5371 100644 --- a/AutomatedTesting/Materials/DefaultPBRTransparent.material +++ b/AutomatedTesting/Materials/DefaultPBRTransparent.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/Presets/PBR/default_grid.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "opacity": { "mode": "Blended" diff --git a/AutomatedTesting/Materials/basic_grey.material b/AutomatedTesting/Materials/basic_grey.material index 0b890db4c6..6ecc1e029a 100644 --- a/AutomatedTesting/Materials/basic_grey.material +++ b/AutomatedTesting/Materials/basic_grey.material @@ -1,6 +1,6 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 0.18, 0.18, 0.18 ], diff --git a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material index 878b3ac39f..52c323b454 100644 --- a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material +++ b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/Skin.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "wrinkleLayers": { "count": 3, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneTransparentVisualization.material b/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneTransparentVisualization.material index 981e392eef..11d8d44e94 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneTransparentVisualization.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneTransparentVisualization.material @@ -1,6 +1,6 @@ { "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "enableShadows": false, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneVisualization.material b/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneVisualization.material index 4446cc2d9d..50440b714f 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneVisualization.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/OcclusionCullingPlane/OcclusionCullingPlaneVisualization.material @@ -1,6 +1,6 @@ { "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "enableShadows": false, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/default_grid.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/default_grid.material index 387d022bd2..05345a1649 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/default_grid.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/default_grid.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/Default/default_basecolor.tif" diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum.material index ece08a3492..38ebe17687 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_matte.material index afc2bb56f3..c3ec8a9266 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_polished.material index 27fa2bb11e..90c62b6d76 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_aluminum_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass.material index 77f658aafa..e456d147e1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_matte.material index d9c72471c8..11705a2bf8 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_polished.material index 57b5a15e54..5a2b2433d4 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_brass_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome.material index 50e21d481c..cb8a8fad1e 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_matte.material index 55e1b0c3bc..1592c4c095 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_polished.material index ce6599837c..6c2e403fc9 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_chrome_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt.material index be4067570d..ea399542c0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_matte.material index 09aed7ba63..c20f50c95e 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_polished.material index c1e6ca7798..7f00525f4d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_cobalt_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper.material index 3970606e7d..23b9fba63d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_matte.material index d0385eebde..e16cf0bb4e 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_polished.material index 5e52702d21..53fac02767 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_copper_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold.material index 2638e76a74..6ee7eed53f 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_matte.material index fd21141048..6fa842b6f7 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_polished.material index 5861c7b533..55a5412af1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_gold_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron.material index c35f8ca755..cac874c583 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_matte.material index 1ed1dd4dad..1373ff0108 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_polished.material index e60d31bd6d..59e1330993 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_iron_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_mercury.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_mercury.material index e2d304ab32..82fbde8db3 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_mercury.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_mercury.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel.material index a158fa2777..0e3aacc785 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_matte.material index 4ae75d3a42..db72087d30 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_polished.material index 48effb1c94..d4467508ae 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_nickel_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium.material index 2b2a6f148a..0e91117519 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_matte.material index 1ab89f90ad..b7a5648fcf 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_polished.material index 5b7879c3fa..d8e398a7de 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_palladium_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum.material index 678c3321ce..f450fb66b0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_matte.material index 7afa0809bb..a515ba5aaf 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_polished.material index df6a8fb595..5b3d184631 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_platinum_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver.material index a53c252144..14247e6421 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_matte.material index 588f90c3d1..e98fd5376d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_polished.material index 96fbdee686..ae757460a5 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_silver_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium.material index a34430bd7d..c3ce0014a1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_matte.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_matte.material index 52ebc71d9c..0745b4894d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_matte.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_matte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_polished.material b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_polished.material index b9dd832849..ff2d7734ad 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_polished.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/Presets/PBR/metal_titanium_polished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/ReflectionProbe/ReflectionProbeVisualization.material b/Gems/Atom/Feature/Common/Assets/Materials/ReflectionProbe/ReflectionProbeVisualization.material index e9bb191532..f4063ba923 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/ReflectionProbe/ReflectionProbeVisualization.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/ReflectionProbe/ReflectionProbeVisualization.material @@ -1,6 +1,6 @@ { "materialType": "ReflectionProbeVisualization.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "general": { "enableShadows": false, diff --git a/Gems/Atom/Feature/Common/Assets/Materials/basic_grey.material b/Gems/Atom/Feature/Common/Assets/Materials/basic_grey.material index 0b890db4c6..6ecc1e029a 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/basic_grey.material +++ b/Gems/Atom/Feature/Common/Assets/Materials/basic_grey.material @@ -1,6 +1,6 @@ { "materialType": "Materials/Types/StandardPBR.materialtype", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 0.18, 0.18, 0.18 ], diff --git a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material index aaa2dc455f..061510d4c2 100644 --- a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material +++ b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Brick.material @@ -2,7 +2,7 @@ "description": "", "materialType": "TestData/Materials/Types/AutoBrick.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "appearance": { "ao": 0.5252525210380554, diff --git a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material index 37c17e5616..b81ff4110b 100644 --- a/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material +++ b/Gems/Atom/TestData/TestData/Materials/AutoBrick/Tile.material @@ -2,7 +2,7 @@ "description": "", "materialType": "TestData/Materials/Types/AutoBrick.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "appearance": { "ao": 0.010100999847054482, diff --git a/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material b/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material index c9276216eb..1e140b9cf7 100644 --- a/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material +++ b/Gems/Atom/TestData/TestData/Materials/ParallaxRock.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/Presets/PBR/default_grid.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseTextureMap": "TestData/Textures/cc0/Rock030_2K_AmbientOcclusion.jpg" diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material index e6c032b0f9..be607e7721 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_hermanubis_regression_test.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/Skin.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material index 9b955ddb1d..4222108b5e 100644 --- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material +++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/Skin.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material index 415bd36dcf..f683ad052d 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer2": true, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material index d91cfb34eb..042f31f3ec 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer2Off.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer2": false diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material index 3ee48df612..59fc168a6c 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures_Layer3Off.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/001_ManyFeatures.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer3": false diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material index 64adf317a9..a1d3c288ea 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer2": true, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material index ffcbf3ce7e..b7be8ab18f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendMask.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "debugDrawMode": "BlendMask" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material index 8d13ac781f..99a9c9f382 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_BlendWeights.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "debugDrawMode": "FinalBlendWeights" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material index 7aff50cb56..6dbee69845 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/003_Debug_Displacement.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "debugDrawMode": "Displacement" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material index ea3ea8b519..b53df9a505 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/004_UseVertexColors.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/002_ParallaxPdo.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "blendSource": "BlendMaskVertexColors" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material index 9163fe0a0c..f313080cce 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "blendSource": "Displacement", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material index 9413e35128..6f64bcd49f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer2Off.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer2": false diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material index 93e0b21780..8b32223c82 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_Layer3Off.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "enableLayer3": false diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material index 6b062f6d1e..023316c5f6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "blendSource": "Displacement_With_BlendMaskTexture" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material index 0e6519afd4..d88802d4de 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_AllSameHeight.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "displacementBlendDistance": 0.0010000000474974514 diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material index b5b5656084..9ba4d20a9a 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskTexture.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "layer1_parallax": { "offset": -0.03200000151991844, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material index 8461ea429c..51219aa180 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement_With_BlendMaskVertexColors.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "TestData/Materials/StandardMultilayerPbrTestCases/005_UseDisplacement.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "blendSource": "Displacement_With_BlendMaskVertexColors", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material index 2e4eee7f8e..164b73c892 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/001_DefaultWhite.material @@ -2,5 +2,5 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3 + "materialTypeVersion": 3 } \ No newline at end of file diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material index f8214e1b2e..29329a03a2 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLerp.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material index bf31a4a111..46a8fd70ef 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorLinearLight.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material index b3b67448ea..7abf4ca40c 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/002_BaseColorMultiply.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material index 12690076c3..73ad13e27b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalMatte.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material index 41496bd801..9dea40d6ec 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/003_MetalPolished.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material index ebc65557ec..d20e354a53 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/004_MetalMap.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material index e770537005..283c6ac60b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/005_RoughnessMap.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material index d0e0dccf1e..11228e2199 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/006_SpecularF0Map.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material index de9886ac46..3b9779aac1 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOff.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material index 411646effc..dbbcdc631d 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/007_MultiscatteringCompensationOn.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material index c5561823ed..4b2842a594 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material index b26cb927d0..aec3bbf478 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/008_NormalMap_Bevels.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.30000001192092898, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material index 98dd6baecd..1528403868 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material index dbaec36136..20f5ccf098 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material index 5545e5a482..d8683681c4 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_PackedAlpha_DoubleSided.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Textures/Foliage_Leaves_0_BaseColor.dds" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material index 960a8b0700..8e8dad46d8 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_DoubleSided.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "opacity": { "alphaSource": "Split", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material index 2adc42141c..2d9b4c514b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Cutout_SplitAlpha_SingleSided.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "opacity": { "alphaSource": "Split", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material index a26bf6e045..f7ac93a7ac 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Opaque_DoubleSided.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/Default/checker_uv_basecolor.png" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material index 1716792af1..9d36d0a7e6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_TintedTransparent.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material index 28f43a9a57..a7fe0d1d4d 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_AmbientOcclusion.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "010_OcclusionBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 2.0, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material index cee64dd107..1f9c94db47 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_BothOcclusion.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "010_OcclusionBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 2.0, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material index 9a41a7d191..534305b68a 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_OcclusionBase.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material index 703088d6f8..6403bc5c14 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/010_SpecularOcclusion.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "010_OcclusionBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "specularFactor": 2.0, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material index 97d657b82b..dc42c0d6b5 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/011_Emissive.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/Default/default_basecolor.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material index ed070d5de2..fee4a30f77 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material index f5ec0e8287..d69b75285e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/012_Parallax_POM_Cutout.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_bc.png" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material index 666bf45d57..a1da93acbb 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_Off.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "metallic": { "factor": 1.0 diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material index 0581280d67..07018e9140 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/013_SpecularAA_On.material @@ -1,7 +1,7 @@ { "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "applySpecularAA": true diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material index c23f71e7df..e02a8b5fc2 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material index caa9f88818..56d8515305 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material index 04d2051e8e..e7575d8bd6 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_NormalMap_2ndUv.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material index 51915a7bb0..3ccbfeacc1 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/014_ClearCoat_RoughnessMap.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material index 37a9b1144e..fb3621f056 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "subsurfaceScattering": { "enableSubsurfaceScattering": true, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material index 38adbc70cd..eff175be77 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/015_SubsurfaceScattering_Transmission.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "subsurfaceScattering": { "enableSubsurfaceScattering": true, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material index e1260ab4f2..d88c1f151f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_AmbientOcclusion.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseTextureMap": "TestData/Objects/cube/cube_diff.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material index 5dd3b88e1b..89bd1005a5 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_BaseColor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Objects/cube/cube_diff.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material index 21f2733d94..564de16cc2 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Emissive.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material index 6c5f72faa1..0eff6198dd 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Metallic.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "metallic": { "factor": 1.0, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material index d53fbec47e..e50c669114 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "textureMap": "TestData/Objects/cube/cube_diff.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material index d693224e78..0b3d678bdd 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate20.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material index 19e3fce5e6..4a7ade8b30 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_Rotate90.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material index 44345f37c9..c0477ac5cf 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyU.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material index 2fadfa6e22..b088a0c090 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleOnlyV.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material index 476ba647be..c7c3fac87f 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_ScaleUniform.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material index d3db77e1eb..849e926031 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Normal_Dome_TransformAll.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "normal": { "factor": 0.15000000596046449, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material index 5e8a0438dd..b203ec5318 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Opacity.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "opacity": { "alphaSource": "Split", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material index b3e69212db..ad2e27063b 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_A.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Objects/cube/cube_diff.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material index 3d52f3b9e6..75646e5191 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Parallax_B.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "TestData/Objects/cube/cube_diff.tif" diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material index 4aa4b4a651..49ff9555f1 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_Roughness.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "metallic": { "factor": 1.0 diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material index bf53b57022..a750e30d80 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/100_UvTiling_SpecularF0.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "TestData\\Materials\\StandardPbrTestCases\\UvTilingBase.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material index 82192bac41..30959fc972 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material index dd31d00db0..2cb14b490e 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material index eda8ef12de..826ae2d737 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "detailLayerGroup": { "baseColorDetailBlend": 0.800000011920929, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material index 28c922a240..1c2214a031 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColorWithMask.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/103_DetailMaps_BaseColor.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "detailLayerGroup": { "baseColorDetailBlend": 1.0, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material index 291f0fc828..9a80cfaaa0 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "detailLayerGroup": { "enableDetailLayer": true, diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material index 1c11d653c0..0ee81633ae 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/104_DetailMaps_NormalWithMask.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "TestData/Materials/StandardPbrTestCases/104_DetailMaps_Normal.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "detailLayerGroup": { "blendDetailMask": "TestData/Textures/checker8x8_gray_512.png", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material index 6964342447..b2747ead21 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/EnhancedPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png", diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material index 48c287552f..be607db929 100644 --- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/UvTilingBase.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\Types\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "uv": { "center": [ diff --git a/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material b/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material index 104d675387..8a2f45260a 100644 --- a/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material +++ b/Gems/Atom/TestData/TestData/Objects/ModelHotReload/DisplayVertexColor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardMultilayerPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "blend": { "blendSource": "BlendMaskVertexColors", diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/AnodizedMetal/anodized_metal.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/AnodizedMetal/anodized_metal.material index cb2c725678..9672075409 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/AnodizedMetal/anodized_metal.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/AnodizedMetal/anodized_metal.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Asphalt/asphalt.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Asphalt/asphalt.material index a004cefd18..76cabce752 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Asphalt/asphalt.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Asphalt/asphalt.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Asphalt/asphalt_basecolor.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BasicFabric/basic_fabric.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BasicFabric/basic_fabric.material index bf26749d3c..30a203a43a 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BasicFabric/basic_fabric.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BasicFabric/basic_fabric.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/BasicFabric/basic_fabric_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BrushedSteel/brushed_steel.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BrushedSteel/brushed_steel.material index 0a98da1143..8feed25399 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BrushedSteel/brushed_steel.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/BrushedSteel/brushed_steel.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "factor": 0.9292929172515869, diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/CarPaint/car_paint.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/CarPaint/car_paint.material index 3cd0e542fa..92544dd7be 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/CarPaint/car_paint.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/CarPaint/car_paint.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Coal/coal.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Coal/coal.material index 78ceb399ee..4c377178d3 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Coal/coal.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Coal/coal.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/ConcreteStucco/concrete_stucco.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/ConcreteStucco/concrete_stucco.material index d4e2016022..c5c2e24a2a 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/ConcreteStucco/concrete_stucco.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/ConcreteStucco/concrete_stucco.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Copper/copper.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Copper/copper.material index 80b7ea29f3..56d0fb1357 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Copper/copper.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Copper/copper.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Fabric/fabric.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Fabric/fabric.material index ff3a250b96..c2a71513ff 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Fabric/fabric.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Fabric/fabric.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Fabric/fabric_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GalvanizedSteel/galvanized_steel.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GalvanizedSteel/galvanized_steel.material index aca0648374..83dc076c23 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GalvanizedSteel/galvanized_steel.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GalvanizedSteel/galvanized_steel.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/GalvanizedSteel/galvanized_steel.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GlazedClay/glazed_clay.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GlazedClay/glazed_clay.material index 66f4dd7d00..ff82c9b03f 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GlazedClay/glazed_clay.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/GlazedClay/glazed_clay.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gloss/gloss.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gloss/gloss.material index ceaca4a274..3e2b1fb56e 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gloss/gloss.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gloss/gloss.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gold/gold.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gold/gold.material index b9ee3e5a12..a5e0fa4dba 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gold/gold.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Gold/gold.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Ground/ground.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Ground/ground.material index 86f84d4c84..63e9c49fba 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Ground/ground.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Ground/ground.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Ground/ground_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Iron/iron.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Iron/iron.material index d859a4a4cf..0ec8cc4819 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Iron/iron.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Iron/iron.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Leather/dark_leather.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Leather/dark_leather.material index 6c14a0c7fe..46d8511186 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Leather/dark_leather.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Leather/dark_leather.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Leather/leather_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Light_Leather/light_leather.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Light_Leather/light_leather.material index 1ae26a8e0d..a73e80b6cb 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Light_Leather/light_leather.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Light_Leather/light_leather.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Light_Leather/light_leather_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MicrofiberFabric/microfiber_fabric.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MicrofiberFabric/microfiber_fabric.material index d2f5964457..5d6b123c5d 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MicrofiberFabric/microfiber_fabric.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MicrofiberFabric/microfiber_fabric.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MixedStones/mixed_stones.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MixedStones/mixed_stones.material index b6dea22b24..c3a916b0bb 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MixedStones/mixed_stones.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/MixedStones/mixed_stones.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/MixedStones/mixed_stones_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Nickle/nickle.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Nickle/nickle.material index 82ff63aa20..9bec82bfd2 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Nickle/nickle.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Nickle/nickle.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plaster/plaster.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plaster/plaster.material index cdf76f612d..73ff1024e3 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plaster/plaster.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plaster/plaster.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_01/plastic_01.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_01/plastic_01.material index 227017e1ab..bbac80a528 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_01/plastic_01.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_01/plastic_01.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_02/plastic_02.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_02/plastic_02.material index c30c3234c0..52c7ec11fb 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_02/plastic_02.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_02/plastic_02.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_03/plastic_03.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_03/plastic_03.material index 433c56251d..e7feda6620 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_03/plastic_03.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Plastic_03/plastic_03.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Platinum/platinum.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Platinum/platinum.material index 6613a21f2c..95b9f5767c 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Platinum/platinum.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Platinum/platinum.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Porcelain/porcelain.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Porcelain/porcelain.material index cef8ed194e..9b481628b5 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Porcelain/porcelain.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Porcelain/porcelain.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/RotaryBrushedSteel/rotary_brushed_steel.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/RotaryBrushedSteel/rotary_brushed_steel.material index 866c18d650..ae6753bffc 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/RotaryBrushedSteel/rotary_brushed_steel.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/RotaryBrushedSteel/rotary_brushed_steel.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Rust/rust.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Rust/rust.material index f6f2bdc52b..0ef4da333e 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Rust/rust.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Rust/rust.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Rust/rust_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Suede/suede.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Suede/suede.material index 782ed7451c..ae3288cbe9 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Suede/suede.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/Suede/suede.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/Suede/suede_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/TireRubber/tire_rubber.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/TireRubber/tire_rubber.material index 2fc5cec7a4..1cbd3a168a 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/TireRubber/tire_rubber.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/TireRubber/tire_rubber.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WoodPlanks/wood_planks.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WoodPlanks/wood_planks.material index 91f89a0a1b..0320a9a0f7 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WoodPlanks/wood_planks.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WoodPlanks/wood_planks.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/WoodPlanks/wood_planks_diffuse.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WornMetal/warn_metal.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WornMetal/warn_metal.material index cfdba2d2ef..876b404156 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WornMetal/warn_metal.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/WornMetal/warn_metal.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Materials/WornMetal/worn_metal_basecolor.jpg" diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/black.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/black.material index 56759107c9..f610fd7da0 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/black.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/black.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/white.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/blue.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/blue.material index 4691b674e0..1318552396 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/blue.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/blue.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/white.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/green.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/green.material index 6e118ddc7c..c378e48167 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/green.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/green.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/white.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/grey.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/grey.material index 82e8b17127..751561f5d1 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/grey.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/grey.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/white.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/red.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/red.material index 2527f82148..edb1cde854 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/red.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/red.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "Materials/white.material", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/white.material b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/white.material index bfb95933c4..b7383ff5e0 100644 --- a/Gems/AtomContent/ReferenceMaterials/Assets/Materials/white.material +++ b/Gems/AtomContent/ReferenceMaterials/Assets/Materials/white.material @@ -2,5 +2,5 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3 + "materialTypeVersion": 3 } diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material index cc2c9e785b..d15aa620c7 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material index a4bfb73d12..579359b085 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material index fe9c54bc02..88d5fc0fc6 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material index a19afa33e2..7244397ee9 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material index 0c1208d8fb..8a3f289c26 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material index 6aad4d644a..7bc193978f 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material index 302589dc85..a53cbef4e4 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material index 5217a4e4be..6ddb645319 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material index dba44f7b49..e3d310cd15 100644 --- a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/Gems/AtomContent/Sponza/Assets/objects/lightBlocker_lambert1.material b/Gems/AtomContent/Sponza/Assets/objects/lightBlocker_lambert1.material index c8e9f1f8f7..35677a81c6 100644 --- a/Gems/AtomContent/Sponza/Assets/objects/lightBlocker_lambert1.material +++ b/Gems/AtomContent/Sponza/Assets/objects/lightBlocker_lambert1.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "emissive": { "color": [ diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/maya_materials_export.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/maya_materials_export.py index d7280dc8cc..d5593002c9 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/maya_materials_export.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/maya_materials_export.py @@ -382,7 +382,7 @@ class MayaToLumberyard(QtWidgets.QWidget): material = {'description': name, 'materialType': default_settings.get('materialType'), 'parentMaterial': default_settings.get('parentMaterial'), - 'propertyLayoutVersion': default_settings.get('propertyLayoutVersion'), + 'materialTypeVersion': default_settings.get('materialTypeVersion'), 'properties': self.get_shader_properties(name, material_type, file_connections)} self.material_definitions[name if name not in self.material_definitions.keys() else self.get_increment(name)] = material diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/pbr.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/pbr.material index 94fc5a16bd..f156f60d33 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/pbr.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Atom/Scripts/Python/DCC_Materials/pbr.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 1.0, diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/main.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/main.py index 860273d1eb..869f9bafc5 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/main.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/main.py @@ -628,7 +628,7 @@ class MaterialsToLumberyard(QtWidgets.QWidget): 'description': name, 'materialType': default_settings.get('materialType'), 'parentMaterial': default_settings.get('parentMaterial'), - 'propertyLayoutVersion': default_settings.get('propertyLayoutVersion'), + 'materialTypeVersion': default_settings.get('materialTypeVersion'), 'properties': self.get_lumberyard_material_properties(name, dcc_app, material_type, file_connections)} self.lumberyard_materials_dictionary[name if name not in self.lumberyard_materials_dictionary.keys() else self.get_filename_increment(name)] = material diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/materials_export.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/materials_export.py index ea0182bb9b..5243a45ec9 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/materials_export.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/materials_export.py @@ -546,7 +546,7 @@ class MaterialsToLumberyard(QtWidgets.QWidget): 'description': name, 'materialType': default_settings.get('materialType'), 'parentMaterial': default_settings.get('parentMaterial'), - 'propertyLayoutVersion': default_settings.get('propertyLayoutVersion'), + 'materialTypeVersion': default_settings.get('materialTypeVersion'), 'properties': self.get_lumberyard_material_properties(name, material_type, file_connections)} self.material_definitions[name if name not in self.material_definitions.keys() else self.get_filename_increment(name)] = material diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/pbr.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/pbr.material index 94fc5a16bd..f156f60d33 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/pbr.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/dcc_materials/pbr.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 1.0, diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/kitbash_converter/standardPBR.template.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/kitbash_converter/standardPBR.template.material index cc2c548174..71d3df3471 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/kitbash_converter/standardPBR.template.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/kitbash_converter/standardPBR.template.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "texcoord": 0 diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/legacy_asset_converter/standardPBR.template.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/legacy_asset_converter/standardPBR.template.material index 78891d6c46..fe2a22a1fe 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/legacy_asset_converter/standardPBR.template.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/legacy_asset_converter/standardPBR.template.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "texcoord": 0 diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/maya_materials_export.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/maya_materials_export.py index ad481ba5b1..e7ec878397 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/maya_materials_export.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/maya_materials_export.py @@ -387,7 +387,7 @@ class MayaToLumberyard(QtWidgets.QWidget): material = {'description': name, 'materialType': default_settings.get('materialType'), 'parentMaterial': default_settings.get('parentMaterial'), - 'propertyLayoutVersion': default_settings.get('propertyLayoutVersion'), + 'materialTypeVersion': default_settings.get('materialTypeVersion'), 'properties': self.get_shader_properties(name, material_type, file_connections)} self.material_definitions[name if name not in self.material_definitions.keys() else self.get_increment(name)] = material diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/standardpbr.template.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/standardpbr.template.material index 30d895f9ac..936b6a0eb1 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/standardpbr.template.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/maya_dcc_materials/standardpbr.template.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 1.0, diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/stingraypbs_converter/StandardPBR_AllProperties.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/stingraypbs_converter/StandardPBR_AllProperties.material index 00ff63829f..c5f8395e5e 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/stingraypbs_converter/StandardPBR_AllProperties.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/Python/stingraypbs_converter/StandardPBR_AllProperties.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "occlusion": { "diffuseFactor": 1.0, diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/StandardPBR_AllProperties.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/StandardPBR_AllProperties.material index 7d38d1a1a3..052c0a3dcb 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/StandardPBR_AllProperties.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/StandardPBR_AllProperties.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "texcoord": 0 diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom.material index 26f4dd7508..60b3f7021f 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom.material @@ -1,7 +1,7 @@ { "material": { "baseMaterial": "StaticMesh.basematerial", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "general": { "DiffuseColor": [ 1.0, 0.5, 0.5, 1.0 ], diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom_variant00.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom_variant00.material index 26d30908b8..dc4e2293b9 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom_variant00.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Substance/resources/atom/atom_variant00.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials\\StandardPBR\\StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "texcoord": 0 diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Tools/Resources/Atom/StandardPBR_AllProperties.material b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Tools/Resources/Atom/StandardPBR_AllProperties.material index 7d38d1a1a3..052c0a3dcb 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Tools/Resources/Atom/StandardPBR_AllProperties.material +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Tools/Resources/Atom/StandardPBR_AllProperties.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "general": { "texcoord": 0 diff --git a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_body_mat.material b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_body_mat.material index 2ebfc261b7..8e7c325700 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_body_mat.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_body_mat.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_eye_mat.material b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_eye_mat.material index 87c8b7dab5..61041448c5 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_eye_mat.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken_chicken_eye_mat.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material index 8d645287f6..1350910624 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material index 9340723882..64db8c1444 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_blinds_broken.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material index 682be41887..a55b9cc715 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_four.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material index 6ff5a554d3..0294285d36 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_corners_two.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material index c65a3afdbe..1f86911beb 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material +++ b/Gems/NvCloth/Assets/Objects/cloth/Environment/cloth_locked_edge.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "color": [ diff --git a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Box_1x1_MiddleGrey.material b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Box_1x1_MiddleGrey.material index dee26ff898..586af47cbc 100644 --- a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Box_1x1_MiddleGrey.material +++ b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Box_1x1_MiddleGrey.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/_Primitives/Middle_Gray_Checker.tif" diff --git a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Cylinder_1x1_MiddleGrey.material b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Cylinder_1x1_MiddleGrey.material index dee26ff898..586af47cbc 100644 --- a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Cylinder_1x1_MiddleGrey.material +++ b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Cylinder_1x1_MiddleGrey.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/_Primitives/Middle_Gray_Checker.tif" diff --git a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Sphere_1x1_MiddleGrey.material b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Sphere_1x1_MiddleGrey.material index 718d951bb2..db9e3624be 100644 --- a/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Sphere_1x1_MiddleGrey.material +++ b/Gems/PrimitiveAssets/Assets/Objects/_Primitives/_Sphere_1x1_MiddleGrey.material @@ -2,7 +2,7 @@ "description": "", "materialType": "Materials/Types/StandardPBR.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 3, + "materialTypeVersion": 3, "properties": { "baseColor": { "textureMap": "Textures/_Primitives/Middle_Gray_Checker.tif" diff --git a/Gems/Terrain/Assets/Materials/Terrain/DefaultPbrTerrain.material b/Gems/Terrain/Assets/Materials/Terrain/DefaultPbrTerrain.material index da2fc95293..fca5130653 100644 --- a/Gems/Terrain/Assets/Materials/Terrain/DefaultPbrTerrain.material +++ b/Gems/Terrain/Assets/Materials/Terrain/DefaultPbrTerrain.material @@ -2,7 +2,7 @@ "description": "", "materialType": "PbrTerrain.materialtype", "parentMaterial": "", - "propertyLayoutVersion": 1, + "materialTypeVersion": 1, "properties": { "baseColor": { "color": [ 0.18, 0.18, 0.18 ] From fbfea49b68dbd0fb5c139087a6acbfe4a2f0c6be Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 18 Jan 2022 23:55:40 -0800 Subject: [PATCH 246/272] small comment tweak based on feedback Signed-off-by: Gene Walters --- .../Code/Source/NetworkEntity/NetworkSpawnableLibrary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h index 469086f4cb..ab6211f522 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkSpawnableLibrary.h @@ -26,7 +26,7 @@ namespace Multiplayer //! INetworkSpawnableLibrary overrides. //! @{ // Iterates over all assets (on-disk and in-memory) and stores any spawnables that are "network.spawnables" - // This allows us to look up network spawnable assets by name or id for later use + // This allows users to look up network spawnable assets by name or id if needed later void BuildSpawnablesList() override; void ProcessSpawnableAsset(const AZStd::string& relativePath, AZ::Data::AssetId id) override; AZ::Name GetSpawnableNameFromAssetId(AZ::Data::AssetId assetId) override; From 667a9df34231b2215cda2877b8f2ae0c70e2b243 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Wed, 19 Jan 2022 17:20:27 +0100 Subject: [PATCH 247/272] ImGui: Added new histogram group helper (#6998) * Added a helper class for a group containing several histograms. * The group is shown using collapsible header. Signed-off-by: Benjamin Jillich --- .../Include/LYImGuiUtils/HistogramGroup.h | 54 ++++++++++++ .../Source/LYImGuiUtils/HistogramGroup.cpp | 82 +++++++++++++++++++ .../Code/imgui_lyutils_static_files.cmake | 2 + 3 files changed, 138 insertions(+) create mode 100644 Gems/ImGui/Code/Include/LYImGuiUtils/HistogramGroup.h create mode 100644 Gems/ImGui/Code/Source/LYImGuiUtils/HistogramGroup.cpp diff --git a/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramGroup.h b/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramGroup.h new file mode 100644 index 0000000000..b3c7e0e7d8 --- /dev/null +++ b/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramGroup.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#ifdef IMGUI_ENABLED + +#include +#include +#include + +#include +#include + +namespace ImGui::LYImGuiUtils +{ + //! Helper for a group containing several histograms. + //! The group is shown using collapsible header. + class HistogramGroup + { + public: + HistogramGroup() = default; + HistogramGroup(const char* name, int histogramBinCount); + + void OnImGuiUpdate(); + void PushHistogramValue(const char* valueName, float value, const AZ::Color& color); + + const char* GetName() const { return m_name.c_str(); } + const AZStd::string& GetNameString() const { return m_name; } + void SetName(AZStd::string name) { m_name = name; } + + void SetHistogramBinCount(int count) { m_histogramBinCount = count; } + + //! Needs to be public for l-value access for ImGui::MenuItem() + bool m_show = true; + + private: + AZStd::string m_name; //< The name shown in the collapsible header. + int m_histogramBinCount = 100; //< The number of bins in the histogram. + + using HistogramIndexByNames = AZStd::unordered_map; + HistogramIndexByNames m_histogramIndexByName; //< Look-up table for the histogram index by name. + AZStd::vector m_histograms; //< Owns the histogram containers. + + static constexpr float s_histogramHeight = 85.0f; + }; +} // namespace ImGui::LYImGuiUtils + +#endif // IMGUI_ENABLED diff --git a/Gems/ImGui/Code/Source/LYImGuiUtils/HistogramGroup.cpp b/Gems/ImGui/Code/Source/LYImGuiUtils/HistogramGroup.cpp new file mode 100644 index 0000000000..62e8eb7b33 --- /dev/null +++ b/Gems/ImGui/Code/Source/LYImGuiUtils/HistogramGroup.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#ifdef IMGUI_ENABLED +#include "LYImGuiUtils/HistogramGroup.h" + +namespace ImGui::LYImGuiUtils +{ + HistogramGroup::HistogramGroup(const char* name, int histogramBinCount) + : m_name(name) + , m_histogramBinCount(histogramBinCount) + { + } + + void HistogramGroup::PushHistogramValue(const char* valueName, float value, const AZ::Color& color) + { + auto iterator = m_histogramIndexByName.find(valueName); + if (iterator != m_histogramIndexByName.end()) + { + ImGui::LYImGuiUtils::HistogramContainer& histogramContiner = m_histograms[iterator->second]; + histogramContiner.PushValue(value); + histogramContiner.SetBarLineColor(ImColor(color.GetR(), color.GetG(), color.GetB(), color.GetA())); + } + else + { + ImGui::LYImGuiUtils::HistogramContainer newHistogram; + newHistogram.Init(/*histogramName=*/valueName, + /*containerCount=*/m_histogramBinCount, + /*viewType=*/ImGui::LYImGuiUtils::HistogramContainer::ViewType::Histogram, + /*displayOverlays=*/true, + /*min=*/0.0f, + /*max=*/0.0f); + + newHistogram.SetMoveDirection(ImGui::LYImGuiUtils::HistogramContainer::PushRightMoveLeft); + newHistogram.PushValue(value); + + m_histogramIndexByName[valueName] = m_histograms.size(); + m_histograms.push_back(newHistogram); + } + } + + void HistogramGroup::OnImGuiUpdate() + { + if (!m_show) + { + return; + } + + if (ImGui::CollapsingHeader(m_name.c_str(), ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed)) + { + for (auto& histogram : m_histograms) + { + ImGui::BeginGroup(); + { + histogram.Draw(ImGui::GetColumnWidth() - 70, s_histogramHeight); + + ImGui::SameLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0,0,0,255)); + { + const ImColor color = histogram.GetBarLineColor(); + ImGui::PushStyleColor(ImGuiCol_Button, color.Value); + { + const AZStd::string valueString = AZStd::string::format("%.2f", histogram.GetLastValue()); + ImGui::Button(valueString.c_str()); + } + ImGui::PopStyleColor(); + } + ImGui::PopStyleColor(); + } + ImGui::EndGroup(); + } + } + } +} // namespace ImGui::LYImGuiUtils + +#endif // IMGUI_ENABLED diff --git a/Gems/ImGui/Code/imgui_lyutils_static_files.cmake b/Gems/ImGui/Code/imgui_lyutils_static_files.cmake index d63730e6cb..9807cfe29d 100644 --- a/Gems/ImGui/Code/imgui_lyutils_static_files.cmake +++ b/Gems/ImGui/Code/imgui_lyutils_static_files.cmake @@ -8,7 +8,9 @@ set(FILES Include/LYImGuiUtils/HistogramContainer.h + Include/LYImGuiUtils/HistogramGroup.h Include/LYImGuiUtils/ImGuiDrawHelpers.h Source/LYImGuiUtils/HistogramContainer.cpp + Source/LYImGuiUtils/HistogramGroup.cpp Source/LYImGuiUtils/ImGuiDrawHelpers.cpp ) From 65a749494e01453f542ddbdfe143894608bc1be2 Mon Sep 17 00:00:00 2001 From: Ignacio Martinez <82394219+AMZN-Igarri@users.noreply.github.com> Date: Wed, 19 Jan 2022 17:45:52 +0100 Subject: [PATCH 248/272] Fix: Entity Outliner: Outliner is unusable with the Editor in slice mode (#6983) * Fixed vertical offset Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Fixed QPoint Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Fixed Entry delegate Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * SetRenderHint in Entry delegate Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Save and restore painter inside the highlighter Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Restoring Painter Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Removed comment Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../UI/Outliner/OutlinerListModel.cpp | 7 ++++--- .../AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp | 1 + .../AzToolsFramework/Editor/RichTextHighlighter.cpp | 8 +++----- .../AzToolsFramework/Editor/RichTextHighlighter.h | 3 ++- .../UI/Outliner/EntityOutlinerListModel.cpp | 2 ++ 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp index 1c361b050d..39be4839e6 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp @@ -2599,11 +2599,12 @@ void OutlinerItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optionV4.text.clear(); optionV4.widget->style()->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); - // Now we setup a Text Document so it can draw the rich text int verticalOffset = GetEntityNameVerticalOffset(entityId); - painter->translate(textRect.topLeft() + QPoint(0, verticalOffset)); - AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect); + AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText( + entityNameRichText, painter, optionV4, textRect, QPoint(0, verticalOffset)); + + painter->restore(); OutlinerListModel::s_paintingName = false; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp index 8e69d5f788..5711ca2608 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp @@ -290,6 +290,7 @@ namespace AzToolsFramework { displayString = RichTextHighlighter::HighlightText(displayString, m_assetBrowserFilerModel->GetStringFilter()->GetFilterString()); } + RichTextHighlighter::PaintHighlightedRichText(displayString, painter, optionV4, remainingRect); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp index 8b28298c3d..f22fdd16b4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.cpp @@ -29,12 +29,11 @@ namespace AzToolsFramework return highlightedString; } - void RichTextHighlighter::PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect) + void RichTextHighlighter::PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect, QPoint offset /* = QPoint()*/) { + // Now we setup a Text Document so it can draw the rich text painter->save(); painter->setRenderHint(QPainter::Antialiasing); - - // Now we setup a Text Document so it can draw the rich text QTextDocument textDoc; textDoc.setDefaultFont(option.font); if (option.state & QStyle::State_Enabled) @@ -46,10 +45,9 @@ namespace AzToolsFramework textDoc.setDefaultStyleSheet("body {color: #7C7C7C}"); } textDoc.setHtml("" + highlightedString + ""); - painter->translate(availableRect.topLeft()); + painter->translate(availableRect.topLeft() + offset); textDoc.setTextWidth(availableRect.width()); textDoc.drawContents(painter, QRectF(0, 0, availableRect.width(), availableRect.height())); - painter->restore(); } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h index b5c1859497..cdcb0b14b3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Editor/RichTextHighlighter.h @@ -30,7 +30,8 @@ namespace AzToolsFramework RichTextHighlighter() = delete; static QString HighlightText(const QString& displayString, const QString& matchingSubstring); - static void PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, QRect availableRect); + static void PaintHighlightedRichText(const QString& highlightedString,QPainter* painter, QStyleOptionViewItem option, + QRect availableRect, QPoint offset = QPoint()); }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp index e0060e2b42..93e4ffd3da 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp @@ -2368,6 +2368,8 @@ namespace AzToolsFramework AzToolsFramework::RichTextHighlighter::PaintHighlightedRichText(entityNameRichText, painter, optionV4, textRect); + painter->restore(); + EntityOutlinerListModel::s_paintingName = false; } From 9d3f8e0b7dfd81bfc091b072505e615f2f21e8ba Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Wed, 19 Jan 2022 09:09:32 -0800 Subject: [PATCH 249/272] [development] minor Android toolchain updates (#6931) Fixed issue with Android NDK r23 native only builds where the platform version was ignored Bumped the default ANDROID_NATIVE_API_LEVEL to 24 so it matches the Android project generator scripts Removed some unnecessary information from message strings Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- cmake/Platform/Android/Toolchain_android.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Android/Toolchain_android.cmake b/cmake/Platform/Android/Toolchain_android.cmake index 75ff4554fd..974eb33681 100644 --- a/cmake/Platform/Android/Toolchain_android.cmake +++ b/cmake/Platform/Android/Toolchain_android.cmake @@ -37,9 +37,9 @@ if(NOT ANDROID_ABI MATCHES "^arm64-") message(FATAL_ERROR "Only the 64-bit ANDROID_ABI's are supported. arm64-v8a can be used if not set") endif() if(NOT ANDROID_NATIVE_API_LEVEL) - set(ANDROID_NATIVE_API_LEVEL 21) + set(ANDROID_NATIVE_API_LEVEL 24) endif() - +set(ANDROID_PLATFORM android-${ANDROID_NATIVE_API_LEVEL}) # Make a backup of the CMAKE_FIND_ROOT_PATH since it will be altered by the NDK toolchain file and needs to be restored after the input set(BACKUP_CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}) @@ -64,9 +64,9 @@ set(LY_TOOLCHAIN_NDK_API_LEVEL ${ANDROID_PLATFORM_LEVEL}) set(MIN_NDK_VERSION 21) if(${LY_TOOLCHAIN_NDK_PKG_MAJOR} VERSION_LESS ${MIN_NDK_VERSION}) - message(FATAL_ERROR "Unsupported NDK Version ${LY_TOOLCHAIN_NDK_PKG_MAJOR}.${LY_TOOLCHAIN_NDK_PKG_MINOR}.${LY_TOOLCHAIN_NDK_API_LEVEL}. Must be version ${MIN_NDK_VERSION} or above") + message(FATAL_ERROR "Unsupported NDK Version ${LY_TOOLCHAIN_NDK_PKG_MAJOR}.${LY_TOOLCHAIN_NDK_PKG_MINOR}. Must be version ${MIN_NDK_VERSION} or above") else() - message(STATUS "Detected NDK Version ${LY_TOOLCHAIN_NDK_PKG_MAJOR}.${LY_TOOLCHAIN_NDK_PKG_MINOR}.${LY_TOOLCHAIN_NDK_PKG_MINOR}") + message(STATUS "Detected NDK Version ${LY_TOOLCHAIN_NDK_PKG_MAJOR}.${LY_TOOLCHAIN_NDK_PKG_MINOR}") endif() list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES LY_NDK_DIR) From a63ea12a1f6a47ba6ea27ce2ad847526023b1180 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Wed, 19 Jan 2022 09:52:27 -0800 Subject: [PATCH 250/272] System shortcuts crash the Editor when Global Preferences are open (#6994) * Changes to the keyPressEvent override of the Editor Preferences Dialog to prevent infinite loops on focus switches. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Renaming function to clarify its purpose. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- Code/Editor/EditorPreferencesDialog.cpp | 22 ++++++++++++---------- Code/Editor/EditorPreferencesDialog.h | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Code/Editor/EditorPreferencesDialog.cpp b/Code/Editor/EditorPreferencesDialog.cpp index 665daf52a8..42f7446716 100644 --- a/Code/Editor/EditorPreferencesDialog.cpp +++ b/Code/Editor/EditorPreferencesDialog.cpp @@ -112,29 +112,31 @@ void EditorPreferencesDialog::showEvent(QShowEvent* event) QDialog::showEvent(event); } -void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event) +bool WidgetConsumesKeyPressEvent(QKeyEvent* event) { // If the enter key is pressed during any text input, the dialog box will close // making it inconvenient to do multiple edits. This routine captures the // Key_Enter or Key_Return and clears the focus to give a visible cue that - // editing of that field has finished and then doesn't propogate it. + // editing of that field has finished and then doesn't propagate it. if (event->key() != Qt::Key::Key_Enter && event->key() != Qt::Key::Key_Return) { - QApplication::sendEvent(widget, event); + return false; } - else + + if (QWidget* editWidget = QApplication::focusWidget()) { - if (QWidget* editWidget = QApplication::focusWidget()) - { - editWidget->clearFocus(); - } + editWidget->clearFocus(); } -} + return true; +} void EditorPreferencesDialog::keyPressEvent(QKeyEvent* event) { - WidgetHandleKeyPressEvent(this, event); + if (!WidgetConsumesKeyPressEvent(event)) + { + QDialog::keyPressEvent(event); + } } void EditorPreferencesDialog::OnTreeCurrentItemChanged() diff --git a/Code/Editor/EditorPreferencesDialog.h b/Code/Editor/EditorPreferencesDialog.h index a3f05ad00d..70a186375b 100644 --- a/Code/Editor/EditorPreferencesDialog.h +++ b/Code/Editor/EditorPreferencesDialog.h @@ -19,7 +19,7 @@ namespace Ui class EditorPreferencesTreeWidgetItem; -void WidgetHandleKeyPressEvent(QWidget* widget, QKeyEvent* event); +bool WidgetConsumesKeyPressEvent(QKeyEvent* event); class EditorPreferencesDialog : public QDialog From ca56770655b0f79b7d3e1f6322def650549feb05 Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Wed, 19 Jan 2022 10:50:56 -0800 Subject: [PATCH 251/272] [AWSMetrics] Update the auto-generated code to follow O3DE coding standard (#6910) * [AWSMetrics] Update the auto-generated code to follow O3DE coding standard Signed-off-by: Junbo Liang <68558268+junbo75@users.noreply.github.com> --- .../Code/Source/AWSMetricsConstant.h | 18 ++--- .../Code/Source/AWSMetricsServiceApi.cpp | 65 ++++++++++++------- .../Code/Source/AWSMetricsServiceApi.h | 44 +++++++------ .../AWSMetrics/Code/Source/MetricsManager.cpp | 26 ++++---- Gems/AWSMetrics/Code/Source/MetricsManager.h | 5 +- .../Code/Tests/AWSMetricsServiceApiTest.cpp | 48 +++++++------- .../Code/Tests/MetricsManagerTest.cpp | 16 ++--- Gems/AWSMetrics/cdk/api_spec.json | 26 ++++---- 8 files changed, 136 insertions(+), 112 deletions(-) diff --git a/Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h b/Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h index ecb2b5dcfa..8779b66355 100644 --- a/Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h +++ b/Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h @@ -21,16 +21,16 @@ namespace AWSMetrics static constexpr char AwsMetricsAttributeKeyEventData[] = "event_data"; //! Service API request and response object keys - static constexpr char AwsMetricsSuccessResponseRecordKeyErrorCode[] = "error_code"; - static constexpr char AwsMetricsSuccessResponseRecordKeyResult[] = "result"; - static constexpr char AwsMetricsSuccessResponseKeyFailedRecordCount[] = "failed_record_count"; - static constexpr char AwsMetricsSuccessResponseKeyEvents[] = "events"; - static constexpr char AwsMetricsSuccessResponseKeyTotal[] = "total"; - static constexpr char AwsMetricsErrorKeyMessage[] = "message"; - static constexpr char AwsMetricsErrorKeyType[] = "type"; - static constexpr char AwsMetricsRequestParameterKeyEvents[] = "events"; + static constexpr char AwsMetricsPostMetricsEventsResponseEntryKeyErrorCode[] = "error_code"; + static constexpr char AwsMetricsPostMetricsEventsResponseEntryKeyResult[] = "result"; + static constexpr char AwsMetricsPostMetricsEventsResponseKeyFailedRecordCount[] = "failed_record_count"; + static constexpr char AwsMetricsPostMetricsEventsResponseKeyEvents[] = "events"; + static constexpr char AwsMetricsPostMetricsEventsResponseKeyTotal[] = "total"; + static constexpr char AwsMetricsPostMetricsEventsErrorKeyMessage[] = "message"; + static constexpr char AwsMetricsPostMetricsEventsErrorKeyType[] = "type"; + static constexpr char AwsMetricsPostMetricsEventsRequestParameterKeyEvents[] = "events"; - static constexpr char AwsMetricsSuccessResponseRecordResult[] = "Ok"; + static constexpr char AwsMetricsPostMetricsEventsResponseEntrySuccessResult[] = "Ok"; //! Service API limits //! https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html diff --git a/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.cpp b/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.cpp index 7e568e0c40..b7e9d7a1a9 100644 --- a/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.cpp +++ b/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.cpp @@ -15,56 +15,77 @@ namespace AWSMetrics { namespace ServiceAPI { - bool MetricsEventSuccessResponseRecord::OnJsonKey(const char* key, AWSCore::JsonReader& reader) + bool PostMetricsEventsResponseEntry::OnJsonKey(const char* key, AWSCore::JsonReader& reader) { - if (strcmp(key, AwsMetricsSuccessResponseRecordKeyErrorCode) == 0) return reader.Accept(errorCode); + if (strcmp(key, AwsMetricsPostMetricsEventsResponseEntryKeyErrorCode) == 0) + { + return reader.Accept(m_errorCode); + } - if (strcmp(key, AwsMetricsSuccessResponseRecordKeyResult) == 0) return reader.Accept(result); + if (strcmp(key, AwsMetricsPostMetricsEventsResponseEntryKeyResult) == 0) + { + return reader.Accept(m_result); + } return reader.Ignore(); } - bool MetricsEventSuccessResponse::OnJsonKey(const char* key, AWSCore::JsonReader& reader) + bool PostMetricsEventsResponse::OnJsonKey(const char* key, AWSCore::JsonReader& reader) { - if (strcmp(key, AwsMetricsSuccessResponseKeyFailedRecordCount) == 0) return reader.Accept(failedRecordCount); + if (strcmp(key, AwsMetricsPostMetricsEventsResponseKeyFailedRecordCount) == 0) + { + return reader.Accept(m_failedRecordCount); + } - if (strcmp(key, AwsMetricsSuccessResponseKeyEvents) == 0) return reader.Accept(events); + if (strcmp(key, AwsMetricsPostMetricsEventsResponseKeyEvents) == 0) + { + return reader.Accept(m_responseEntries); + } - if (strcmp(key, AwsMetricsSuccessResponseKeyTotal) == 0) return reader.Accept(total); + if (strcmp(key, AwsMetricsPostMetricsEventsResponseKeyTotal) == 0) + { + return reader.Accept(m_total); + } return reader.Ignore(); } - bool Error::OnJsonKey(const char* key, AWSCore::JsonReader& reader) + bool PostMetricsEventsError::OnJsonKey(const char* key, AWSCore::JsonReader& reader) { - if (strcmp(key, AwsMetricsErrorKeyMessage) == 0) return reader.Accept(message); + if (strcmp(key, AwsMetricsPostMetricsEventsErrorKeyMessage) == 0) + { + return reader.Accept(message); + } - if (strcmp(key, AwsMetricsErrorKeyType) == 0) return reader.Accept(type); + if (strcmp(key, AwsMetricsPostMetricsEventsErrorKeyType) == 0) + { + return reader.Accept(type); + } return reader.Ignore(); } - // Generated Function Parameters - bool PostProducerEventsRequest::Parameters::BuildRequest(AWSCore::RequestBuilder& request) + // Generated request parameters + bool PostMetricsEventsRequest::Parameters::BuildRequest(AWSCore::RequestBuilder& request) { - bool ok = true; + bool buildResult = true; + buildResult = buildResult && request.WriteJsonBodyParameter(*this); - ok = ok && request.WriteJsonBodyParameter(*this); - return ok; + return buildResult; } - bool PostProducerEventsRequest::Parameters::WriteJson(AWSCore::JsonWriter& writer) const + bool PostMetricsEventsRequest::Parameters::WriteJson(AWSCore::JsonWriter& writer) const { - bool ok = true; + bool writeResult = true; - ok = ok && writer.StartObject(); + writeResult = writeResult && writer.StartObject(); - ok = ok && writer.Key(AwsMetricsRequestParameterKeyEvents); - ok = ok && data.SerializeToJson(writer); + writeResult = writeResult && writer.Key(AwsMetricsPostMetricsEventsRequestParameterKeyEvents); + writeResult = writeResult && m_metricsQueue.SerializeToJson(writer); - ok = ok && writer.EndObject(); + writeResult = writeResult && writer.EndObject(); - return ok; + return writeResult; } } } diff --git a/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h b/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h index a64c9f8a53..dde36fc04a 100644 --- a/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h +++ b/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h @@ -16,41 +16,44 @@ namespace AWSMetrics { namespace ServiceAPI { - //! Struct for storing event record from the response. - struct MetricsEventSuccessResponseRecord + //! Response for an individual metrics event from a PostMetricsEvents request. + //! If the event is successfully sent to the backend, it receives an "Ok" result. + //! If the event fails to be sent to the backend, the result includes an error code and an "Error" result. + struct PostMetricsEventsResponseEntry { - //! Identify the expected property type and provide a location where the property value can be stored. + //! Identify the expected property type in the response entry for each individual metrics event and provide a location where the property value can be stored. //! @param key Name of the property. //! @param reader JSON reader to read the property. bool OnJsonKey(const char* key, AWSCore::JsonReader& reader); - AZStd::string errorCode; //!< Error code if the event is not sent successfully. - AZStd::string result; //!< Processing result for the input record. + AZStd::string m_errorCode; //!< Error code if the individual metrics event failed to be sent. + AZStd::string m_result; //!< Result for the processed individual metrics event. Expected value: "Error" or "Ok". }; - using MetricsEventSuccessResponsePropertyEvents = AZStd::vector; + using PostMetricsEventsResponseEntries = AZStd::vector; - //! Struct for storing the success response. - struct MetricsEventSuccessResponse + //! Response for all the processed metrics events from a PostMetricsEvents request. + struct PostMetricsEventsResponse { - //! Identify the expected property type and provide a location where the property value can be stored. + //! Identify the expected property type in the response and provide a location where the property value can be stored. //! @param key Name of the property. //! @param reader JSON reader to read the property. bool OnJsonKey(const char* key, AWSCore::JsonReader& reader); - int failedRecordCount{ 0 }; //!< Number of events that failed to be saved to metrics events stream. - MetricsEventSuccessResponsePropertyEvents events; //! List of input event records. - int total{ 0 }; //!< Total number of events that were processed in the request + int m_failedRecordCount{ 0 }; //!< Number of events that failed to be sent to the backend. + PostMetricsEventsResponseEntries m_responseEntries; //! Response list for all the processed metrics events. + int m_total{ 0 }; //!< Total number of events that were processed in the request. }; - //! Struct for storing the failure response. - struct Error + //! Failure response for sending the PostMetricsEvents request. + struct PostMetricsEventsError { - //! Identify the expected property type and provide a location where the property value can be stored. + //! Identify the expected property type in the failure response and provide a location where the property value can be stored. //! @param key Name of the property. //! @param reader JSON reader to read the property. bool OnJsonKey(const char* key, AWSCore::JsonReader& reader); + //! Do not rename the following members since they are expected by the AWSCore dependency. AZStd::string message; //!< Error message. AZStd::string type; //!< Error type. }; @@ -60,7 +63,7 @@ namespace AWSMetrics //! POST request defined by api_spec.json to send metrics to the backend. //! The path for this service API is "/producer/events". - class PostProducerEventsRequest + class PostMetricsEventsRequest : public AWSCore::ServiceRequest { public: @@ -79,14 +82,15 @@ namespace AWSMetrics //! @return Whether the serialization is successful. bool WriteJson(AWSCore::JsonWriter& writer) const; - MetricsQueue data; //!< Data to send via the service API request. + MetricsQueue m_metricsQueue; //!< Metrics events to send via the service API request. }; - MetricsEventSuccessResponse result; //! Success response. - Error error; //! Failure response. + //! Do not rename the following members since they are expected by the AWSCore dependency. + PostMetricsEventsResponse result; //! Success response. + PostMetricsEventsError error; //! Failure response. Parameters parameters; //! Request parameter. }; - using PostProducerEventsRequestJob = AWSCore::ServiceRequestJob; + using PostMetricsEventsRequestJob = AWSCore::ServiceRequestJob; } // ServiceAPI } // AWSMetrics diff --git a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp index 03e31770ee..d484b8c169 100644 --- a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp +++ b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp @@ -172,17 +172,17 @@ namespace AWSMetrics if (outcome.IsSuccess()) { // Generate response records for success call to keep consistency with the Service API response - ServiceAPI::MetricsEventSuccessResponsePropertyEvents responseRecords; + ServiceAPI::PostMetricsEventsResponseEntries responseEntries; int numMetricsEventsInRequest = metricsQueue->GetNumMetrics(); for (int index = 0; index < numMetricsEventsInRequest; ++index) { - ServiceAPI::MetricsEventSuccessResponseRecord responseRecord; - responseRecord.result = AwsMetricsSuccessResponseRecordResult; + ServiceAPI::PostMetricsEventsResponseEntry responseEntry; + responseEntry.m_result = AwsMetricsPostMetricsEventsResponseEntrySuccessResult; - responseRecords.emplace_back(responseRecord); + responseEntries.emplace_back(responseEntry); } - OnResponseReceived(*metricsQueue, responseRecords); + OnResponseReceived(*metricsQueue, responseEntries); AZ::TickBus::QueueFunction([requestId]() { @@ -209,19 +209,19 @@ namespace AWSMetrics { int requestId = ++m_sendMetricsId; - ServiceAPI::PostProducerEventsRequestJob* requestJob = ServiceAPI::PostProducerEventsRequestJob::Create( - [this, requestId](ServiceAPI::PostProducerEventsRequestJob* successJob) + ServiceAPI::PostMetricsEventsRequestJob* requestJob = ServiceAPI::PostMetricsEventsRequestJob::Create( + [this, requestId](ServiceAPI::PostMetricsEventsRequestJob* successJob) { - OnResponseReceived(successJob->parameters.data, successJob->result.events); + OnResponseReceived(successJob->parameters.m_metricsQueue, successJob->result.m_responseEntries); AZ::TickBus::QueueFunction([requestId]() { AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsSuccess, requestId); }); }, - [this, requestId](ServiceAPI::PostProducerEventsRequestJob* failedJob) + [this, requestId](ServiceAPI::PostMetricsEventsRequestJob* failedJob) { - OnResponseReceived(failedJob->parameters.data); + OnResponseReceived(failedJob->parameters.m_metricsQueue); AZStd::string errorMessage = failedJob->error.message; AZ::TickBus::QueueFunction([requestId, errorMessage]() @@ -230,11 +230,11 @@ namespace AWSMetrics }); }); - requestJob->parameters.data = AZStd::move(metricsQueue); + requestJob->parameters.m_metricsQueue = AZStd::move(metricsQueue); requestJob->Start(); } - void MetricsManager::OnResponseReceived(const MetricsQueue& metricsEventsInRequest, const ServiceAPI::MetricsEventSuccessResponsePropertyEvents& responseRecords) + void MetricsManager::OnResponseReceived(const MetricsQueue& metricsEventsInRequest, const ServiceAPI::PostMetricsEventsResponseEntries& responseEntries) { MetricsQueue metricsEventsForRetry; int numMetricsEventsInRequest = metricsEventsInRequest.GetNumMetrics(); @@ -242,7 +242,7 @@ namespace AWSMetrics { MetricsEvent metricsEvent = metricsEventsInRequest[index]; - if (responseRecords.size() > 0 && responseRecords[index].result == AwsMetricsSuccessResponseRecordResult) + if (responseEntries.size() > 0 && responseEntries[index].m_result == AwsMetricsPostMetricsEventsResponseEntrySuccessResult) { // The metrics event is sent to the backend successfully. if (metricsEvent.GetNumFailures() == 0) diff --git a/Gems/AWSMetrics/Code/Source/MetricsManager.h b/Gems/AWSMetrics/Code/Source/MetricsManager.h index 3bb06acd75..63a614ae67 100644 --- a/Gems/AWSMetrics/Code/Source/MetricsManager.h +++ b/Gems/AWSMetrics/Code/Source/MetricsManager.h @@ -60,9 +60,8 @@ namespace AWSMetrics //! Update the global stats and add qualified failed metrics events back to the buffer for retry. //! @param metricsEventsInRequest Metrics events in the original request. - //! @param responseRecords Response records from the call. Each record in the list contains the result for sending the corresponding metrics event. - void OnResponseReceived(const MetricsQueue& metricsEventsInRequest, const ServiceAPI::MetricsEventSuccessResponsePropertyEvents& responseRecords = - ServiceAPI::MetricsEventSuccessResponsePropertyEvents()); + //! @param responseEntries Response list for all the processed metrics events. + void OnResponseReceived(const MetricsQueue& metricsEventsInRequest, const ServiceAPI::PostMetricsEventsResponseEntries& responseEntries = ServiceAPI::PostMetricsEventsResponseEntries()); //! Implementation for flush all metrics buffered in memory. void FlushMetricsAsync(); diff --git a/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp b/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp index b7e7527b20..2b7f92601b 100644 --- a/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp +++ b/Gems/AWSMetrics/Code/Tests/AWSMetricsServiceApiTest.cpp @@ -42,43 +42,43 @@ namespace AWSMetrics TEST_F(AWSMetricsServiceApiTest, OnJsonKey_MetricsEventSuccessResponseRecord_AcceptValidKeys) { - ServiceAPI::MetricsEventSuccessResponseRecord responseRecord; - responseRecord.result = "ok"; + ServiceAPI::PostMetricsEventsResponseEntry responseRecord; + responseRecord.m_result = "ok"; - EXPECT_CALL(JsonReader, Accept(responseRecord.result)).Times(1); - EXPECT_CALL(JsonReader, Accept(responseRecord.errorCode)).Times(1); + EXPECT_CALL(JsonReader, Accept(responseRecord.m_result)).Times(1); + EXPECT_CALL(JsonReader, Accept(responseRecord.m_errorCode)).Times(1); EXPECT_CALL(JsonReader, Ignore()).Times(1); - responseRecord.OnJsonKey(AwsMetricsSuccessResponseRecordKeyResult, JsonReader); - responseRecord.OnJsonKey(AwsMetricsSuccessResponseRecordKeyErrorCode, JsonReader); + responseRecord.OnJsonKey(AwsMetricsPostMetricsEventsResponseEntryKeyResult, JsonReader); + responseRecord.OnJsonKey(AwsMetricsPostMetricsEventsResponseEntryKeyErrorCode, JsonReader); responseRecord.OnJsonKey("other", JsonReader); } TEST_F(AWSMetricsServiceApiTest, OnJsonKeyWithEvents_MetricsEventSuccessResponseRecord_AcceptValidKeys) { // Verifiy that JsonReader accepts valid JSON keys in each event record from a success reponse - ServiceAPI::MetricsEventSuccessResponseRecord responseRecord; - responseRecord.result = "ok"; + ServiceAPI::PostMetricsEventsResponseEntry responseRecord; + responseRecord.m_result = "Ok"; - ServiceAPI::MetricsEventSuccessResponse response; - response.events.emplace_back(responseRecord); - response.failedRecordCount = 0; - response.total = 1; + ServiceAPI::PostMetricsEventsResponse response; + response.m_responseEntries.emplace_back(responseRecord); + response.m_failedRecordCount = 0; + response.m_total = 1; - EXPECT_CALL(JsonReader, Accept(response.failedRecordCount)).Times(1); - EXPECT_CALL(JsonReader, Accept(response.total)).Times(1); + EXPECT_CALL(JsonReader, Accept(response.m_failedRecordCount)).Times(1); + EXPECT_CALL(JsonReader, Accept(response.m_total)).Times(1); EXPECT_CALL(JsonReader, Accept(::testing::An())).Times(1); EXPECT_CALL(JsonReader, Ignore()).Times(1); - response.OnJsonKey(AwsMetricsSuccessResponseKeyFailedRecordCount, JsonReader); - response.OnJsonKey(AwsMetricsSuccessResponseKeyTotal, JsonReader); - response.OnJsonKey(AwsMetricsSuccessResponseKeyEvents, JsonReader); + response.OnJsonKey(AwsMetricsPostMetricsEventsResponseKeyFailedRecordCount, JsonReader); + response.OnJsonKey(AwsMetricsPostMetricsEventsResponseKeyTotal, JsonReader); + response.OnJsonKey(AwsMetricsPostMetricsEventsResponseKeyEvents, JsonReader); response.OnJsonKey("other", JsonReader); } TEST_F(AWSMetricsServiceApiTest, OnJsonKey_Error_AcceptValidKeys) { - ServiceAPI::Error error; + ServiceAPI::PostMetricsEventsError error; error.message = "error message"; error.type = "404"; @@ -86,16 +86,16 @@ namespace AWSMetrics EXPECT_CALL(JsonReader, Accept(error.type)).Times(1); EXPECT_CALL(JsonReader, Ignore()).Times(1); - error.OnJsonKey(AwsMetricsErrorKeyMessage, JsonReader); - error.OnJsonKey(AwsMetricsErrorKeyType, JsonReader); + error.OnJsonKey(AwsMetricsPostMetricsEventsErrorKeyMessage, JsonReader); + error.OnJsonKey(AwsMetricsPostMetricsEventsErrorKeyType, JsonReader); error.OnJsonKey("other", JsonReader); } TEST_F(AWSMetricsServiceApiTest, BuildRequestBody_PostProducerEventsRequest_SerializedMetricsQueue) { - ServiceAPI::PostProducerEventsRequest request; - request.parameters.data = MetricsQueue(); - request.parameters.data.AddMetrics(MetricsEventBuilder().Build()); + ServiceAPI::PostMetricsEventsRequest request; + request.parameters.m_metricsQueue = MetricsQueue(); + request.parameters.m_metricsQueue.AddMetrics(MetricsEventBuilder().Build()); AWSCore::RequestBuilder requestBuilder{}; EXPECT_TRUE(request.parameters.BuildRequest(requestBuilder)); @@ -104,6 +104,6 @@ namespace AWSMetrics std::istreambuf_iterator eos; AZStd::string bodyString{ std::istreambuf_iterator(*bodyContent), eos }; - EXPECT_TRUE(bodyString.contains(AZStd::string::format("{\"%s\":[{\"event_timestamp\":", AwsMetricsRequestParameterKeyEvents))); + EXPECT_TRUE(bodyString.contains(AZStd::string::format("{\"%s\":[{\"event_timestamp\":", AwsMetricsPostMetricsEventsRequestParameterKeyEvents))); } } diff --git a/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp b/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp index 9fcebec524..154e88f90e 100644 --- a/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp +++ b/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp @@ -430,14 +430,14 @@ namespace AWSMetrics ReplaceLocalFileIOWithMockIO(); } - TEST_F(MetricsManagerTest, OnResponseReceived_WithResponseRecords_RetryFailedMetrics) + TEST_F(MetricsManagerTest, OnResponseReceived_WithResponseEntries_RetryFailedMetrics) { // Reset the config file to change the max queue size setting. ResetClientConfig(false, (double)TestMetricsEventSizeInBytes * (MaxNumMetricsEvents + 1) / MbToBytes, DefaultFlushPeriodInSeconds, 1); MetricsQueue metricsEvents; - ServiceAPI::MetricsEventSuccessResponsePropertyEvents responseRecords; + ServiceAPI::PostMetricsEventsResponseEntries responseEntries; for (int index = 0; index < MaxNumMetricsEvents; ++index) { MetricsEvent newEvent; @@ -445,19 +445,19 @@ namespace AWSMetrics metricsEvents.AddMetrics(newEvent); - ServiceAPI::MetricsEventSuccessResponseRecord responseRecord; + ServiceAPI::PostMetricsEventsResponseEntry responseEntry; if (index % 2 == 0) { - responseRecord.errorCode = "Error"; + responseEntry.m_errorCode = "Error"; } else { - responseRecord.result = "Ok"; + responseEntry.m_result = "Ok"; } - responseRecords.emplace_back(responseRecord); + responseEntries.emplace_back(responseEntry); } - m_metricsManager->OnResponseReceived(metricsEvents, responseRecords); + m_metricsManager->OnResponseReceived(metricsEvents, responseEntries); const GlobalStatistics& stats = m_metricsManager->GetGlobalStatistics(); EXPECT_EQ(stats.m_numEvents, MaxNumMetricsEvents); @@ -471,7 +471,7 @@ namespace AWSMetrics ASSERT_EQ(m_metricsManager->GetNumBufferedMetrics(), MaxNumMetricsEvents / 2); } - TEST_F(MetricsManagerTest, OnResponseReceived_NoResponseRecords_RetryAllMetrics) + TEST_F(MetricsManagerTest, OnResponseReceived_NoResponseEntries_RetryAllMetrics) { // Reset the config file to change the max queue size setting. ResetClientConfig(false, (double)TestMetricsEventSizeInBytes * (MaxNumMetricsEvents + 1) / MbToBytes, diff --git a/Gems/AWSMetrics/cdk/api_spec.json b/Gems/AWSMetrics/cdk/api_spec.json index 74a19ba460..0daf629516 100644 --- a/Gems/AWSMetrics/cdk/api_spec.json +++ b/Gems/AWSMetrics/cdk/api_spec.json @@ -3,7 +3,7 @@ "info": { "title": "AWSMetricsServiceApi", "description": "Service API for the data analytics pipeline defined by the AWS Metrics Gem", - "version": "1.0.0" + "version": "1.0.1" }, "x-amazon-apigateway-request-validators": { "all": { @@ -68,7 +68,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MetricsEventSuccessResponse" + "$ref": "#/components/schemas/PostMetricsEventsResponse" } } } @@ -78,7 +78,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/PostMetricsEventsError" } } } @@ -88,17 +88,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/PostMetricsEventsError" } } } }, "500": { - "description": "Internal Server Error", + "description": "Internal Server PostMetricsEventsError", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/PostMetricsEventsError" } } } @@ -109,7 +109,7 @@ }, "components": { "schemas": { - "Error": { + "PostMetricsEventsError": { "type": "object", "properties": { "message": { @@ -184,18 +184,18 @@ } } }, - "MetricsEventSuccessResponse": { + "PostMetricsEventsResponse": { "title": "Metrics Event Success Response Schema", "type": "object", "properties": { "failed_record_count": { "type": "number", - "description": "Number of events that failed to be saved to metrics events stream" + "description": "Number of events that failed to be sent to the backend" }, "events": { "type": "array", "items": { - "$ref": "#/components/schemas/MetricsEventSuccessResponseRecord" + "$ref": "#/components/schemas/PostMetricsEventsResponseEntry" } }, "total": { @@ -204,16 +204,16 @@ } } }, - "MetricsEventSuccessResponseRecord": { + "PostMetricsEventsResponseEntry": { "type": "object", "properties": { "error_code": { "type": "string", - "description": "The error code from the metrics events stream. Value set if Result is Error" + "description": "Error code if the individual metrics event failed to be sent" }, "result": { "type": "string", - "description": "Processing result for the input record" + "description": "Result for the processed individual metrics event. Expected value: \"Error\" or \"Ok\"" } } } From 83878e63775ccb3bdad0cad49a9ae973e1d48596 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Wed, 19 Jan 2022 12:57:52 -0600 Subject: [PATCH 252/272] Change GetValues() to take in const positions. (#6987) * Change GetValues() to take in const positions. To support this, span needed some template deductions to correctly convert from non-const containers to const ones. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Removed the most problematic template deduction rules. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Remove duplicate validate_iterator methods. iterator type is a pointer, not a value, so "const iterator" and "const const_iterator" produce the same function signature. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed the span types. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../AzCore/AzCore/std/containers/span.h | 36 +++++++----------- .../AzCore/AzCore/std/containers/span.inl | 38 +++---------------- .../AzCore/AzCore/std/containers/vector.h | 20 ---------- .../Components/ConstantGradientComponent.h | 2 +- .../Components/DitherGradientComponent.h | 2 +- .../Components/ImageGradientComponent.h | 2 +- .../Components/InvertGradientComponent.h | 2 +- .../Components/LevelsGradientComponent.h | 2 +- .../Components/MixedGradientComponent.h | 2 +- .../Components/PerlinGradientComponent.h | 2 +- .../Components/PosterizeGradientComponent.h | 2 +- .../Components/RandomGradientComponent.h | 2 +- .../Components/ReferenceGradientComponent.h | 2 +- .../ShapeAreaFalloffGradientComponent.h | 2 +- .../Components/SmoothStepGradientComponent.h | 2 +- .../SurfaceAltitudeGradientComponent.h | 2 +- .../Components/SurfaceMaskGradientComponent.h | 2 +- .../SurfaceSlopeGradientComponent.h | 2 +- .../Components/ThresholdGradientComponent.h | 2 +- .../Ebuses/GradientRequestBus.h | 2 +- .../Include/GradientSignal/GradientSampler.h | 4 +- .../Components/ConstantGradientComponent.cpp | 2 +- .../Components/DitherGradientComponent.cpp | 2 +- .../Components/ImageGradientComponent.cpp | 2 +- .../Components/InvertGradientComponent.cpp | 2 +- .../Components/LevelsGradientComponent.cpp | 2 +- .../Components/MixedGradientComponent.cpp | 2 +- .../Components/PerlinGradientComponent.cpp | 2 +- .../Components/PosterizeGradientComponent.cpp | 2 +- .../Components/RandomGradientComponent.cpp | 2 +- .../Components/ReferenceGradientComponent.cpp | 2 +- .../ShapeAreaFalloffGradientComponent.cpp | 2 +- .../SmoothStepGradientComponent.cpp | 2 +- .../SurfaceAltitudeGradientComponent.cpp | 2 +- .../SurfaceMaskGradientComponent.cpp | 2 +- .../SurfaceSlopeGradientComponent.cpp | 2 +- .../Components/ThresholdGradientComponent.cpp | 2 +- 37 files changed, 55 insertions(+), 109 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.h b/Code/Framework/AzCore/AzCore/std/containers/span.h index 5bb51bf481..fbf5f56870 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/span.h +++ b/Code/Framework/AzCore/AzCore/std/containers/span.h @@ -33,23 +33,24 @@ namespace AZStd * * Since the span does not copy and store any data, it is only valid as long as the data used to create it is valid. */ - template + template class span final { public: - using value_type = Element; + using element_type = T; + using value_type = AZStd::remove_cv_t; - using pointer = value_type*; - using const_pointer = const value_type*; + using pointer = T*; + using const_pointer = const T*; - using reference = value_type&; - using const_reference = const value_type&; + using reference = T&; + using const_reference = const T&; using size_type = AZStd::size_t; using difference_type = AZStd::ptrdiff_t; - using iterator = value_type*; - using const_iterator = const value_type*; + using iterator = T*; + using const_iterator = const T*; using reverse_iterator = AZStd::reverse_iterator; using const_reverse_iterator = AZStd::reverse_iterator; @@ -65,21 +66,11 @@ namespace AZStd // create a span to just the first element instead of an entire array. constexpr span(const_pointer s) = delete; - template - constexpr span(AZStd::array& data); + template + constexpr span(Container& data); - constexpr span(AZStd::vector& data); - - template - constexpr span(AZStd::fixed_vector& data); - - template - constexpr span(const AZStd::array& data); - - constexpr span(const AZStd::vector& data); - - template - constexpr span(const AZStd::fixed_vector& data); + template + constexpr span(const Container& data); constexpr span(const span&) = default; @@ -132,6 +123,7 @@ namespace AZStd pointer m_begin; pointer m_end; }; + } // namespace AZStd #include diff --git a/Code/Framework/AzCore/AzCore/std/containers/span.inl b/Code/Framework/AzCore/AzCore/std/containers/span.inl index 01bab9a5a4..2b24a11fc3 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/span.inl +++ b/Code/Framework/AzCore/AzCore/std/containers/span.inl @@ -29,42 +29,16 @@ namespace AZStd , m_end(last) { } - template - template - inline constexpr span::span(AZStd::array& data) + template + template + inline constexpr span::span(Container& data) : m_begin(data.data()) , m_end(m_begin + data.size()) { } - template - inline constexpr span::span(AZStd::vector& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - template - template - inline constexpr span::span(AZStd::fixed_vector& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - template - template - inline constexpr span::span(const AZStd::array& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - template - inline constexpr span::span(const AZStd::vector& data) - : m_begin(data.data()) - , m_end(m_begin + data.size()) - { } - - template - template - inline constexpr span::span(const AZStd::fixed_vector& data) + template + template + inline constexpr span::span(const Container& data) : m_begin(data.data()) , m_end(m_begin + data.size()) { } diff --git a/Code/Framework/AzCore/AzCore/std/containers/vector.h b/Code/Framework/AzCore/AzCore/std/containers/vector.h index 255e1c4de4..cd25450777 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/vector.h +++ b/Code/Framework/AzCore/AzCore/std/containers/vector.h @@ -954,25 +954,6 @@ namespace AZStd return true; } /// Validates an iter iterator. Returns a combination of \ref iterator_status_flag. - AZ_FORCE_INLINE int validate_iterator(const iterator& iter) const - { -#ifdef AZSTD_HAS_CHECKED_ITERATORS - AZ_Assert(iter.m_container == this, "Iterator doesn't belong to this container"); - pointer iterPtr = iter.m_iter; -#else - pointer iterPtr = iter; -#endif - if (iterPtr < m_start || iterPtr > m_last) - { - return isf_none; - } - else if (iterPtr == m_last) - { - return isf_valid; - } - - return isf_valid | isf_can_dereference; - } AZ_FORCE_INLINE int validate_iterator(const const_iterator& iter) const { #ifdef AZSTD_HAS_CHECKED_ITERATORS @@ -992,7 +973,6 @@ namespace AZStd return isf_valid | isf_can_dereference; } - AZ_FORCE_INLINE int validate_iterator(const reverse_iterator& iter) const { return validate_iterator(iter.base()); } AZ_FORCE_INLINE int validate_iterator(const const_reverse_iterator& iter) const { return validate_iterator(iter.base()); } /** diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h index 1ed06a976a..ff81206225 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ConstantGradientComponent.h @@ -62,7 +62,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h index add6de06cf..ff863115af 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/DitherGradientComponent.h @@ -77,7 +77,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h index 79d42ec478..044e9d91b1 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ImageGradientComponent.h @@ -69,7 +69,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; // AZ::Data::AssetBus overrides... void OnAssetReady(AZ::Data::Asset asset) override; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h index a370286b0b..e4c1faa5d0 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/InvertGradientComponent.h @@ -64,7 +64,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h index 093f84ef3a..eee777045f 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/LevelsGradientComponent.h @@ -69,7 +69,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h index 658118fca4..27e7d238a7 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/MixedGradientComponent.h @@ -99,7 +99,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h index 19f3fe7294..d1f35220ed 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PerlinGradientComponent.h @@ -70,7 +70,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; private: PerlinGradientConfig m_configuration; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h index bff49ac619..55ea37868b 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/PosterizeGradientComponent.h @@ -73,7 +73,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h index 328fed5118..ffd532e024 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/RandomGradientComponent.h @@ -61,7 +61,7 @@ namespace GradientSignal // GradientRequestBus overrides... float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; private: RandomGradientConfig m_configuration; diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h index 17c40865b3..82d2de1725 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ReferenceGradientComponent.h @@ -64,7 +64,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h index 27b2da58a3..4169f31a89 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h @@ -69,7 +69,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h index 03f629ab1e..282ad65a0c 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SmoothStepGradientComponent.h @@ -71,7 +71,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h index eb76fac292..6843be8a0e 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h @@ -90,7 +90,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h index 3eafb8c115..2580da10a0 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h @@ -70,7 +70,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h index b464b6fb0f..bdfbcd2b7f 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h @@ -92,7 +92,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h index 96bc235ea8..06369cbe0a 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/ThresholdGradientComponent.h @@ -65,7 +65,7 @@ namespace GradientSignal ////////////////////////////////////////////////////////////////////////// // GradientRequestBus float GetValue(const GradientSampleParams& sampleParams) const override; - void GetValues(AZStd::span positions, AZStd::span outValues) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const override; protected: diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h index 45b5a173a3..a2e5912f82 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Ebuses/GradientRequestBus.h @@ -56,7 +56,7 @@ namespace GradientSignal * \param positions The input list of positions to query. * \param outValues The output list of values. This list is expected to be the same size as the positions list. */ - virtual void GetValues(AZStd::span positions, AZStd::span outValues) const + virtual void GetValues(AZStd::span positions, AZStd::span outValues) const { // Reference implementation of GetValues for any gradients that don't have their own optimized implementations. // This is 10%-60% faster than calling GetValue via EBus many times due to the per-call EBus overhead. diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h index bf5c8d1ea0..113693e928 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/GradientSampler.h @@ -33,7 +33,7 @@ namespace GradientSignal static void Reflect(AZ::ReflectContext* context); inline float GetValue(const GradientSampleParams& sampleParams) const; - inline void GetValues(AZStd::span positions, AZStd::span outValues) const; + inline void GetValues(AZStd::span positions, AZStd::span outValues) const; bool IsEntityInHierarchy(const AZ::EntityId& entityId) const; @@ -147,7 +147,7 @@ namespace GradientSignal return output * m_opacity; } - inline void GradientSampler::GetValues(AZStd::span positions, AZStd::span outValues) const + inline void GradientSampler::GetValues(AZStd::span positions, AZStd::span outValues) const { auto ClearOutputValues = [](AZStd::span outValues) { diff --git a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp index ac81f616c6..bf94429a63 100644 --- a/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ConstantGradientComponent.cpp @@ -135,7 +135,7 @@ namespace GradientSignal } void ConstantGradientComponent::GetValues( - [[maybe_unused]] AZStd::span positions, AZStd::span outValues) const + [[maybe_unused]] AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp index 1b320afeb9..eaed069292 100644 --- a/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/DitherGradientComponent.cpp @@ -264,7 +264,7 @@ namespace GradientSignal return GetDitherValue(scaledCoordinate, value); } - void DitherGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void DitherGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp index d948f6269e..3639d5c6df 100644 --- a/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ImageGradientComponent.cpp @@ -219,7 +219,7 @@ namespace GradientSignal return 0.0f; } - void ImageGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void ImageGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp index aef5cc7a52..c9d8451104 100644 --- a/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/InvertGradientComponent.cpp @@ -137,7 +137,7 @@ namespace GradientSignal return output; } - void InvertGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void InvertGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp index 25f6a34614..85797ef4fe 100644 --- a/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/LevelsGradientComponent.cpp @@ -185,7 +185,7 @@ namespace GradientSignal return output; } - void LevelsGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void LevelsGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp index 23bdd379fe..d3cc1a5f24 100644 --- a/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/MixedGradientComponent.cpp @@ -284,7 +284,7 @@ namespace GradientSignal return AZ::GetClamp(result, 0.0f, 1.0f); } - void MixedGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void MixedGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp index e3dfaf2161..17d389559b 100644 --- a/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/PerlinGradientComponent.cpp @@ -203,7 +203,7 @@ namespace GradientSignal return 0.0f; } - void PerlinGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void PerlinGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp index 4616e080f1..b46c9891ed 100644 --- a/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/PosterizeGradientComponent.cpp @@ -155,7 +155,7 @@ namespace GradientSignal return PosterizeValue(input, bands, m_configuration.m_mode); } - void PosterizeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void PosterizeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp index 0f4ece38a1..245801e3b8 100644 --- a/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/RandomGradientComponent.cpp @@ -183,7 +183,7 @@ namespace GradientSignal return 0.0f; } - void RandomGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void RandomGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp index e135401ff5..a3d67e6f8a 100644 --- a/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ReferenceGradientComponent.cpp @@ -134,7 +134,7 @@ namespace GradientSignal return m_configuration.m_gradientSampler.GetValue(sampleParams); } - void ReferenceGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void ReferenceGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp index 77b7f1a428..62b4834f47 100644 --- a/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ShapeAreaFalloffGradientComponent.cpp @@ -168,7 +168,7 @@ namespace GradientSignal return (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / m_configuration.m_falloffWidth), 0.0f); } - void ShapeAreaFalloffGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void ShapeAreaFalloffGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp index 683f0a37fa..9d1a601fe8 100644 --- a/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SmoothStepGradientComponent.cpp @@ -172,7 +172,7 @@ namespace GradientSignal return m_configuration.m_smoothStep.GetSmoothedValue(value); } - void SmoothStepGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void SmoothStepGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp index ee6c272e40..1670483131 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp @@ -211,7 +211,7 @@ namespace GradientSignal return CalculateAltitudeRatio(points, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); } - void SurfaceAltitudeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void SurfaceAltitudeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp index f697050f56..ea72971818 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceMaskGradientComponent.cpp @@ -175,7 +175,7 @@ namespace GradientSignal return result; } - void SurfaceMaskGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void SurfaceMaskGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp index 50105a862f..e557785509 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceSlopeGradientComponent.cpp @@ -215,7 +215,7 @@ namespace GradientSignal return GetSlopeRatio(points, angleMin, angleMax); } - void SurfaceSlopeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void SurfaceSlopeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { diff --git a/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp index 5df579576d..25e956be38 100644 --- a/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/ThresholdGradientComponent.cpp @@ -141,7 +141,7 @@ namespace GradientSignal return (m_configuration.m_gradientSampler.GetValue(sampleParams) <= m_configuration.m_threshold) ? 0.0f : 1.0f; } - void ThresholdGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + void ThresholdGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const { if (positions.size() != outValues.size()) { From cfd721bce16de707574219fd46fc7456d0d21ca4 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 19 Jan 2022 11:52:57 -0800 Subject: [PATCH 253/272] A bit of Generic DOM tidying/fixup (#6914) * A bit of Generic DOM tidying/fixup - Refactor out a test fixture for all DOM tests / benchmarks - Optimize `GetType` implementation to not use `AZStd::variant::visit` (benchmark included to A/B the implementations) - Tag a few more mutating Value functions with "Mutable" to avoid astonishing copy-on-writes Benchmark results for GetType implementation: ``` DomValueBenchmark/AzDomValueGetType_UsingVariantIndex 18.2 ns 18.0 ns 40727273 items_per_second=443.667M/s DomValueBenchmark/AzDomValueGetType_UsingVariantVisit 32.2 ns 32.2 ns 21333333 items_per_second=248.242M/s ``` Signed-off-by: Nicholas Van Sickle --- Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp | 8 +- Code/Framework/AzCore/AzCore/DOM/DomValue.cpp | 105 +++----- Code/Framework/AzCore/AzCore/DOM/DomValue.h | 16 +- .../AzCore/Tests/DOM/DomFixtures.cpp | 189 ++++++++++++++ Code/Framework/AzCore/Tests/DOM/DomFixtures.h | 66 +++++ .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 146 ++--------- .../AzCore/Tests/DOM/DomJsonTests.cpp | 9 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 243 +++++++++--------- .../AzCore/Tests/DOM/DomValueTests.cpp | 14 +- .../AzCore/Tests/azcoretests_files.cmake | 2 + 10 files changed, 453 insertions(+), 345 deletions(-) create mode 100644 Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp create mode 100644 Code/Framework/AzCore/Tests/DOM/DomFixtures.h diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp index c604373296..bc5c2b28cf 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp @@ -77,8 +77,8 @@ namespace AZ::Dom::Utils for (size_t i = 0; i < ourValues.size(); ++i) { const Object::EntryType& lhsChild = ourValues[i]; - const Object::EntryType& rhsChild = theirValues[i]; - if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + auto rhsIt = rhs.FindMember(lhsChild.first); + if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second)) { return false; } @@ -144,8 +144,8 @@ namespace AZ::Dom::Utils for (size_t i = 0; i < ourProperties.size(); ++i) { const Object::EntryType& lhsChild = ourProperties[i]; - const Object::EntryType& rhsChild = theirProperties[i]; - if (lhsChild.first != rhsChild.first || !DeepCompareIsEqual(lhsChild.second, rhsChild.second)) + auto rhsIt = rhs.FindMember(lhsChild.first); + if (rhsIt == rhs.MemberEnd() || !DeepCompareIsEqual(lhsChild.second, rhsIt->second)) { return false; } diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp index 6d944c9f45..10c8e33715 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.cpp @@ -283,64 +283,33 @@ namespace AZ::Dom Type Dom::Value::GetType() const { - return AZStd::visit( - [](auto&& value) -> Type - { - using CurrentType = AZStd::decay_t; - if constexpr (AZStd::is_same_v) - { - return Type::Null; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Int64; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Uint64; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Double; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Bool; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::String; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Object; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Array; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Node; - } - else if constexpr (AZStd::is_same_v) - { - return Type::Opaque; - } - else - { - AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); - } - }, - m_value); + switch (m_value.index()) + { + case GetTypeIndex(): + return Type::Null; + case GetTypeIndex(): + return Type::Int64; + case GetTypeIndex(): + return Type::Uint64; + case GetTypeIndex(): + return Type::Double; + case GetTypeIndex(): + return Type::Bool; + case GetTypeIndex(): + case GetTypeIndex(): + case GetTypeIndex(): + return Type::String; + case GetTypeIndex(): + return Type::Object; + case GetTypeIndex(): + return Type::Array; + case GetTypeIndex(): + return Type::Node; + case GetTypeIndex>(): + return Type::Opaque; + } + AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + return Type::Null; } bool Value::IsNull() const @@ -594,12 +563,12 @@ namespace AZ::Dom return GetObjectInternal().end(); } - Object::Iterator Value::MemberBegin() + Object::Iterator Value::MutableMemberBegin() { return GetObjectInternal().begin(); } - Object::Iterator Value::MemberEnd() + Object::Iterator Value::MutableMemberEnd() { return GetObjectInternal().end(); } @@ -725,12 +694,12 @@ namespace AZ::Dom return object.end(); } - Object::Iterator Value::EraseMember(Object::ConstIterator pos) + Object::Iterator Value::EraseMember(Object::Iterator pos) { return GetObjectInternal().erase(pos); } - Object::Iterator Value::EraseMember(Object::ConstIterator first, Object::ConstIterator last) + Object::Iterator Value::EraseMember(Object::Iterator first, Object::Iterator last) { return GetObjectInternal().erase(first, last); } @@ -811,12 +780,12 @@ namespace AZ::Dom return GetArrayInternal().end(); } - Array::Iterator Value::ArrayBegin() + Array::Iterator Value::MutableArrayBegin() { return GetArrayInternal().begin(); } - Array::Iterator Value::ArrayEnd() + Array::Iterator Value::MutableArrayEnd() { return GetArrayInternal().end(); } @@ -843,12 +812,12 @@ namespace AZ::Dom return *this; } - Array::Iterator Value::ArrayErase(Array::ConstIterator pos) + Array::Iterator Value::ArrayErase(Array::Iterator pos) { return GetArrayInternal().erase(pos); } - Array::Iterator Value::ArrayErase(Array::ConstIterator first, Array::ConstIterator last) + Array::Iterator Value::ArrayErase(Array::Iterator first, Array::Iterator last) { return GetArrayInternal().erase(first, last); } @@ -1113,6 +1082,10 @@ namespace AZ::Dom { result = visitor.RefCountedString(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); } + else if constexpr (AZStd::is_same_v) + { + result = visitor.String(arg, copyStrings ? Lifetime::Temporary : Lifetime::Persistent); + } else if constexpr (AZStd::is_same_v) { result = visitor.StartObject(); diff --git a/Code/Framework/AzCore/AzCore/DOM/DomValue.h b/Code/Framework/AzCore/AzCore/DOM/DomValue.h index ecf8326525..d1d3c1745d 100644 --- a/Code/Framework/AzCore/AzCore/DOM/DomValue.h +++ b/Code/Framework/AzCore/AzCore/DOM/DomValue.h @@ -268,8 +268,8 @@ namespace AZ::Dom Object::ConstIterator MemberBegin() const; Object::ConstIterator MemberEnd() const; - Object::Iterator MemberBegin(); - Object::Iterator MemberEnd(); + Object::Iterator MutableMemberBegin(); + Object::Iterator MutableMemberEnd(); Object::Iterator FindMutableMember(KeyType name); Object::Iterator FindMutableMember(AZStd::string_view name); @@ -289,8 +289,8 @@ namespace AZ::Dom void RemoveMember(KeyType name); void RemoveMember(AZStd::string_view name); Object::Iterator RemoveMember(Object::Iterator pos); - Object::Iterator EraseMember(Object::ConstIterator pos); - Object::Iterator EraseMember(Object::ConstIterator first, Object::ConstIterator last); + Object::Iterator EraseMember(Object::Iterator pos); + Object::Iterator EraseMember(Object::Iterator first, Object::Iterator last); Object::Iterator EraseMember(KeyType name); Object::Iterator EraseMember(AZStd::string_view name); @@ -313,15 +313,15 @@ namespace AZ::Dom Array::ConstIterator ArrayBegin() const; Array::ConstIterator ArrayEnd() const; - Array::Iterator ArrayBegin(); - Array::Iterator ArrayEnd(); + Array::Iterator MutableArrayBegin(); + Array::Iterator MutableArrayEnd(); Value& ArrayReserve(size_t newCapacity); Value& ArrayPushBack(Value value); Value& ArrayPopBack(); - Array::Iterator ArrayErase(Array::ConstIterator pos); - Array::Iterator ArrayErase(Array::ConstIterator first, Array::ConstIterator last); + Array::Iterator ArrayErase(Array::Iterator pos); + Array::Iterator ArrayErase(Array::Iterator first, Array::Iterator last); Array::ContainerType& GetMutableArray(); const Array::ContainerType& GetArray() const; diff --git a/Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp b/Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp new file mode 100644 index 0000000000..236c1f6d74 --- /dev/null +++ b/Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +namespace AZ::Dom::Tests +{ + void DomTestHarness::SetUpHarness() + { + NameDictionary::Create(); + AZ::AllocatorInstance::Create(); + } + + void DomTestHarness::TearDownHarness() + { + AZ::AllocatorInstance::Destroy(); + NameDictionary::Destroy(); + } + + void DomBenchmarkFixture::SetUp(const ::benchmark::State& st) + { + UnitTest::AllocatorsBenchmarkFixture::SetUp(st); + SetUpHarness(); + } + + void DomBenchmarkFixture::SetUp(::benchmark::State& st) + { + UnitTest::AllocatorsBenchmarkFixture::SetUp(st); + SetUpHarness(); + } + + void DomBenchmarkFixture::TearDown(::benchmark::State& st) + { + TearDownHarness(); + UnitTest::AllocatorsBenchmarkFixture::TearDown(st); + } + + void DomBenchmarkFixture::TearDown(const ::benchmark::State& st) + { + TearDownHarness(); + UnitTest::AllocatorsBenchmarkFixture::TearDown(st); + } + + rapidjson::Document DomBenchmarkFixture::GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength) + { + rapidjson::Document document; + document.SetObject(); + + AZStd::string entryTemplate; + while (entryTemplate.size() < aznumeric_cast(stringTemplateLength)) + { + entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "; + } + entryTemplate.resize(stringTemplateLength); + AZStd::string buffer; + + auto createString = [&](int n) -> rapidjson::Value + { + buffer = AZStd::string::format("#%i %s", n, entryTemplate.c_str()); + return rapidjson::Value(buffer.data(), aznumeric_cast(buffer.size()), document.GetAllocator()); + }; + + auto createEntry = [&](int n) -> rapidjson::Value + { + rapidjson::Value entry(rapidjson::kObjectType); + entry.AddMember("string", createString(n), document.GetAllocator()); + entry.AddMember("int", rapidjson::Value(n), document.GetAllocator()); + entry.AddMember("double", rapidjson::Value(aznumeric_cast(n) * 0.5), document.GetAllocator()); + entry.AddMember("bool", rapidjson::Value(n % 2 == 0), document.GetAllocator()); + entry.AddMember("null", rapidjson::Value(rapidjson::kNullType), document.GetAllocator()); + return entry; + }; + + auto createArray = [&]() -> rapidjson::Value + { + rapidjson::Value array; + array.SetArray(); + for (int i = 0; i < entryCount; ++i) + { + array.PushBack(createEntry(i), document.GetAllocator()); + } + return array; + }; + + auto createObject = [&]() -> rapidjson::Value + { + rapidjson::Value object; + object.SetObject(); + for (int i = 0; i < entryCount; ++i) + { + buffer = AZStd::string::format("Key%i", i); + rapidjson::Value key; + key.SetString(buffer.data(), aznumeric_cast(buffer.length()), document.GetAllocator()); + object.AddMember(key.Move(), createArray(), document.GetAllocator()); + } + return object; + }; + + document.SetObject(); + document.AddMember("entries", createObject(), document.GetAllocator()); + + return document; + } + + AZStd::string DomBenchmarkFixture::GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) + { + rapidjson::Document document = GenerateDomJsonBenchmarkDocument(entryCount, stringTemplateLength); + + AZStd::string serializedJson; + auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson); + AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON"); + return serializedJson; + } + + Value DomBenchmarkFixture::GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) + { + Value root(Type::Object); + + AZStd::string entryTemplate; + while (entryTemplate.size() < aznumeric_cast(stringTemplateLength)) + { + entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "; + } + entryTemplate.resize(stringTemplateLength); + AZStd::string buffer; + + auto createString = [&](int n) -> Value + { + return Value(AZStd::string::format("#%i %s", n, entryTemplate.c_str()), true); + }; + + auto createEntry = [&](int n) -> Value + { + Value entry(Type::Object); + entry.AddMember("string", createString(n)); + entry.AddMember("int", Value(n)); + entry.AddMember("double", Value(aznumeric_cast(n) * 0.5)); + entry.AddMember("bool", Value(n % 2 == 0)); + entry.AddMember("null", Value(Type::Null)); + return entry; + }; + + auto createArray = [&]() -> Value + { + Value array(Type::Array); + for (int i = 0; i < entryCount; ++i) + { + array.ArrayPushBack(createEntry(i)); + } + return array; + }; + + auto createObject = [&]() -> Value + { + Value object; + object.SetObject(); + for (int i = 0; i < entryCount; ++i) + { + buffer = AZStd::string::format("Key%i", i); + object.AddMember(AZ::Name(buffer), createArray()); + } + return object; + }; + + root["entries"] = createObject(); + + return root; + } + + void DomTestFixture::SetUp() + { + UnitTest::AllocatorsFixture::SetUp(); + SetUpHarness(); + } + + void DomTestFixture::TearDown() + { + TearDownHarness(); + UnitTest::AllocatorsFixture::TearDown(); + } +} // namespace AZ::Dom::Tests diff --git a/Code/Framework/AzCore/Tests/DOM/DomFixtures.h b/Code/Framework/AzCore/Tests/DOM/DomFixtures.h new file mode 100644 index 0000000000..381eff6b98 --- /dev/null +++ b/Code/Framework/AzCore/Tests/DOM/DomFixtures.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +#define DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method) \ + BENCHMARK_REGISTER_F(BaseClass, Method)->Args({ 10, 5 })->Args({ 10, 500 })->Args({ 100, 5 })->Args({ 100, 500 }) +#define DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(BaseClass, Method) \ + DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method)->Unit(benchmark::kMillisecond); +#define DOM_REGISTER_SERIALIZATION_BENCHMARK_NS(BaseClass, Method) \ + DOM_REGISTER_SERIALIZATION_BENCHMARK(BaseClass, Method)->Unit(benchmark::kNanosecond); + +namespace AZ::Dom::Tests +{ + class DomTestHarness + { + public: + virtual ~DomTestHarness() = default; + + virtual void SetUpHarness(); + virtual void TearDownHarness(); + }; + + class DomBenchmarkFixture + : public DomTestHarness + , public UnitTest::AllocatorsBenchmarkFixture + { + public: + void SetUp(const ::benchmark::State& st) override; + void SetUp(::benchmark::State& st) override; + void TearDown(::benchmark::State& st) override; + void TearDown(const ::benchmark::State& st) override; + + rapidjson::Document GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength); + AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength); + Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength); + + template + static void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state) + { + { + T instance = AZStd::move(value); + state.PauseTiming(); + } + state.ResumeTiming(); + } + }; + + class DomTestFixture + : public DomTestHarness + , public UnitTest::AllocatorsFixture + { + public: + void SetUp() override; + void TearDown() override; + }; +} // namespace AZ::Dom::Tests diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index 8eda110e7b..f84b60af07 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -16,131 +16,14 @@ #include #include #include +#include -namespace Benchmark +namespace AZ::Dom::Benchmark { - class DomJsonBenchmark : public UnitTest::AllocatorsBenchmarkFixture + class DomJsonBenchmark : public Tests::DomBenchmarkFixture { - public: - void SetUp(const ::benchmark::State& st) override - { - UnitTest::AllocatorsBenchmarkFixture::SetUp(st); - AZ::NameDictionary::Create(); - AZ::AllocatorInstance::Create(); - } - - void SetUp(::benchmark::State& st) override - { - UnitTest::AllocatorsBenchmarkFixture::SetUp(st); - AZ::NameDictionary::Create(); - AZ::AllocatorInstance::Create(); - } - - void TearDown(::benchmark::State& st) override - { - AZ::AllocatorInstance::Destroy(); - AZ::NameDictionary::Destroy(); - UnitTest::AllocatorsBenchmarkFixture::TearDown(st); - } - - void TearDown(const ::benchmark::State& st) override - { - AZ::AllocatorInstance::Destroy(); - AZ::NameDictionary::Destroy(); - UnitTest::AllocatorsBenchmarkFixture::TearDown(st); - } - - rapidjson::Document GenerateDomJsonBenchmarkDocument(int64_t entryCount, int64_t stringTemplateLength) - { - rapidjson::Document document; - document.SetObject(); - - AZStd::string entryTemplate; - while (entryTemplate.size() < static_cast(stringTemplateLength)) - { - entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "; - } - entryTemplate.resize(stringTemplateLength); - AZStd::string buffer; - - auto createString = [&](int n) -> rapidjson::Value - { - buffer = AZStd::string::format("#%i %s", n, entryTemplate.c_str()); - return rapidjson::Value(buffer.data(), static_cast(buffer.size()), document.GetAllocator()); - }; - - auto createEntry = [&](int n) -> rapidjson::Value - { - rapidjson::Value entry(rapidjson::kObjectType); - entry.AddMember("string", createString(n), document.GetAllocator()); - entry.AddMember("int", rapidjson::Value(n), document.GetAllocator()); - entry.AddMember("double", rapidjson::Value(static_cast(n) * 0.5), document.GetAllocator()); - entry.AddMember("bool", rapidjson::Value(n % 2 == 0), document.GetAllocator()); - entry.AddMember("null", rapidjson::Value(rapidjson::kNullType), document.GetAllocator()); - return entry; - }; - - auto createArray = [&]() -> rapidjson::Value - { - rapidjson::Value array; - array.SetArray(); - for (int i = 0; i < entryCount; ++i) - { - array.PushBack(createEntry(i), document.GetAllocator()); - } - return array; - }; - - auto createObject = [&]() -> rapidjson::Value - { - rapidjson::Value object; - object.SetObject(); - for (int i = 0; i < entryCount; ++i) - { - buffer = AZStd::string::format("Key%i", i); - rapidjson::Value key; - key.SetString(buffer.data(), static_cast(buffer.length()), document.GetAllocator()); - object.AddMember(key.Move(), createArray(), document.GetAllocator()); - } - return object; - }; - - document.SetObject(); - document.AddMember("entries", createObject(), document.GetAllocator()); - - return document; - } - - AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) - { - rapidjson::Document document = GenerateDomJsonBenchmarkDocument(entryCount, stringTemplateLength); - - AZStd::string serializedJson; - auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson); - AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON"); - return serializedJson; - } - - template - void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state) - { - { - T instance = AZStd::move(value); - state.PauseTiming(); - } - state.ResumeTiming(); - } }; -// Helper macro for registering JSON benchmarks -#define BENCHMARK_REGISTER_JSON(BaseClass, Method) \ - BENCHMARK_REGISTER_F(BaseClass, Method) \ - ->Args({ 10, 5 }) \ - ->Args({ 10, 500 }) \ - ->Args({ 100, 5 }) \ - ->Args({ 100, 500 }) \ - ->Unit(benchmark::kMillisecond); - BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace)(benchmark::State& state) { AZ::Dom::JsonBackend backend; @@ -163,7 +46,7 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToRapidjsonInPlace) BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace)(benchmark::State& state) { @@ -187,7 +70,7 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToAzDomValueInPlace) BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToRapidjson)(benchmark::State& state) { @@ -207,7 +90,7 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToRapidjson) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToRapidjson) BENCHMARK_DEFINE_F(DomJsonBenchmark, AzDomDeserializeToAzDomValue)(benchmark::State& state) { @@ -227,7 +110,7 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, AzDomDeserializeToAzDomValue) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, AzDomDeserializeToAzDomValue) BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonDeserializeToRapidjson)(benchmark::State& state) { @@ -243,7 +126,7 @@ namespace Benchmark state.SetBytesProcessed(serializedPayload.size() * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeserializeToRapidjson) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonDeserializeToRapidjson) BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonMakeComplexObject)(benchmark::State& state) { @@ -254,7 +137,7 @@ namespace Benchmark state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonMakeComplexObject) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonMakeComplexObject) BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonLookupMemberByString)(benchmark::State& state) { @@ -264,7 +147,9 @@ namespace Benchmark { AZStd::string key(AZStd::string::format("key%" PRId64, i)); keys.push_back(key); - document.AddMember(rapidjson::Value(key.data(), static_cast(key.size()), document.GetAllocator()), rapidjson::Value(i), document.GetAllocator()); + document.AddMember( + rapidjson::Value(key.data(), static_cast(key.size()), document.GetAllocator()), rapidjson::Value(i), + document.GetAllocator()); } for (auto _ : state) @@ -293,7 +178,7 @@ namespace Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonDeepCopy) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonDeepCopy) BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonCopyAndMutate)(benchmark::State& state) { @@ -309,9 +194,8 @@ namespace Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_JSON(DomJsonBenchmark, RapidjsonCopyAndMutate) + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomJsonBenchmark, RapidjsonCopyAndMutate) -#undef BENCHMARK_REGISTER_JSON -} // namespace Benchmark +} // namespace AZ::Dom::Benchmark #endif // defined(HAVE_BENCHMARK) diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonTests.cpp index c7af6438cf..ff9e378134 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonTests.cpp @@ -13,24 +13,23 @@ #include #include #include +#include namespace AZ::Dom::Tests { - class DomJsonTests : public UnitTest::AllocatorsFixture + class DomJsonTests : public DomTestFixture { public: void SetUp() override { - UnitTest::AllocatorsFixture::SetUp(); - NameDictionary::Create(); + DomTestFixture::SetUp(); m_document = AZStd::make_unique(); } void TearDown() override { m_document.reset(); - NameDictionary::Destroy(); - UnitTest::AllocatorsFixture::TearDown(); + DomTestFixture::TearDown(); } rapidjson::Value CreateString(const AZStd::string& text) diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 40b96e148b..69d99eb12b 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -6,111 +6,134 @@ * */ -#include #include +#include #include #include -#include +#include namespace AZ::Dom::Benchmark { - class DomValueBenchmark : public UnitTest::AllocatorsBenchmarkFixture + class DomValueBenchmark : public Tests::DomBenchmarkFixture { - public: - void SetUp(const ::benchmark::State& st) override - { - UnitTest::AllocatorsBenchmarkFixture::SetUp(st); - AZ::NameDictionary::Create(); - AZ::AllocatorInstance::Create(); - } - - void SetUp(::benchmark::State& st) override - { - UnitTest::AllocatorsBenchmarkFixture::SetUp(st); - AZ::NameDictionary::Create(); - AZ::AllocatorInstance::Create(); - } - - void TearDown(::benchmark::State& st) override - { - AZ::AllocatorInstance::Destroy(); - AZ::NameDictionary::Destroy(); - UnitTest::AllocatorsBenchmarkFixture::TearDown(st); - } - - void TearDown(const ::benchmark::State& st) override - { - AZ::AllocatorInstance::Destroy(); - AZ::NameDictionary::Destroy(); - UnitTest::AllocatorsBenchmarkFixture::TearDown(st); - } - - Value GenerateDomBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength) - { - Value root(Type::Object); - - AZStd::string entryTemplate; - while (entryTemplate.size() < static_cast(stringTemplateLength)) - { - entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor "; - } - entryTemplate.resize(stringTemplateLength); - AZStd::string buffer; - - auto createString = [&](int n) -> Value - { - return Value(AZStd::string::format("#%i %s", n, entryTemplate.c_str()), true); - }; - - auto createEntry = [&](int n) -> Value - { - Value entry(Type::Object); - entry.AddMember("string", createString(n)); - entry.AddMember("int", Value(n)); - entry.AddMember("double", Value(static_cast(n) * 0.5)); - entry.AddMember("bool", Value(n % 2 == 0)); - entry.AddMember("null", Value(Type::Null)); - return entry; - }; - - auto createArray = [&]() -> Value - { - Value array(Type::Array); - for (int i = 0; i < entryCount; ++i) - { - array.ArrayPushBack(createEntry(i)); - } - return array; - }; - - auto createObject = [&]() -> Value - { - Value object; - object.SetObject(); - for (int i = 0; i < entryCount; ++i) - { - buffer = AZStd::string::format("Key%i", i); - object.AddMember(AZ::Name(buffer), createArray()); - } - return object; - }; - - root["entries"] = createObject(); - - return root; - } - - template - void TakeAndDiscardWithoutTimingDtor(T&& value, benchmark::State& state) - { - { - T instance = AZStd::move(value); - state.PauseTiming(); - } - state.ResumeTiming(); - } }; + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueGetType_UsingVariantIndex)(benchmark::State& state) + { + Value intValue(5); + Value boolValue(true); + Value objValue(Type::Object); + Value nodeValue(Type::Node); + Value arrValue(Type::Array); + Value uintValue(5u); + Value doubleValue(4.0); + Value stringValue("foo", true); + + for (auto _ : state) + { + (intValue.GetType()); + (boolValue.GetType()); + (objValue.GetType()); + (nodeValue.GetType()); + (arrValue.GetType()); + (uintValue.GetType()); + (doubleValue.GetType()); + (stringValue.GetType()); + } + + state.SetItemsProcessed(8 * state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueGetType_UsingVariantIndex); + + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueGetType_UsingVariantVisit)(benchmark::State& state) + { + Value intValue(5); + Value boolValue(true); + Value objValue(Type::Object); + Value nodeValue(Type::Node); + Value arrValue(Type::Array); + Value uintValue(5u); + Value doubleValue(4.0); + Value stringValue("foo", true); + + auto getTypeViaVisit = [](const Value& value) + { + return AZStd::visit( + [](auto&& value) constexpr -> Type + { + using CurrentType = AZStd::decay_t; + if constexpr (AZStd::is_same_v) + { + return Type::Null; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Int64; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Uint64; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Double; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Bool; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::String; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Object; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Array; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Node; + } + else if constexpr (AZStd::is_same_v) + { + return Type::Opaque; + } + else + { + AZ_Assert(false, "AZ::Dom::Value::GetType: m_value has an unexpected type"); + } + }, + value.GetInternalValue()); + }; + + for (auto _ : state) + { + (getTypeViaVisit(intValue)); + (getTypeViaVisit(boolValue)); + (getTypeViaVisit(objValue)); + (getTypeViaVisit(nodeValue)); + (getTypeViaVisit(arrValue)); + (getTypeViaVisit(uintValue)); + (getTypeViaVisit(doubleValue)); + (getTypeViaVisit(stringValue)); + } + + state.SetItemsProcessed(8 * state.iterations()); + } + BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueGetType_UsingVariantVisit); + BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueMakeComplexObject)(benchmark::State& state) { for (auto _ : state) @@ -120,12 +143,7 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.range(0) * state.range(0) * state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueMakeComplexObject) - ->Args({ 10, 5 }) - ->Args({ 10, 500 }) - ->Args({ 100, 5 }) - ->Args({ 100, 500 }) - ->Unit(benchmark::kMillisecond); + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueMakeComplexObject) BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueShallowCopy)(benchmark::State& state) { @@ -139,12 +157,7 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueShallowCopy) - ->Args({ 10, 5 }) - ->Args({ 10, 500 }) - ->Args({ 100, 5 }) - ->Args({ 100, 500 }) - ->Unit(benchmark::kNanosecond); + DOM_REGISTER_SERIALIZATION_BENCHMARK_NS(DomValueBenchmark, AzDomValueShallowCopy) BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueCopyAndMutate)(benchmark::State& state) { @@ -159,12 +172,7 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueCopyAndMutate) - ->Args({ 10, 5 }) - ->Args({ 10, 500 }) - ->Args({ 100, 5 }) - ->Args({ 100, 500 }) - ->Unit(benchmark::kNanosecond); + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueCopyAndMutate) BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueDeepCopy)(benchmark::State& state) { @@ -178,12 +186,7 @@ namespace AZ::Dom::Benchmark state.SetItemsProcessed(state.iterations()); } - BENCHMARK_REGISTER_F(DomValueBenchmark, AzDomValueDeepCopy) - ->Args({ 10, 5 }) - ->Args({ 10, 500 }) - ->Args({ 100, 5 }) - ->Args({ 100, 500 }) - ->Unit(benchmark::kMillisecond); + DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomValueBenchmark, AzDomValueDeepCopy) BENCHMARK_DEFINE_F(DomValueBenchmark, LookupMemberByName)(benchmark::State& state) { diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp index 10e9f29a44..f39ca4818a 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueTests.cpp @@ -15,26 +15,18 @@ #include #include #include +#include namespace AZ::Dom::Tests { - class DomValueTests : public UnitTest::AllocatorsFixture + class DomValueTests : public DomTestFixture { public: - void SetUp() override - { - UnitTest::AllocatorsFixture::SetUp(); - NameDictionary::Create(); - AZ::AllocatorInstance::Create(); - } - void TearDown() override { m_value = Value(); - AZ::AllocatorInstance::Destroy(); - NameDictionary::Destroy(); - UnitTest::AllocatorsFixture::TearDown(); + DomTestFixture::TearDown(); } void PerformValueChecks() diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 7be3afb4a9..aee6828b76 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -215,6 +215,8 @@ set(FILES AZStd/Variant.cpp AZStd/VariantSerialization.cpp AZStd/VectorAndArray.cpp + DOM/DomFixtures.cpp + DOM/DomFixtures.h DOM/DomJsonTests.cpp DOM/DomJsonBenchmarks.cpp DOM/DomValueTests.cpp From 5cac67bfaddd9fc568e35ad2c1f8a75a03f0b765 Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Wed, 19 Jan 2022 12:11:39 -0800 Subject: [PATCH 254/272] Silence aws logging for unit test and have a new AWSNativeSDK as entry point for test env (#6865) * Silence aws logging for unit test * Create a new AWSNativeSDK entry point for test environment only * Update naming for target and file --- Code/Tools/AWSNativeSDKInit/CMakeLists.txt | 18 ++++++++ .../aws_native_sdk_test_files.cmake | 12 +++++ .../source/AWSNativeSDKInit.cpp | 1 - .../tests/libs/AWSNativeSDKTestManager.cpp | 45 +++++++++++++++++++ .../tests/libs/AWSNativeSDKTestManager.h | 39 ++++++++++++++++ Gems/AWSClientAuth/Code/CMakeLists.txt | 3 +- .../Code/Tests/AWSClientAuthGemMock.h | 7 ++- Gems/AWSCore/Code/CMakeLists.txt | 4 +- .../Code/Tests/AWSCoreSystemComponentTest.cpp | 4 +- .../Code/Tests/TestFramework/AWSCoreFixture.h | 6 +-- .../Code/AWSGameLiftClient/CMakeLists.txt | 2 +- .../Tests/AWSGameLiftClientFixture.h | 7 +-- 12 files changed, 130 insertions(+), 18 deletions(-) create mode 100644 Code/Tools/AWSNativeSDKInit/aws_native_sdk_test_files.cmake create mode 100644 Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.cpp create mode 100644 Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.h diff --git a/Code/Tools/AWSNativeSDKInit/CMakeLists.txt b/Code/Tools/AWSNativeSDKInit/CMakeLists.txt index 04f61eb924..de3e0008c2 100644 --- a/Code/Tools/AWSNativeSDKInit/CMakeLists.txt +++ b/Code/Tools/AWSNativeSDKInit/CMakeLists.txt @@ -25,6 +25,24 @@ ly_add_target( AZ::AzCore ) +ly_add_target( + NAME AWSNativeSDKTestLibs STATIC + NAMESPACE AZ + FILES_CMAKE + aws_native_sdk_test_files.cmake + INCLUDE_DIRECTORIES + PUBLIC + include + tests/libs + PRIVATE + source + BUILD_DEPENDENCIES + PRIVATE + 3rdParty::AWSNativeSDK::Core + AZ::AzCore + AZ::AzTest +) + ################################################################################ # Tests ################################################################################ diff --git a/Code/Tools/AWSNativeSDKInit/aws_native_sdk_test_files.cmake b/Code/Tools/AWSNativeSDKInit/aws_native_sdk_test_files.cmake new file mode 100644 index 0000000000..17f4b3f6e9 --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/aws_native_sdk_test_files.cmake @@ -0,0 +1,12 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + tests/libs/AWSNativeSDKTestManager.cpp + tests/libs/AWSNativeSDKTestManager.h +) diff --git a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp index ca63859945..ca02b4f223 100644 --- a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp +++ b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp @@ -89,5 +89,4 @@ namespace AWSNativeSDKInit Platform::CustomizeShutdown(); #endif // #if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK) } - } diff --git a/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.cpp b/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.cpp new file mode 100644 index 0000000000..29300857c1 --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + + +#include + +#include +#include + +#include +#include +#include + +namespace AWSNativeSDKTestLibs +{ + AZ::EnvironmentVariable AWSNativeSDKTestManager::s_sdkManager = nullptr; + + AWSNativeSDKTestManager::AWSNativeSDKTestManager() + { + AZ::Test::SetEnv("AWS_DEFAULT_REGION", "us-east-1", 1); + m_awsSDKOptions.memoryManagementOptions.memoryManager = &m_memoryManager; + Aws::InitAPI(m_awsSDKOptions); + } + + AWSNativeSDKTestManager::~AWSNativeSDKTestManager() + { + Aws::ShutdownAPI(m_awsSDKOptions); + AZ::Test::UnsetEnv("AWS_DEFAULT_REGION"); + } + + void AWSNativeSDKTestManager::Init() + { + s_sdkManager = AZ::Environment::CreateVariable(AWSNativeSDKTestManager::SdkManagerTag); + } + + void AWSNativeSDKTestManager::Shutdown() + { + s_sdkManager = nullptr; + } +} diff --git a/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.h b/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.h new file mode 100644 index 0000000000..48e97bb6f8 --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/tests/libs/AWSNativeSDKTestManager.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace AWSNativeSDKTestLibs +{ + // Entry point for AWSNativeSDK's initialization and shutdown for test environment + // Use an AZ::Environment variable to enforce only one init and shutdown + class AWSNativeSDKTestManager + { + public: + static constexpr const char SdkManagerTag[] = "TestAWSSDKManager"; + + AWSNativeSDKTestManager(); + ~AWSNativeSDKTestManager(); + + static void Init(); + static void Shutdown(); + + private: + static AZ::EnvironmentVariable s_sdkManager; + + AWSNativeSDKInit::MemoryManager m_memoryManager; + Aws::SDKOptions m_awsSDKOptions; + }; +} diff --git a/Gems/AWSClientAuth/Code/CMakeLists.txt b/Gems/AWSClientAuth/Code/CMakeLists.txt index ac9d221f07..e34dd702dd 100644 --- a/Gems/AWSClientAuth/Code/CMakeLists.txt +++ b/Gems/AWSClientAuth/Code/CMakeLists.txt @@ -106,13 +106,12 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) 3rdParty::AWSNativeSDK::AWSClientAuth AZ::AzCore AZ::AzFramework - AZ::AWSNativeSDKInit + AZ::AWSNativeSDKTestLibs Gem::AWSClientAuth.Static Gem::AWSCore Gem::HttpRequestor RUNTIME_DEPENDENCIES Gem::AWSCore - AZ::AWSNativeSDKInit Gem::HttpRequestor ) ly_add_googletest( diff --git a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h index 19314035c4..3bfde09492 100644 --- a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h +++ b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -542,7 +542,7 @@ namespace AWSClientAuthUnitTest m_jobContext.reset(aznew AZ::JobContext(*m_jobManager, *m_jobCancelGroup)); AZ::JobContext::SetGlobalContext(m_jobContext.get()); - AWSNativeSDKInit::InitializationManager::InitAwsApi(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Init(); m_cognitoIdentityProviderClientMock = std::make_shared(); m_cognitoIdentityClientMock = std::make_shared(); } @@ -557,8 +557,7 @@ namespace AWSClientAuthUnitTest m_cognitoIdentityProviderClientMock.reset(); m_cognitoIdentityClientMock.reset(); - AWSNativeSDKInit::InitializationManager::Shutdown(); - + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Shutdown(); AZ::AllocatorInstance::Destroy(); diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 3911aefce6..bb836b57bd 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -163,7 +163,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTest AZ::AzFramework - AZ::AWSNativeSDKInit + AZ::AWSNativeSDKTestLibs Gem::AWSCore.Static ) @@ -202,7 +202,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) 3rdParty::Qt::Gui 3rdParty::Qt::Widgets AZ::AzTest - AZ::AWSNativeSDKInit + AZ::AWSNativeSDKTestLibs Gem::AWSCore.Static Gem::AWSCore.Editor.Static ) diff --git a/Gems/AWSCore/Code/Tests/AWSCoreSystemComponentTest.cpp b/Gems/AWSCore/Code/Tests/AWSCoreSystemComponentTest.cpp index b66b43f735..74a1588895 100644 --- a/Gems/AWSCore/Code/Tests/AWSCoreSystemComponentTest.cpp +++ b/Gems/AWSCore/Code/Tests/AWSCoreSystemComponentTest.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -105,7 +105,7 @@ public: TEST_F(AWSCoreSystemComponentTest, ComponentActivateTest) { // Shutdown SDK which is init in fixture setup step - AWSNativeSDKInit::InitializationManager::Shutdown(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Shutdown(); EXPECT_FALSE(m_coreSystemsComponent->IsAWSApiInitialized()); diff --git a/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h b/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h index 6ea5593d0e..4daf5bb679 100644 --- a/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h +++ b/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h @@ -17,7 +17,7 @@ #include #include -#include +#include namespace AWSCoreTestingUtils { @@ -138,7 +138,7 @@ public: m_app = AZStd::make_unique(); } - AWSNativeSDKInit::InitializationManager::InitAwsApi(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Init(); } void TearDown() override @@ -148,7 +148,7 @@ public: void TearDownFixture(bool mockSettingsRegistry = true) { - AWSNativeSDKInit::InitializationManager::Shutdown(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Shutdown(); if (mockSettingsRegistry) { diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/CMakeLists.txt b/Gems/AWSGameLift/Code/AWSGameLiftClient/CMakeLists.txt index ab85e89f75..bdc831c439 100644 --- a/Gems/AWSGameLift/Code/AWSGameLiftClient/CMakeLists.txt +++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/CMakeLists.txt @@ -90,7 +90,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Gem::AWSCore Gem::AWSGameLift.Client.Static 3rdParty::AWSNativeSDK::GameLiftClient - AZ::AWSNativeSDKInit + AZ::AWSNativeSDKTestLibs ) # Add AWSGameLift.Client.Tests to googletest ly_add_googletest( diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Tests/AWSGameLiftClientFixture.h b/Gems/AWSGameLift/Code/AWSGameLiftClient/Tests/AWSGameLiftClientFixture.h index 88ddb92531..b1c689baec 100644 --- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Tests/AWSGameLiftClientFixture.h +++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Tests/AWSGameLiftClientFixture.h @@ -8,12 +8,13 @@ #pragma once -#include +#include #include #include #include #include #include +#include class AWSGameLiftClientFixture : public UnitTest::ScopedAllocatorSetupFixture @@ -38,12 +39,12 @@ public: m_jobContext.reset(aznew AZ::JobContext(*m_jobManager, *m_jobCancelGroup)); AZ::JobContext::SetGlobalContext(m_jobContext.get()); - AWSNativeSDKInit::InitializationManager::InitAwsApi(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Init(); } void TearDown() override { - AWSNativeSDKInit::InitializationManager::Shutdown(); + AWSNativeSDKTestLibs::AWSNativeSDKTestManager::Shutdown(); AZ::JobContext::SetGlobalContext(nullptr); m_jobContext.reset(); From b61238e50c0e7c9dc0c44e757be657a82881903a Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Wed, 19 Jan 2022 12:30:51 -0800 Subject: [PATCH 255/272] Minor fixes to whitespace and comments. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 8bf975fd82..f2a9efd896 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -136,8 +136,6 @@ namespace AZ } } - - template MaterialPropertyValue CastVectorMaterialPropertyValue(const MaterialPropertyValue& value) { @@ -252,8 +250,8 @@ namespace AZ else { // The material asset could be finalized sometime after the original JSON is loaded, and the material type might not have been available - // at that time, so the data type would not be known for each property. So each raw property's type could be based on what appeared in the JSON - // and this is the first opportunity we have to resolve that value with the actual type. For example, a float property could have been specified in + // at that time, so the data type would not be known for each property. So each raw property's type was based on what appeared in the JSON + // and here we have the first opportunity to resolve that value with the actual type. For example, a float property could have been specified in // the JSON as 7 instead of 7.0, which is valid. Similarly, a Color and a Vector3 can both be specified as "[0.0,0.0,0.0]" in the JSON file. MaterialPropertyValue finalValue = value; From d223513ffeb6aa3c88bdacecbcb3e2b3309084e7 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 19 Jan 2022 15:01:20 -0600 Subject: [PATCH 256/272] Updating query areas for instance count validation Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../ShapeIntersectionFilter_FilterStageToggle.py | 13 +++++++------ .../largeworlds/dyn_veg/TestSuite_Main_Optimized.py | 1 - 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py index 8f179f7f50..b5c00a53b7 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py @@ -68,7 +68,7 @@ def ShapeIntersectionFilter_FilterStageToggle(): # Create a new entity as a child of the vegetation area entity with Box Shape box = hydra.Entity("box") box.create_entity(position, ["Box Shape"]) - box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0)) + box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0)) # Create a new entity as a child of the vegetation area entity with Cylinder Shape. cylinder = hydra.Entity("cylinder") @@ -80,10 +80,10 @@ def ShapeIntersectionFilter_FilterStageToggle(): # On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0) Report.result(Tests.instance_count_in_box_shape, result) vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0) Report.result(Tests.instance_count_in_cylinder_shape, result) # Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier, @@ -98,12 +98,13 @@ def ShapeIntersectionFilter_FilterStageToggle(): # Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id) - # Toggle between PreProcess and PostProcess + # Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position + # offsets vegetation.get_set_test(3, "Configuration|Filter Stage", 1) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0) Report.result(Tests.preprocess_instance_count, result) vegetation.get_set_test(3, "Configuration|Filter Stage", 2) - result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0) + result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0) Report.result(Tests.postprocess_instance_count, result) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index af1c187817..5b1e504442 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -131,7 +131,6 @@ class TestAutomation_PrefabNotEnabled(EditorTestSuite): class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module - @pytest.mark.skip("https://github.com/o3de/o3de/issues/6973") class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest): from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module From 3506a3975987fe1c9af8dd0ed57e89649aa49d80 Mon Sep 17 00:00:00 2001 From: Mikhail Naumov Date: Wed, 19 Jan 2022 15:01:21 -0600 Subject: [PATCH 257/272] Merge branch 'mnaumov/FixingEOOrdering' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/FixingEOOrdering_signofffix Signed-off-by: Mikhail Naumov --- .../Entity/EditorEntityContextBus.h | 7 ++----- .../Entity/EditorEntityHelpers.cpp | 4 ++-- .../Entity/EditorEntityModel.cpp | 9 ++------ .../Entity/EditorEntityModel.h | 4 +--- .../Prefab/PrefabPublicHandler.cpp | 21 +++++++++++++++++-- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h index 30ffb461fa..21c87da7b8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h @@ -201,11 +201,8 @@ namespace AzToolsFramework //! Fired after the EditorEntityContext fails to export the root level slice to the game stream virtual void OnSaveStreamForGameFailure(AZStd::string_view /*failureString*/) {} - //! Fired when the user triggers a clone of ComponentEntity object(s), before operation begins - virtual void OnEntitiesAboutToBeCloned() {} - - //! Fires when the user triggers a clone of ComponentEntity object(s)), after operation completes - virtual void OnEntitiesCloned() {} + //! Preserve entity order when re-parenting entities + virtual void ForceAddEntitiesToBack(bool /*forceAddToBack*/) {} }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp index 3e256430a2..265924e996 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp @@ -1157,7 +1157,7 @@ namespace AzToolsFramework bool CloneInstantiatedEntities(const EntityIdSet& entitiesToClone, EntityIdSet& clonedEntities) { - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesAboutToBeCloned); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, true); ScopedUndoBatch undoBatch("Clone Selection"); // Track the mapping of source to cloned entity. This both helps make sure that an entity is not accidentally @@ -1199,7 +1199,7 @@ namespace AzToolsFramework // Also replace the selection with the entities that have been cloned. Internal::UpdateUndoStackAndSelectClonedEntities(allEntityClonesContainer.m_entities, undoBatch); - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnEntitiesCloned); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, false); for (const AZ::Entity* entity : allEntityClonesContainer.m_entities) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp index e4d4f40bce..88db0b049c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp @@ -643,14 +643,9 @@ namespace AzToolsFramework } } - void EditorEntityModel::OnEntitiesAboutToBeCloned() + void EditorEntityModel::ForceAddEntitiesToBack(bool forceAddToBack) { - m_forceAddToBack = true; - } - - void EditorEntityModel::OnEntitiesCloned() - { - m_forceAddToBack = false; + m_forceAddToBack = forceAddToBack; } void EditorEntityModel::ChildEntityOrderArrayUpdated() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h index 45d3d4ea59..de6b598dfc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h @@ -94,9 +94,7 @@ namespace AzToolsFramework void OnEntityStreamLoadBegin() override; void OnEntityStreamLoadSuccess() override; void OnEntityStreamLoadFailed() override; - void OnEntitiesAboutToBeCloned() override; - void OnEntitiesCloned() override; - + void ForceAddEntitiesToBack(bool forceAddToBack) override; //////////////////////////////////////////////// // AzFramework::EntityContextEventBus::Handler diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index aaf6141e12..99806ca239 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,20 @@ namespace AzToolsFramework return AZ::Failure(findCommonRootOutcome.TakeError()); } + // order entities by their respective position within Entity Outliner + EditorEntitySortRequestBus::Event( + commonRootEntityId, + [&topLevelEntities](EditorEntitySortRequestBus::Events* sortRequests) + { + AZStd::sort( + topLevelEntities.begin(), topLevelEntities.end(), + [&sortRequests](AZ::Entity* entity1, AZ::Entity* entity2) + { + return sortRequests->GetChildEntityIndex(entity1->GetId()) < + sortRequests->GetChildEntityIndex(entity2->GetId()); + }); + }); + AZ::EntityId containerEntityId; InstanceOptionalReference instanceToCreate; @@ -153,8 +168,6 @@ namespace AzToolsFramework } // Create the Prefab - AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInMemory requires an absolute file path."); - instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab( entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(filePath), commonRootEntityOwningInstance); @@ -172,6 +185,7 @@ namespace AzToolsFramework // Parent the non-container top level entities to the container entity. // Parenting the top level container entities will be done during the creation of links. + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, true); for (AZ::Entity* topLevelEntity : topLevelEntities) { if (!IsInstanceContainerEntity(topLevelEntity->GetId())) @@ -179,6 +193,7 @@ namespace AzToolsFramework AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); } } + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, false); // Update the template of the instance since the entities are modified since the template creation. Prefab::PrefabDom serializedInstance; @@ -279,6 +294,8 @@ namespace AzToolsFramework CreatePrefabResult PrefabPublicHandler::CreatePrefabInDisk(const EntityIdList& entityIds, AZ::IO::PathView filePath) { + AZ_Assert(filePath.IsAbsolute(), "CreatePrefabInDisk requires an absolute file path."); + auto result = CreatePrefabInMemory(entityIds, filePath); if (result.IsSuccess()) { From f7c120b4b7571ab790ad34bffbaddafaf4d35717 Mon Sep 17 00:00:00 2001 From: Mikhail Naumov Date: Wed, 19 Jan 2022 15:15:15 -0600 Subject: [PATCH 258/272] PR feedback Signed-off-by: Mikhail Naumov --- .../AzToolsFramework/Entity/EditorEntityContextBus.h | 2 +- .../AzToolsFramework/Entity/EditorEntityHelpers.cpp | 4 ++-- .../AzToolsFramework/Entity/EditorEntityModel.cpp | 2 +- .../AzToolsFramework/Entity/EditorEntityModel.h | 2 +- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h index 21c87da7b8..1a5ba60bdf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityContextBus.h @@ -202,7 +202,7 @@ namespace AzToolsFramework virtual void OnSaveStreamForGameFailure(AZStd::string_view /*failureString*/) {} //! Preserve entity order when re-parenting entities - virtual void ForceAddEntitiesToBack(bool /*forceAddToBack*/) {} + virtual void SetForceAddEntitiesToBackFlag(bool /*forceAddToBack*/) {} }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp index 265924e996..dc0f5e9654 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp @@ -1157,7 +1157,7 @@ namespace AzToolsFramework bool CloneInstantiatedEntities(const EntityIdSet& entitiesToClone, EntityIdSet& clonedEntities) { - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, true); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true); ScopedUndoBatch undoBatch("Clone Selection"); // Track the mapping of source to cloned entity. This both helps make sure that an entity is not accidentally @@ -1199,7 +1199,7 @@ namespace AzToolsFramework // Also replace the selection with the entities that have been cloned. Internal::UpdateUndoStackAndSelectClonedEntities(allEntityClonesContainer.m_entities, undoBatch); - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, false); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false); for (const AZ::Entity* entity : allEntityClonesContainer.m_entities) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp index 88db0b049c..adf062875e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.cpp @@ -643,7 +643,7 @@ namespace AzToolsFramework } } - void EditorEntityModel::ForceAddEntitiesToBack(bool forceAddToBack) + void EditorEntityModel::SetForceAddEntitiesToBackFlag(bool forceAddToBack) { m_forceAddToBack = forceAddToBack; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h index de6b598dfc..c2574a9940 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityModel.h @@ -94,7 +94,7 @@ namespace AzToolsFramework void OnEntityStreamLoadBegin() override; void OnEntityStreamLoadSuccess() override; void OnEntityStreamLoadFailed() override; - void ForceAddEntitiesToBack(bool forceAddToBack) override; + void SetForceAddEntitiesToBackFlag(bool forceAddToBack) override; //////////////////////////////////////////////// // AzFramework::EntityContextEventBus::Handler diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 99806ca239..bde5de2f64 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -185,7 +185,7 @@ namespace AzToolsFramework // Parent the non-container top level entities to the container entity. // Parenting the top level container entities will be done during the creation of links. - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, true); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, true); for (AZ::Entity* topLevelEntity : topLevelEntities) { if (!IsInstanceContainerEntity(topLevelEntity->GetId())) @@ -193,7 +193,7 @@ namespace AzToolsFramework AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); } } - EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::ForceAddEntitiesToBack, false); + EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::SetForceAddEntitiesToBackFlag, false); // Update the template of the instance since the entities are modified since the template creation. Prefab::PrefabDom serializedInstance; From 2b43ad8029f53acd9edee4b49adfafdf9b2e0a01 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Wed, 19 Jan 2022 17:10:37 -0600 Subject: [PATCH 259/272] FastNoise GetValues() specialization (#7009) * Add comparison operator for use from unit tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * First version of FastNoise benchmarks. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Simplified unit tests and added initial benchmarks. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add GetValue vs GetValues unit test. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Moved Gradient test code into helper files for use from FastNoise. Also added benchmarks for each type of FastNoise so that we can have some comparative values handy. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Specialization for GetValues(). Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- Gems/FastNoise/Code/CMakeLists.txt | 46 ++-- .../Source/FastNoiseGradientComponent.cpp | 46 +++- .../Code/Source/FastNoiseGradientComponent.h | 3 + .../Code/Tests/FastNoiseBenchmarks.cpp | 116 ++++++++ .../Code/Tests/FastNoiseEditorTest.cpp | 44 +++ Gems/FastNoise/Code/Tests/FastNoiseTest.cpp | 254 ++++-------------- Gems/FastNoise/Code/Tests/FastNoiseTest.h | 60 +++++ .../Code/fastnoise_editor_tests_files.cmake | 13 + .../Code/fastnoise_tests_files.cmake | 1 + .../Code/Tests/GradientSignalBenchmarks.cpp | 211 ++------------- .../Tests/GradientSignalGetValuesTests.cpp | 76 ++---- .../Code/Tests/GradientSignalTestHelpers.cpp | 203 ++++++++++++++ .../Code/Tests/GradientSignalTestHelpers.h | 76 ++++++ .../gradientsignal_shared_tests_files.cmake | 2 + 14 files changed, 672 insertions(+), 479 deletions(-) create mode 100644 Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp create mode 100644 Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp create mode 100644 Gems/FastNoise/Code/Tests/FastNoiseTest.h create mode 100644 Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake create mode 100644 Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp create mode 100644 Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h diff --git a/Gems/FastNoise/Code/CMakeLists.txt b/Gems/FastNoise/Code/CMakeLists.txt index 819592e018..d945db1665 100644 --- a/Gems/FastNoise/Code/CMakeLists.txt +++ b/Gems/FastNoise/Code/CMakeLists.txt @@ -104,7 +104,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) NAME FastNoise.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} NAMESPACE Gem FILES_CMAKE - fastnoise_tests_files.cmake + fastnoise_editor_tests_files.cmake COMPILE_DEFINITIONS PUBLIC FASTNOISE_EDITOR @@ -120,23 +120,31 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_googletest( NAME Gem::FastNoise.Editor.Tests ) - else() - ly_add_target( - NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - fastnoise_tests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Tests - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Gem::FastNoise.Static - Gem::LmbrCentral - ) - ly_add_googletest( - NAME Gem::FastNoise.Tests - ) endif() + + ly_add_target( + NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + fastnoise_tests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + Gem::FastNoise.Static + Gem::GradientSignal + Gem::GradientSignal.Tests.Static + Gem::LmbrCentral + ) + ly_add_googletest( + NAME Gem::FastNoise.Tests + ) + + ly_add_googlebenchmark( + NAME Gem::FastNoise.Benchmarks + TARGET Gem::FastNoise.Tests + ) + endif() diff --git a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp index 4cea2efcc8..ceeafc3af6 100644 --- a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp +++ b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp @@ -54,6 +54,21 @@ namespace FastNoiseGem return AZ::Edit::PropertyVisibility::Hide; } + bool FastNoiseGradientConfig::operator==(const FastNoiseGradientConfig& rhs) const + { + return (m_cellularDistanceFunction == rhs.m_cellularDistanceFunction) + && (m_cellularJitter == rhs.m_cellularJitter) + && (m_cellularReturnType == rhs.m_cellularReturnType) + && (m_fractalType == rhs.m_fractalType) + && (m_frequency == rhs.m_frequency) + && (m_gain == rhs.m_gain) + && (m_interp == rhs.m_interp) + && (m_lacunarity == rhs.m_lacunarity) + && (m_noiseType == rhs.m_noiseType) + && (m_octaves == rhs.m_octaves) + && (m_seed == rhs.m_seed); + } + void FastNoiseGradientConfig::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) @@ -306,7 +321,7 @@ namespace FastNoiseGem float FastNoiseGradientComponent::GetValue(const GradientSignal::GradientSampleParams& sampleParams) const { - AZ::Vector3 uvw = sampleParams.m_position; + AZ::Vector3 uvw; bool wasPointRejected = false; { @@ -314,13 +329,34 @@ namespace FastNoiseGem m_gradientTransform.TransformPositionToUVW(sampleParams.m_position, uvw, wasPointRejected); } - if (!wasPointRejected) + // Generator returns a range between [-1, 1], map that to [0, 1] + return wasPointRejected ? + 0.0f : + AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f); + } + + void FastNoiseGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const + { + if (positions.size() != outValues.size()) { - // Generator returns a range between [-1, 1], map that to [0, 1] - return AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f); + AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size()); + return; } - return 0.0f; + AZStd::shared_lock lock(m_transformMutex); + AZ::Vector3 uvw; + + for (size_t index = 0; index < positions.size(); index++) + { + bool wasPointRejected = false; + + m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected); + + // Generator returns a range between [-1, 1], map that to [0, 1] + outValues[index] = wasPointRejected ? + 0.0f : + AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f); + } } template diff --git a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h index dd19049ee6..29c42bfe1b 100644 --- a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h +++ b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h @@ -47,6 +47,8 @@ namespace FastNoiseGem AZ::u32 GetFrequencyParameterVisbility() const; AZ::u32 GetInterpParameterVisibility() const; + bool operator==(const FastNoiseGradientConfig& rhs) const; + int m_seed = 1; float m_frequency = 1.f; FastNoise::Interp m_interp = FastNoise::Interp::Quintic; @@ -90,6 +92,7 @@ namespace FastNoiseGem // GradientRequestBus overrides... float GetValue(const GradientSignal::GradientSampleParams& sampleParams) const override; + void GetValues(AZStd::span positions, AZStd::span outValues) const override; protected: FastNoiseGradientConfig m_configuration; diff --git a/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp b/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp new file mode 100644 index 0000000000..1e438db112 --- /dev/null +++ b/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#ifdef HAVE_BENCHMARK + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace UnitTest +{ + class FastNoiseGetValues + : public ::benchmark::Fixture + { + public: + void RunGetValueOrGetValuesBenchmark(benchmark::State& state, FastNoise::NoiseType noiseType) + { + AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity"); + ASSERT_TRUE(noiseEntity != nullptr); + noiseEntity->CreateComponent(); + noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId); + noiseEntity->CreateComponent(); + + // Set up a FastNoise component with the requested noise type + FastNoiseGem::FastNoiseGradientConfig cfg; + cfg.m_frequency = 0.01f; + cfg.m_noiseType = noiseType; + noiseEntity->CreateComponent(cfg); + + noiseEntity->Init(); + noiseEntity->Activate(); + + UnitTest::GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, noiseEntity->GetId()); + } + + }; + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Value)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Value); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::ValueFractal); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Perlin); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::PerlinFractal); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Simplex); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::SimplexFractal); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cellular); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::WhiteNoise); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cubic); + } + + BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal)(benchmark::State& state) + { + RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::CubicFractal); + } + + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Value); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic); + GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal); + +#endif +} + + + diff --git a/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp b/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp new file mode 100644 index 0000000000..e30c6c01e0 --- /dev/null +++ b/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include + + +class FastNoiseEditorTestApp : public ::testing::Test +{ +}; + +TEST_F(FastNoiseEditorTestApp, FastNoise_EditorCreateGameEntity) +{ + AZStd::unique_ptr noiseEntity(aznew AZ::Entity("editor_noise_entity")); + ASSERT_TRUE(noiseEntity != nullptr); + + FastNoiseGem::EditorFastNoiseGradientComponent editor; + auto* editorBase = static_cast(&editor); + editorBase->BuildGameEntity(noiseEntity.get()); + + // the new game entity's FastNoise component should look like the default one + FastNoiseGem::FastNoiseGradientConfig defaultConfig; + FastNoiseGem::FastNoiseGradientConfig gameComponentConfig; + + FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent(); + ASSERT_TRUE(noiseComp != nullptr); + + // Change a value in the gameComponentConfig just to verify that it got overwritten instead of simply matching the default. + gameComponentConfig.m_seed++; + noiseComp->WriteOutConfig(&gameComponentConfig); + ASSERT_EQ(defaultConfig, gameComponentConfig); +} + +// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems. +AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment); diff --git a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp index f0d5a9d1bd..1ac5e8ddca 100644 --- a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp +++ b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp @@ -10,199 +10,61 @@ #include #include -#include -#include -#include #include +#include #include -#include -#include +#include #include -#include +#include +#include +#include #include #include #include +#include +#include -class MockGradientTransformComponent - : public AZ::Component - , private GradientSignal::GradientTransformRequestBus::Handler - , private GradientSignal::GradientTransformModifierRequestBus::Handler +class FastNoiseTest : public ::testing::Test { -public: - AZ_COMPONENT(MockGradientTransformComponent, "{464CF47B-7E10-4E1B-BD06-79BD2AC91399}"); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) - { - services.push_back(AZ_CRC("GradientTransformService", 0x8c8c5ecc)); - } - static void Reflect([[maybe_unused]] AZ::ReflectContext* context) {} - - MockGradientTransformComponent() = default; - ~MockGradientTransformComponent() = default; - - // AZ::Component interface - void Activate() override {} - void Deactivate() override {} - - //////////////////////////////////////////////////////////////////////////// - //// GradientTransformRequestBus - const GradientSignal::GradientTransform& GetGradientTransform() const override - { - return m_gradientTransform; - } - - ////////////////////////////////////////////////////////////////////////// - // GradientTransformModifierRequestBus - bool GetAllowReference() const override { return false; } - void SetAllowReference([[maybe_unused]] bool value) override {} - - AZ::EntityId GetShapeReference() const override { return AZ::EntityId(); } - void SetShapeReference([[maybe_unused]] AZ::EntityId shapeReference) override {} - - bool GetOverrideBounds() const override { return false; } - void SetOverrideBounds([[maybe_unused]] bool value) override {} - - AZ::Vector3 GetBounds() const override { return AZ::Vector3(); } - void SetBounds([[maybe_unused]] AZ::Vector3 bounds) override {} - - GradientSignal::TransformType GetTransformType() const override { return static_cast(0); } - void SetTransformType([[maybe_unused]] GradientSignal::TransformType type) override {} - - bool GetOverrideTranslate() const override { return false; } - void SetOverrideTranslate([[maybe_unused]] bool value) override {} - - AZ::Vector3 GetTranslate() const override { return AZ::Vector3(); } - void SetTranslate([[maybe_unused]] AZ::Vector3 translate) override {} - - bool GetOverrideRotate() const override { return false; } - void SetOverrideRotate([[maybe_unused]] bool value) override {} - - AZ::Vector3 GetRotate() const override { return AZ::Vector3(); } - void SetRotate([[maybe_unused]] AZ::Vector3 rotate) override {} - - bool GetOverrideScale() const override { return false; } - void SetOverrideScale([[maybe_unused]] bool value) override {} - - AZ::Vector3 GetScale() const override { return AZ::Vector3(); } - void SetScale([[maybe_unused]] AZ::Vector3 scale) override {} - - float GetFrequencyZoom() const override { return false; } - void SetFrequencyZoom([[maybe_unused]] float frequencyZoom) override {} - - GradientSignal::WrappingType GetWrappingType() const override { return static_cast(0); } - void SetWrappingType([[maybe_unused]] GradientSignal::WrappingType type) override {} - - bool GetIs3D() const override { return false; } - void SetIs3D([[maybe_unused]] bool value) override {} - - bool GetAdvancedMode() const override { return false; } - void SetAdvancedMode([[maybe_unused]] bool value) override {} - - GradientSignal::GradientTransform m_gradientTransform; }; -TEST(FastNoiseTest, ComponentsWithComponentApplication) -{ - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024; - appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL; - appDesc.m_stackRecordLevels = 20; - - AZ::ComponentApplication app; - AZ::Entity* systemEntity = app.Create(appDesc); - ASSERT_TRUE(systemEntity != nullptr); - app.RegisterComponentDescriptor(FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor()); - systemEntity->CreateComponent(); - - systemEntity->Init(); - systemEntity->Activate(); - - AZ::Entity* noiseEntity = aznew AZ::Entity("fastnoise_entity"); - noiseEntity->CreateComponent(); - app.AddEntity(noiseEntity); - - app.Destroy(); - ASSERT_TRUE(true); -} - -class FastNoiseTestApp - : public ::testing::Test -{ -public: - FastNoiseTestApp() - : m_application() - , m_systemEntity(nullptr) - { - } - - void SetUp() override - { - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024; - appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL; - appDesc.m_stackRecordLevels = 20; - - AZ::ComponentApplication::StartupParameters appStartup; - appStartup.m_createStaticModulesCallback = - [](AZStd::vector& modules) - { - modules.emplace_back(new FastNoiseGem::FastNoiseModule); - }; - - m_systemEntity = m_application.Create(appDesc, appStartup); - m_application.RegisterComponentDescriptor(MockGradientTransformComponent::CreateDescriptor()); - m_systemEntity->Init(); - m_systemEntity->Activate(); - } - - void TearDown() override - { - m_application.Destroy(); - } - - AZ::ComponentApplication m_application; - AZ::Entity* m_systemEntity; -}; - -////////////////////////////////////////////////////////////////////////// -// testing class to inspect protected data members in the FastNoiseGradientComponent -struct FastNoiseGradientComponentTester : public FastNoiseGem::FastNoiseGradientComponent -{ - const FastNoiseGem::FastNoiseGradientConfig& GetConfig() const { return m_configuration; } - - void AssertTrue(const FastNoiseGem::FastNoiseGradientConfig& cfg) - { - ASSERT_TRUE(m_configuration.m_cellularDistanceFunction == cfg.m_cellularDistanceFunction); - ASSERT_TRUE(m_configuration.m_cellularJitter == cfg.m_cellularJitter); - ASSERT_TRUE(m_configuration.m_cellularReturnType == cfg.m_cellularReturnType); - ASSERT_TRUE(m_configuration.m_fractalType == cfg.m_fractalType); - ASSERT_TRUE(m_configuration.m_frequency == cfg.m_frequency); - ASSERT_TRUE(m_configuration.m_gain == cfg.m_gain); - ASSERT_TRUE(m_configuration.m_interp == cfg.m_interp); - ASSERT_TRUE(m_configuration.m_lacunarity == cfg.m_lacunarity); - ASSERT_TRUE(m_configuration.m_noiseType == cfg.m_noiseType); - ASSERT_TRUE(m_configuration.m_octaves == cfg.m_octaves); - ASSERT_TRUE(m_configuration.m_seed == cfg.m_seed); - } -}; - -TEST_F(FastNoiseTestApp, FastNoise_Component) +TEST_F(FastNoiseTest, FastNoise_ComponentCreatesSuccessfully) { AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity"); ASSERT_TRUE(noiseEntity != nullptr); noiseEntity->CreateComponent(); - m_application.AddEntity(noiseEntity); FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent(); ASSERT_TRUE(noiseComp != nullptr); } -TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus) +TEST_F(FastNoiseTest, FastNoise_ComponentMatchesConfiguration) { AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity"); ASSERT_TRUE(noiseEntity != nullptr); + + FastNoiseGem::FastNoiseGradientConfig cfg; + FastNoiseGem::FastNoiseGradientConfig componentConfig; + + noiseEntity->CreateComponent(); + noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId); + noiseEntity->CreateComponent(); + noiseEntity->CreateComponent(cfg); + + FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent(); + ASSERT_TRUE(noiseComp != nullptr); + noiseComp->WriteOutConfig(&componentConfig); + ASSERT_EQ(cfg, componentConfig); +} + +TEST_F(FastNoiseTest, FastNoise_ComponentEbusWorksSuccessfully) +{ + AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity"); + ASSERT_TRUE(noiseEntity != nullptr); + noiseEntity->CreateComponent(); + noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId); + noiseEntity->CreateComponent(); noiseEntity->CreateComponent(); - noiseEntity->CreateComponent(); noiseEntity->Init(); noiseEntity->Activate(); @@ -210,51 +72,39 @@ TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus) GradientSignal::GradientSampleParams params; float sample = -1.0f; - GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params); + GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(), + &GradientSignal::GradientRequestBus::Events::GetValue, params); ASSERT_TRUE(sample >= 0.0f); ASSERT_TRUE(sample <= 1.0f); } -TEST_F(FastNoiseTestApp, FastNoise_ComponentMatchesConfiguration) +TEST_F(FastNoiseTest, FastNoise_VerifyGetValueAndGetValuesMatch) { + const float shapeHalfBounds = 128.0f; + AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity"); ASSERT_TRUE(noiseEntity != nullptr); + noiseEntity->CreateComponent(); + noiseEntity->CreateComponent(); - AZ::SimpleLcgRandom rand(AZStd::GetTimeNowMicroSecond()); + // Create a Box Shape to map our gradient into + LmbrCentral::BoxShapeConfig boxConfig(AZ::Vector3(shapeHalfBounds * 2.0f)); + auto boxComponent = noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId); + boxComponent->SetConfiguration(boxConfig); + // Create a Fast Noise component with an adjusted frequency. (The defaults of Perlin noise with frequency=1.0 would cause us + // to always get back the same noise value) FastNoiseGem::FastNoiseGradientConfig cfg; - + cfg.m_frequency = 0.01f; noiseEntity->CreateComponent(cfg); - noiseEntity->CreateComponent(); - m_application.AddEntity(noiseEntity); + noiseEntity->Init(); + noiseEntity->Activate(); - FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent(); - ASSERT_TRUE(noiseComp != nullptr); - reinterpret_cast(noiseComp)->AssertTrue(cfg); + // Create a gradient sampler and run through a series of points to see if they match expectations. + UnitTest::GradientSignalTestHelpers::CompareGetValueAndGetValues(noiseEntity->GetId(), shapeHalfBounds); } -#if FASTNOISE_EDITOR -#include - -TEST_F(FastNoiseTestApp, FastNoise_EditorCreateGameEntity) -{ - AZStd::unique_ptr noiseEntity(aznew AZ::Entity("editor_noise_entity")); - ASSERT_TRUE(noiseEntity != nullptr); - - FastNoiseGem::EditorFastNoiseGradientComponent editor; - auto* editorBase = static_cast(&editor); - editorBase->BuildGameEntity(noiseEntity.get()); - - // the new game entity's ocean component should look like the default one - FastNoiseGem::FastNoiseGradientConfig cfg; - - FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent(); - ASSERT_TRUE(noiseComp != nullptr); - reinterpret_cast(noiseComp)->AssertTrue(cfg); -} - -#endif - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); +// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems. +AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment); diff --git a/Gems/FastNoise/Code/Tests/FastNoiseTest.h b/Gems/FastNoise/Code/Tests/FastNoiseTest.h new file mode 100644 index 0000000000..71b10cfc68 --- /dev/null +++ b/Gems/FastNoise/Code/Tests/FastNoiseTest.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include + +namespace UnitTest +{ + // The FastNoise unit tests need to use the GemTestEnvironment to load the GradientSignal and LmbrCentral Gems so that + // GradientTransform components can be used in the unit tests and benchmarks. + class FastNoiseTestEnvironment + : public AZ::Test::GemTestEnvironment + { + public: + void AddGemsAndComponents() override + { + AddDynamicModulePaths({ "GradientSignal" }); + AddDynamicModulePaths({ "LmbrCentral" }); + + AddComponentDescriptors({ + AzFramework::TransformComponent::CreateDescriptor(), + FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor(), + FastNoiseGem::FastNoiseGradientComponent::CreateDescriptor() + }); + + AddRequiredComponents({ FastNoiseGem::FastNoiseSystemComponent::TYPEINFO_Uuid() }); + } + }; + +#ifdef HAVE_BENCHMARK + //! The Benchmark environment is used for one time setup and tear down of shared resources + class FastNoiseBenchmarkEnvironment + : public AZ::Test::BenchmarkEnvironmentBase + , public FastNoiseTestEnvironment + + { + protected: + void SetUpBenchmark() override + { + SetupEnvironment(); + } + + void TearDownBenchmark() override + { + TeardownEnvironment(); + } + }; +#endif + + +} // namespace UnitTest + diff --git a/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake b/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake new file mode 100644 index 0000000000..685e2fb647 --- /dev/null +++ b/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake @@ -0,0 +1,13 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + Tests/FastNoiseEditorTest.cpp + Source/FastNoiseModule.h + Source/FastNoiseModule.cpp +) diff --git a/Gems/FastNoise/Code/fastnoise_tests_files.cmake b/Gems/FastNoise/Code/fastnoise_tests_files.cmake index 08386940f2..4669b0d446 100644 --- a/Gems/FastNoise/Code/fastnoise_tests_files.cmake +++ b/Gems/FastNoise/Code/fastnoise_tests_files.cmake @@ -7,6 +7,7 @@ # set(FILES + Tests/FastNoiseBenchmarks.cpp Tests/FastNoiseTest.cpp Source/FastNoiseModule.h Source/FastNoiseModule.cpp diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp index bd4ccf5205..6ffb4a31c4 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp @@ -9,6 +9,7 @@ #ifdef HAVE_BENCHMARK #include +#include #include #include @@ -21,220 +22,42 @@ namespace UnitTest class GradientGetValues : public GradientSignalBenchmarkFixture { public: - // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases - // to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark - // function for each test case for each gradient. - enum GetValuePermutation : int64_t - { - EBUS_GET_VALUE, - EBUS_GET_VALUES, - SAMPLER_GET_VALUE, - SAMPLER_GET_VALUES, - }; - // Create an arbitrary size shape for creating our gradients for benchmark runs. const float TestShapeHalfBounds = 128.0f; - - void FillQueryPositions(AZStd::vector& positions, float height, float width) - { - size_t index = 0; - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - positions[index++] = AZ::Vector3(x, y, 0.0f); - } - } - } - - void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) - { - AZ_PROFILE_FUNCTION(Entity); - - GradientSignal::GradientSampleParams params; - - // Get the height and width ranges for querying from our benchmark parameters - const float height = aznumeric_cast(queryRange); - const float width = aznumeric_cast(queryRange); - - // Call GetValue() on the EBus for every height and width in our ranges. - for (auto _ : state) - { - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - float value = 0.0f; - params.m_position = AZ::Vector3(x, y, 0.0f); - GradientSignal::GradientRequestBus::EventResult( - value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params); - benchmark::DoNotOptimize(value); - } - } - } - } - - void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) - { - AZ_PROFILE_FUNCTION(Entity); - - // Get the height and width ranges for querying from our benchmark parameters - float height = aznumeric_cast(queryRange); - float width = aznumeric_cast(queryRange); - int64_t totalQueryPoints = queryRange * queryRange; - - // Call GetValues() for every height and width in our ranges. - for (auto _ : state) - { - // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create - // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. - AZStd::vector positions(totalQueryPoints); - FillQueryPositions(positions, height, width); - - // Query and get the results. - AZStd::vector results(totalQueryPoints); - GradientSignal::GradientRequestBus::Event( - gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); - } - } - - void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) - { - AZ_PROFILE_FUNCTION(Entity); - - // Create a gradient sampler to use for querying our gradient. - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = gradientId; - - // Get the height and width ranges for querying from our benchmark parameters - const float height = aznumeric_cast(queryRange); - const float width = aznumeric_cast(queryRange); - - // Call GetValue() through the GradientSampler for every height and width in our ranges. - for (auto _ : state) - { - for (float y = 0.0f; y < height; y += 1.0f) - { - for (float x = 0.0f; x < width; x += 1.0f) - { - GradientSignal::GradientSampleParams params; - params.m_position = AZ::Vector3(x, y, 0.0f); - float value = gradientSampler.GetValue(params); - benchmark::DoNotOptimize(value); - } - } - } - } - - void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) - { - AZ_PROFILE_FUNCTION(Entity); - - // Create a gradient sampler to use for querying our gradient. - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = gradientId; - - // Get the height and width ranges for querying from our benchmark parameters - const float height = aznumeric_cast(queryRange); - const float width = aznumeric_cast(queryRange); - const int64_t totalQueryPoints = queryRange * queryRange; - - // Call GetValues() through the GradientSampler for every height and width in our ranges. - for (auto _ : state) - { - // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create - // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. - AZStd::vector positions(totalQueryPoints); - FillQueryPositions(positions, height, width); - - // Query and get the results. - AZStd::vector results(totalQueryPoints); - gradientSampler.GetValues(positions, results); - } - } - - void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId) - { - switch (state.range(0)) - { - case GetValuePermutation::EBUS_GET_VALUE: - RunEBusGetValueBenchmark(state, gradientId, state.range(1)); - break; - case GetValuePermutation::EBUS_GET_VALUES: - RunEBusGetValuesBenchmark(state, gradientId, state.range(1)); - break; - case GetValuePermutation::SAMPLER_GET_VALUE: - RunSamplerGetValueBenchmark(state, gradientId, state.range(1)); - break; - case GetValuePermutation::SAMPLER_GET_VALUES: - RunSamplerGetValuesBenchmark(state, gradientId, state.range(1)); - break; - default: - AZ_Assert(false, "Benchmark permutation type not supported."); - } - } }; -// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by -// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results. -#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \ - BENCHMARK_REGISTER_F(Fixture, Func) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \ - ->ArgNames({ "EbusGetValue", "size" }) \ - ->Unit(::benchmark::kMillisecond); \ - BENCHMARK_REGISTER_F(Fixture, Func) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \ - ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \ - ->ArgNames({ "EbusGetValues", "size" }) \ - ->Unit(::benchmark::kMillisecond); \ - BENCHMARK_REGISTER_F(Fixture, Func) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \ - ->ArgNames({ "SamplerGetValue", "size" }) \ - ->Unit(::benchmark::kMillisecond); \ - BENCHMARK_REGISTER_F(Fixture, Func) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \ - ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \ - ->ArgNames({ "SamplerGetValues", "size" }) \ - ->Unit(::benchmark::kMillisecond); - // -------------------------------------------------------------------------------------- // Base Gradients BENCHMARK_DEFINE_F(GradientGetValues, BM_ConstantGradient)(benchmark::State& state) { auto entity = BuildTestConstantGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_ImageGradient)(benchmark::State& state) { auto entity = BuildTestImageGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_PerlinGradient)(benchmark::State& state) { auto entity = BuildTestPerlinGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_RandomGradient)(benchmark::State& state) { auto entity = BuildTestRandomGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_ShapeAreaFalloffGradient)(benchmark::State& state) { auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ConstantGradient); @@ -250,21 +73,21 @@ namespace UnitTest { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_InvertGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_LevelsGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_MixedGradient)(benchmark::State& state) @@ -272,35 +95,35 @@ namespace UnitTest auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds); auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_PosterizeGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_ReferenceGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_SmoothStepGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_ThresholdGradient)(benchmark::State& state) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId()); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_DitherGradient); @@ -321,7 +144,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state) @@ -330,7 +153,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state) @@ -339,7 +162,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); - RunGetValueOrGetValuesBenchmark(state, entity->GetId()); + GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId()); } GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceAltitudeGradient); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp index 6c4ebcc4c0..f0ad53ee64 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp @@ -8,6 +8,7 @@ #include +#include #include namespace UnitTest @@ -18,79 +19,36 @@ namespace UnitTest // Create an arbitrary size shape for comparing values within. It should be large enough that we detect any value anomalies // but small enough that the tests run quickly. const float TestShapeHalfBounds = 128.0f; - - void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId) - { - // Create a gradient sampler and run through a series of points to see if they match expectations. - - const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)); - const AZ::Vector2 stepSize(1.0f, 1.0f); - - GradientSignal::GradientSampler gradientSampler; - gradientSampler.m_gradientId = gradientEntityId; - - const size_t numSamplesX = aznumeric_cast(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX())); - const size_t numSamplesY = aznumeric_cast(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY())); - - // Build up the list of positions to query. - AZStd::vector positions(numSamplesX * numSamplesY); - size_t index = 0; - for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) - { - float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex); - for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) - { - float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex); - positions[index++] = AZ::Vector3(x, y, 0.0f); - } - } - - // Get the results from GetValues - AZStd::vector results(numSamplesX * numSamplesY); - gradientSampler.GetValues(positions, results); - - // For each position, call GetValue and verify that the values match. - for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++) - { - GradientSignal::GradientSampleParams params; - params.m_position = positions[positionIndex]; - float value = gradientSampler.GetValue(params); - - // We use ASSERT_NEAR instead of EXPECT_NEAR because if one value doesn't match, they probably all won't, so there's no - // reason to keep running and printing failures for every value. - ASSERT_NEAR(value, results[positionIndex], 0.000001f); - } - } }; TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestImageGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestPerlinGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestRandomGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestConstantGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch) { auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -98,21 +56,21 @@ namespace UnitTest auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -120,35 +78,35 @@ namespace UnitTest auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds); auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch) { auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds); auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId()); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -157,7 +115,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -166,7 +124,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch) @@ -175,7 +133,7 @@ namespace UnitTest CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds))); auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds); - CompareGetValueAndGetValues(entity->GetId()); + GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds); } } diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp new file mode 100644 index 0000000000..46cc3475e8 --- /dev/null +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + + +#include +#include +#include + +namespace UnitTest +{ + void GradientSignalTestHelpers::CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds) + { + // Create a gradient sampler and run through a series of points to see if they match expectations. + + const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-shapeHalfBounds), AZ::Vector3(shapeHalfBounds)); + const AZ::Vector2 stepSize(1.0f, 1.0f); + + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientEntityId; + + const size_t numSamplesX = aznumeric_cast(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY())); + + // Build up the list of positions to query. + AZStd::vector positions(numSamplesX * numSamplesY); + size_t index = 0; + for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) + { + float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex); + for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) + { + float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex); + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + + // Get the results from GetValues + AZStd::vector results(numSamplesX * numSamplesY); + gradientSampler.GetValues(positions, results); + + // For each position, call GetValue and verify that the values match. + for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++) + { + GradientSignal::GradientSampleParams params; + params.m_position = positions[positionIndex]; + float value = gradientSampler.GetValue(params); + + // We use ASSERT_NEAR instead of EXPECT_NEAR because if one value doesn't match, they probably all won't, so there's no + // reason to keep running and printing failures for every value. + ASSERT_NEAR(value, results[positionIndex], 0.000001f); + } + } + +#ifdef HAVE_BENCHMARK + + void GradientSignalTestHelpers::FillQueryPositions(AZStd::vector& positions, float height, float width) + { + size_t index = 0; + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + positions[index++] = AZ::Vector3(x, y, 0.0f); + } + } + } + + void GradientSignalTestHelpers::RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + GradientSignal::GradientSampleParams params; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + + // Call GetValue() on the EBus for every height and width in our ranges. + for (auto _ : state) + { + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + float value = 0.0f; + params.m_position = AZ::Vector3(x, y, 0.0f); + GradientSignal::GradientRequestBus::EventResult( + value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params); + benchmark::DoNotOptimize(value); + } + } + } + } + + void GradientSignalTestHelpers::RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Get the height and width ranges for querying from our benchmark parameters + float height = aznumeric_cast(queryRange); + float width = aznumeric_cast(queryRange); + int64_t totalQueryPoints = queryRange * queryRange; + + // Call GetValues() for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create + // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. + AZStd::vector positions(totalQueryPoints); + FillQueryPositions(positions, height, width); + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + GradientSignal::GradientRequestBus::Event( + gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results); + } + } + + void GradientSignalTestHelpers::RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Create a gradient sampler to use for querying our gradient. + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientId; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + + // Call GetValue() through the GradientSampler for every height and width in our ranges. + for (auto _ : state) + { + for (float y = 0.0f; y < height; y += 1.0f) + { + for (float x = 0.0f; x < width; x += 1.0f) + { + GradientSignal::GradientSampleParams params; + params.m_position = AZ::Vector3(x, y, 0.0f); + float value = gradientSampler.GetValue(params); + benchmark::DoNotOptimize(value); + } + } + } + } + + void GradientSignalTestHelpers::RunSamplerGetValuesBenchmark( + benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange) + { + AZ_PROFILE_FUNCTION(Entity); + + // Create a gradient sampler to use for querying our gradient. + GradientSignal::GradientSampler gradientSampler; + gradientSampler.m_gradientId = gradientId; + + // Get the height and width ranges for querying from our benchmark parameters + const float height = aznumeric_cast(queryRange); + const float width = aznumeric_cast(queryRange); + const int64_t totalQueryPoints = queryRange * queryRange; + + // Call GetValues() through the GradientSampler for every height and width in our ranges. + for (auto _ : state) + { + // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create + // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. + AZStd::vector positions(totalQueryPoints); + FillQueryPositions(positions, height, width); + + // Query and get the results. + AZStd::vector results(totalQueryPoints); + gradientSampler.GetValues(positions, results); + } + } + + void GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId) + { + switch (state.range(0)) + { + case GetValuePermutation::EBUS_GET_VALUE: + RunEBusGetValueBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::EBUS_GET_VALUES: + RunEBusGetValuesBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::SAMPLER_GET_VALUE: + RunSamplerGetValueBenchmark(state, gradientId, state.range(1)); + break; + case GetValuePermutation::SAMPLER_GET_VALUES: + RunSamplerGetValuesBenchmark(state, gradientId, state.range(1)); + break; + default: + AZ_Assert(false, "Benchmark permutation type not supported."); + } + } +#endif +} + + diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h new file mode 100644 index 0000000000..8a175939ee --- /dev/null +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include + +namespace UnitTest +{ + class GradientSignalTestHelpers + { + public: + static void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds); + +#ifdef HAVE_BENCHMARK + // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases + // to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark + // function for each test case for each gradient. + enum GetValuePermutation : int64_t + { + EBUS_GET_VALUE, + EBUS_GET_VALUES, + SAMPLER_GET_VALUE, + SAMPLER_GET_VALUES, + }; + + static void FillQueryPositions(AZStd::vector& positions, float height, float width); + + static void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange); + static void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange); + static void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange); + static void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange); + static void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId); + +// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by +// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results. +#ifndef GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F +#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \ + ->ArgNames({ "EbusGetValue", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \ + ->ArgNames({ "EbusGetValues", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \ + ->ArgNames({ "SamplerGetValue", "size" }) \ + ->Unit(::benchmark::kMillisecond); \ + BENCHMARK_REGISTER_F(Fixture, Func) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \ + ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \ + ->ArgNames({ "SamplerGetValues", "size" }) \ + ->Unit(::benchmark::kMillisecond); +#endif + +#endif + }; + + +} diff --git a/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake index 7d867b0a33..98ab57b7b0 100644 --- a/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake +++ b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake @@ -7,6 +7,8 @@ # set(FILES + Tests/GradientSignalTestHelpers.cpp + Tests/GradientSignalTestHelpers.h Tests/GradientSignalTestFixtures.cpp Tests/GradientSignalTestFixtures.h Tests/GradientSignalTestMocks.cpp From 4b5f4042f201c35c94f1a60c82975342670972d9 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 19 Jan 2022 16:05:51 -0800 Subject: [PATCH 260/272] Move common code used by multiple tests into functions to reduce code duplication. Signed-off-by: amzn-sj --- .../Tests/TerrainPhysicsColliderTests.cpp | 117 ++++++-------- Gems/Terrain/Code/Tests/TerrainSystemTest.cpp | 149 ++++++++---------- 2 files changed, 111 insertions(+), 155 deletions(-) diff --git a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp index 859e618983..2d0933c367 100644 --- a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp +++ b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp @@ -69,6 +69,46 @@ protected: m_colliderComponent = m_entity->CreateComponent(Terrain::TerrainPhysicsColliderConfig()); m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor()); } + + void ProcessRegionLoop(const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, + AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter, + AzFramework::SurfaceData::SurfaceTagWeightList* surfaceTags, + float mockHeight) + { + if (!perPositionCallback) + { + return; + } + + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + AzFramework::SurfaceData::SurfacePoint surfacePoint; + for (size_t y = 0; y < numSamplesY; y++) + { + float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + for (size_t x = 0; x < numSamplesX; x++) + { + bool terrainExists = false; + float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + surfacePoint.m_position.Set(fx, fy, mockHeight); + if (surfaceTags) + { + surfacePoint.m_surfaceTags.clear(); + if (fy < 128.0) + { + surfacePoint.m_surfaceTags.push_back(surfaceTags->at(0)); + } + else + { + surfacePoint.m_surfaceTags.push_back(surfaceTags->at(1)); + } + } + perPositionCallback(x, y, surfacePoint, terrainExists); + } + } + } }; TEST_F(TerrainPhysicsColliderComponentTest, ActivateEntityActivateSuccess) @@ -239,30 +279,11 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsRetu NiceMock terrainListener; ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( - [](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + [this](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - if (!perPositionCallback) - { - return; - } - - const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); - const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); - - AzFramework::SurfaceData::SurfacePoint surfacePoint; - for (size_t y = 0; y < numSamplesY; y++) - { - float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); - for (size_t x = 0; x < numSamplesX; x++) - { - bool terrainExists = false; - float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); - surfacePoint.m_position.Set(fx, fy, 0.0f); - perPositionCallback(x, y, surfacePoint, terrainExists); - } - } + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, nullptr, 0.0f); } ); @@ -300,30 +321,11 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsRelativ NiceMock terrainListener; ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( - [mockHeight](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + [this, mockHeight](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - if (!perPositionCallback) - { - return; - } - - const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); - const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); - - AzFramework::SurfaceData::SurfacePoint surfacePoint; - for (size_t y = 0; y < numSamplesY; y++) - { - float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); - for (size_t x = 0; x < numSamplesX; x++) - { - bool terrainExists = false; - float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); - surfacePoint.m_position.Set(fx, fy, mockHeight); - perPositionCallback(x, y, surfacePoint, terrainExists); - } - } + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, nullptr, mockHeight); } ); @@ -467,39 +469,16 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM return2.m_surfaceType = tag2; return2.m_weight = 1.0f; + AzFramework::SurfaceData::SurfaceTagWeightList surfaceTags = { return1, return2 }; + NiceMock terrainListener; ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution)); ON_CALL(terrainListener, ProcessSurfacePointsFromRegion).WillByDefault( - [mockHeight, return1, return2](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, + [this, mockHeight, &surfaceTags](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - if (!perPositionCallback) - { - return; - } - - const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); - const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); - - AzFramework::SurfaceData::SurfacePoint surfacePoint; - for (size_t y = 0; y < numSamplesY; y++) - { - float fy = aznumeric_cast(inRegion.GetMin().GetY() + (y * stepSize.GetY())); - for (size_t x = 0; x < numSamplesX; x++) - { - surfacePoint.m_surfaceTags.clear(); - bool terrainExists = false; - float fx = aznumeric_cast(inRegion.GetMin().GetX() + (x * stepSize.GetX())); - surfacePoint.m_position.Set(fx, fy, mockHeight); - if (fy < 128.0) - { - surfacePoint.m_surfaceTags.push_back(return1); - } - surfacePoint.m_surfaceTags.push_back(return2); - perPositionCallback(x, y, surfacePoint, terrainExists); - } - } + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, &surfaceTags, mockHeight); } ); diff --git a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp index 2eebc1b824..ab0847e634 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp @@ -68,6 +68,7 @@ namespace UnitTest AZStd::unique_ptr> m_boxShapeRequests; AZStd::unique_ptr> m_shapeRequests; AZStd::unique_ptr> m_terrainAreaHeightRequests; + AZStd::unique_ptr> m_terrainAreaSurfaceRequests; void SetUp() override { @@ -84,6 +85,7 @@ namespace UnitTest m_boxShapeRequests.reset(); m_shapeRequests.reset(); m_terrainAreaHeightRequests.reset(); + m_terrainAreaSurfaceRequests.reset(); m_app.Destroy(); } @@ -160,6 +162,49 @@ namespace UnitTest ActivateEntity(entity.get()); return entity; } + + void SetupSurfaceWeightMocks(AZ::Entity* entity, AzFramework::SurfaceData::SurfaceTagWeightList& expectedTags) + { + const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1"); + const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2"); + const SurfaceData::SurfaceTag tag3 = SurfaceData::SurfaceTag("tag3"); + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight1; + tagWeight1.m_surfaceType = tag1; + tagWeight1.m_weight = 1.0f; + expectedTags.push_back(tagWeight1); + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight2; + tagWeight2.m_surfaceType = tag2; + tagWeight2.m_weight = 0.7f; + expectedTags.push_back(tagWeight2); + + AzFramework::SurfaceData::SurfaceTagWeight tagWeight3; + tagWeight3.m_surfaceType = tag3; + tagWeight3.m_weight = 0.3f; + expectedTags.push_back(tagWeight3); + + m_terrainAreaSurfaceRequests = AZStd::make_unique>(entity->GetId()); + ON_CALL(*m_terrainAreaSurfaceRequests, GetSurfaceWeights).WillByDefault( + [tagWeight1, tagWeight2, tagWeight3](const AZ::Vector3& position, AzFramework::SurfaceData::SurfaceTagWeightList& surfaceWeights) + { + surfaceWeights.clear(); + float absYPos = fabsf(position.GetY()); + if (absYPos < 1.0f) + { + surfaceWeights.push_back(tagWeight1); + } + else if(absYPos < 2.0f) + { + surfaceWeights.push_back(tagWeight2); + } + else + { + surfaceWeights.push_back(tagWeight3); + } + } + ); + } }; TEST_F(TerrainSystemTest, TrivialCreateDestroy) @@ -921,62 +966,28 @@ namespace UnitTest const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-3.0f, -3.0f, -1.0f, 3.0f, 3.0f, 1.0f); const AZ::Vector2 stepSize(1.0f); - const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1"); - const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2"); - const SurfaceData::SurfaceTag tag3 = SurfaceData::SurfaceTag("tag3"); + AzFramework::SurfaceData::SurfaceTagWeightList expectedTags; + SetupSurfaceWeightMocks(entity.get(), expectedTags); - AzFramework::SurfaceData::SurfaceTagWeight tagWeight1; - tagWeight1.m_surfaceType = tag1; - tagWeight1.m_weight = 1.0f; - - AzFramework::SurfaceData::SurfaceTagWeight tagWeight2; - tagWeight2.m_surfaceType = tag2; - tagWeight2.m_weight = 0.7f; - - AzFramework::SurfaceData::SurfaceTagWeight tagWeight3; - tagWeight3.m_surfaceType = tag3; - tagWeight3.m_weight = 0.3f; - - NiceMock mockSurfaceRequests(entity->GetId()); - ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault( - [&tagWeight1, &tagWeight2, &tagWeight3](const AZ::Vector3& position, AzFramework::SurfaceData::SurfaceTagWeightList& surfaceWeights) - { - surfaceWeights.clear(); - float absYPos = fabsf(position.GetY()); - if (absYPos < 1.0f) - { - surfaceWeights.push_back(tagWeight1); - } - else if(absYPos < 2.0f) - { - surfaceWeights.push_back(tagWeight2); - } - else - { - surfaceWeights.push_back(tagWeight3); - } - } - ); - - auto perPositionCallback = [&tagWeight1, &tagWeight2, &tagWeight3](size_t xIndex, size_t yIndex, + auto perPositionCallback = [&expectedTags](size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { constexpr float epsilon = 0.0001f; float absYPos = fabsf(surfacePoint.m_position.GetY()); if (absYPos < 1.0f) { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight1.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight1.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[0].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[0].m_weight, epsilon); } else if(absYPos < 2.0f) { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight2.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight2.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[1].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[1].m_weight, epsilon); } else { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight3.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight3.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[2].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[2].m_weight, epsilon); } }; @@ -1001,44 +1012,10 @@ namespace UnitTest const AZ::Aabb testRegionBox = AZ::Aabb::CreateFromMinMaxValues(-3.0f, -3.0f, -1.0f, 3.0f, 3.0f, 1.0f); const AZ::Vector2 stepSize(1.0f); - const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1"); - const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2"); - const SurfaceData::SurfaceTag tag3 = SurfaceData::SurfaceTag("tag3"); + AzFramework::SurfaceData::SurfaceTagWeightList expectedTags; + SetupSurfaceWeightMocks(entity.get(), expectedTags); - AzFramework::SurfaceData::SurfaceTagWeight tagWeight1; - tagWeight1.m_surfaceType = tag1; - tagWeight1.m_weight = 1.0f; - - AzFramework::SurfaceData::SurfaceTagWeight tagWeight2; - tagWeight2.m_surfaceType = tag2; - tagWeight2.m_weight = 0.7f; - - AzFramework::SurfaceData::SurfaceTagWeight tagWeight3; - tagWeight3.m_surfaceType = tag3; - tagWeight3.m_weight = 0.3f; - - NiceMock mockSurfaceRequests(entity->GetId()); - ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault( - [&tagWeight1, &tagWeight2, &tagWeight3](const AZ::Vector3& position, AzFramework::SurfaceData::SurfaceTagWeightList& surfaceWeights) - { - surfaceWeights.clear(); - float absYPos = fabsf(position.GetY()); - if (absYPos < 1.0f) - { - surfaceWeights.push_back(tagWeight1); - } - else if(absYPos < 2.0f) - { - surfaceWeights.push_back(tagWeight2); - } - else - { - surfaceWeights.push_back(tagWeight3); - } - } - ); - - auto perPositionCallback = [&tagWeight1, &tagWeight2, &tagWeight3](size_t xIndex, size_t yIndex, + auto perPositionCallback = [&expectedTags](size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { constexpr float epsilon = 0.0001f; @@ -1049,18 +1026,18 @@ namespace UnitTest float absYPos = fabsf(surfacePoint.m_position.GetY()); if (absYPos < 1.0f) { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight1.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight1.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[0].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[0].m_weight, epsilon); } else if(absYPos < 2.0f) { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight2.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight2.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[1].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[1].m_weight, epsilon); } else { - EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, tagWeight3.m_surfaceType); - EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, tagWeight3.m_weight, epsilon); + EXPECT_EQ(surfacePoint.m_surfaceTags[0].m_surfaceType, expectedTags[2].m_surfaceType); + EXPECT_NEAR(surfacePoint.m_surfaceTags[0].m_weight, expectedTags[2].m_weight, epsilon); } }; From 63d755b8f152bf062952bb7527de2bbb357441f9 Mon Sep 17 00:00:00 2001 From: AMZN-byrcolin <68035668+byrcolin@users.noreply.github.com> Date: Wed, 19 Jan 2022 17:09:40 -0800 Subject: [PATCH 261/272] fix launcher not showing gems (#7015) Signed-off-by: byrcolin --- Code/Tools/ProjectManager/Source/PythonBindings.cpp | 4 ++-- Gems/Atom/Asset/ImageProcessingAtom/gem.json | 2 +- Gems/Atom/Bootstrap/gem.json | 2 +- Gems/Atom/Component/DebugCamera/gem.json | 2 +- Gems/Atom/Feature/Common/gem.json | 2 +- Gems/Atom/RHI/DX12/gem.json | 2 +- Gems/Atom/RHI/Metal/gem.json | 2 +- Gems/Atom/RHI/Null/gem.json | 2 +- Gems/Atom/RHI/Vulkan/gem.json | 2 +- Gems/Atom/RHI/gem.json | 2 +- Gems/Atom/RPI/gem.json | 2 +- Gems/Atom/Tools/AtomToolsFramework/gem.json | 2 +- Gems/AtomLyIntegration/AtomBridge/gem.json | 2 +- Gems/AtomLyIntegration/AtomFont/gem.json | 2 +- Gems/AtomLyIntegration/AtomImGuiTools/gem.json | 2 +- Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json | 2 +- Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json | 2 +- Gems/AtomLyIntegration/CommonFeatures/gem.json | 2 +- Gems/AtomLyIntegration/EMotionFXAtom/gem.json | 2 +- Gems/AtomLyIntegration/ImguiAtom/gem.json | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 7c436a3a70..60959d4090 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -408,7 +408,7 @@ namespace O3DE::ProjectManager } // check if engine path is registered - auto allEngines = m_manifest.attr("get_engines")(); + auto allEngines = m_manifest.attr("get_manifest_engines")(); if (pybind11::isinstance(allEngines)) { const AZ::IO::FixedMaxPath enginePathFixed(Py_To_String(enginePath)); @@ -891,7 +891,7 @@ namespace O3DE::ProjectManager bool result = ExecuteWithLock([&] { // external projects - for (auto path : m_manifest.attr("get_projects")()) + for (auto path : m_manifest.attr("get_manifest_projects")()) { projects.push_back(ProjectInfoFromPath(path)); } diff --git a/Gems/Atom/Asset/ImageProcessingAtom/gem.json b/Gems/Atom/Asset/ImageProcessingAtom/gem.json index c2af4b7e7e..baa46268b3 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/gem.json +++ b/Gems/Atom/Asset/ImageProcessingAtom/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Image processing for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/Bootstrap/gem.json b/Gems/Atom/Bootstrap/gem.json index 543efe0f34..726021235f 100644 --- a/Gems/Atom/Bootstrap/gem.json +++ b/Gems/Atom/Bootstrap/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Atom Bootstrap", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/Component/DebugCamera/gem.json b/Gems/Atom/Component/DebugCamera/gem.json index 74d88a21b6..678cce3045 100644 --- a/Gems/Atom/Component/DebugCamera/gem.json +++ b/Gems/Atom/Component/DebugCamera/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Debug Camera component for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/Feature/Common/gem.json b/Gems/Atom/Feature/Common/gem.json index f4c936dc4a..d915c55b1d 100644 --- a/Gems/Atom/Feature/Common/gem.json +++ b/Gems/Atom/Feature/Common/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Common features for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RHI/DX12/gem.json b/Gems/Atom/RHI/DX12/gem.json index 803ae4f4d0..67d91790a9 100644 --- a/Gems/Atom/RHI/DX12/gem.json +++ b/Gems/Atom/RHI/DX12/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "DX12 RHI for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RHI/Metal/gem.json b/Gems/Atom/RHI/Metal/gem.json index 0257048bd3..555b86523c 100644 --- a/Gems/Atom/RHI/Metal/gem.json +++ b/Gems/Atom/RHI/Metal/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Metal RHI for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RHI/Null/gem.json b/Gems/Atom/RHI/Null/gem.json index 1ea2eb4cb0..d531aa4ab5 100644 --- a/Gems/Atom/RHI/Null/gem.json +++ b/Gems/Atom/RHI/Null/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Atom Null RHI", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RHI/Vulkan/gem.json b/Gems/Atom/RHI/Vulkan/gem.json index 508ad85c75..5d49085ac5 100644 --- a/Gems/Atom/RHI/Vulkan/gem.json +++ b/Gems/Atom/RHI/Vulkan/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Vulcan RHI for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RHI/gem.json b/Gems/Atom/RHI/gem.json index 858a64fc17..49ec18ea53 100644 --- a/Gems/Atom/RHI/gem.json +++ b/Gems/Atom/RHI/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "RHI for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/RPI/gem.json b/Gems/Atom/RPI/gem.json index 0acef5179b..fe135c3e90 100644 --- a/Gems/Atom/RPI/gem.json +++ b/Gems/Atom/RPI/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "RPI for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/Atom/Tools/AtomToolsFramework/gem.json b/Gems/Atom/Tools/AtomToolsFramework/gem.json index 6e5a7b311a..a86244e7cc 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/gem.json +++ b/Gems/Atom/Tools/AtomToolsFramework/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Tools Framework for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/AtomBridge/gem.json b/Gems/AtomLyIntegration/AtomBridge/gem.json index 5a8512c90d..87a10aa6d3 100644 --- a/Gems/AtomLyIntegration/AtomBridge/gem.json +++ b/Gems/AtomLyIntegration/AtomBridge/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Atom Bridge", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/AtomFont/gem.json b/Gems/AtomLyIntegration/AtomFont/gem.json index d979509059..4f5ba75ff2 100644 --- a/Gems/AtomLyIntegration/AtomFont/gem.json +++ b/Gems/AtomLyIntegration/AtomFont/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Font Rendering for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json index 205120f6f0..2ae8edfa57 100644 --- a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json +++ b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Tool", - "summary": "", + "summary": "ImGui tools for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json index cff957c1f1..a7b9dab980 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json +++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Viewport display icons for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json index a2bc92c76d..0deeeef602 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Viewport Display Information for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/CommonFeatures/gem.json b/Gems/AtomLyIntegration/CommonFeatures/gem.json index a06f607fab..b6290679b9 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/gem.json +++ b/Gems/AtomLyIntegration/CommonFeatures/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "Common features for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json index 8bea93da91..3847432cf7 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json +++ b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "EmotionFX for Atom", "canonical_tags": [ "Gem" ], diff --git a/Gems/AtomLyIntegration/ImguiAtom/gem.json b/Gems/AtomLyIntegration/ImguiAtom/gem.json index 4c65d80e33..70ff1c0414 100644 --- a/Gems/AtomLyIntegration/ImguiAtom/gem.json +++ b/Gems/AtomLyIntegration/ImguiAtom/gem.json @@ -6,7 +6,7 @@ "origin": "Open 3D Engine - o3de.org", "origin_url": "https://github.com/o3de/o3de", "type": "Code", - "summary": "", + "summary": "ImGui support for Atom", "canonical_tags": [ "Gem" ], From 7bba4172ece3aa4d44c9ac1970d7e8c667fc582a Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 19 Jan 2022 18:04:56 -0800 Subject: [PATCH 262/272] Add a GetNumSamplesFromRegion function which returns the number of samples given a region and step size. Update Terrain Feature Processor to use this function to get the number of samples instead of computing num samples independently. Signed-off-by: amzn-sj --- .../Terrain/TerrainDataRequestBus.h | 4 ++++ .../Mocks/Terrain/MockTerrainDataRequestBus.h | 2 ++ .../TerrainFeatureProcessor.cpp | 24 +++++++++++-------- .../Source/TerrainSystem/TerrainSystem.cpp | 10 ++++++++ .../Code/Source/TerrainSystem/TerrainSystem.h | 4 ++++ 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 0d16bf3460..9379485646 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -161,6 +161,10 @@ namespace AzFramework SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const = 0; + //! Returns the number of samples for a given region and step size. + virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const = 0; + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the //! coordinates in the region. virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion, diff --git a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h index f3a6cc07b3..52ac28ef63 100644 --- a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h @@ -92,6 +92,8 @@ namespace UnitTest ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); MOCK_CONST_METHOD3( ProcessSurfacePointsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD2( + GetNumSamplesFromRegion, AZStd::pair(const AZ::Aabb&, const AZ::Vector2&)); MOCK_CONST_METHOD4( ProcessHeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); MOCK_CONST_METHOD4( diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp index ebc8a16fcb..4232a37264 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -208,12 +208,21 @@ namespace Terrain } int32_t xStart = aznumeric_cast(AZStd::ceilf(m_dirtyRegion.GetMin().GetX() / m_sampleSpacing)); - int32_t xEnd = aznumeric_cast(AZStd::floorf(m_dirtyRegion.GetMax().GetX() / m_sampleSpacing)) + 1; int32_t yStart = aznumeric_cast(AZStd::ceilf(m_dirtyRegion.GetMin().GetY() / m_sampleSpacing)); - int32_t yEnd = aznumeric_cast(AZStd::floorf(m_dirtyRegion.GetMax().GetY() / m_sampleSpacing)) + 1; - uint32_t updateWidth = xEnd - xStart; - uint32_t updateHeight = yEnd - yStart; + AZ::Vector2 stepSize(m_sampleSpacing); + AZ::Vector3 maxBound( + m_dirtyRegion.GetMax().GetX() + m_sampleSpacing, m_dirtyRegion.GetMax().GetY() + m_sampleSpacing, 0.0f); + AZ::Aabb region; + region.Set(m_dirtyRegion.GetMin(), maxBound); + + AZStd::pair numSamples; + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + numSamples, &AzFramework::Terrain::TerrainDataRequests::GetNumSamplesFromRegion, + region, stepSize); + + uint32_t updateWidth = numSamples.first; + uint32_t updateHeight = numSamples.second; AZStd::vector pixels; pixels.reserve(updateWidth * updateHeight); { @@ -238,14 +247,9 @@ namespace Terrain pixels.push_back(uint16Height); }; - AZ::Vector2 stepSize(m_sampleSpacing); - AZ::Vector3 maxBound( - m_dirtyRegion.GetMax().GetX() + m_sampleSpacing, m_dirtyRegion.GetMax().GetY() + m_sampleSpacing, 0.0f); - AZ::Aabb region; - region.Set(m_dirtyRegion.GetMin(), maxBound); AzFramework::Terrain::TerrainDataRequestBus::Broadcast( &AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, - region, stepSize, perPositionCallback,AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); + region, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); } if (m_heightmapImage) diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp index 2ecd13b5ad..4dfa03ed53 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp @@ -690,6 +690,16 @@ void TerrainSystem::ProcessSurfacePointsFromListOfVector2( } } +AZStd::pair TerrainSystem::GetNumSamplesFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const +{ + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + return AZStd::make_pair(numSamplesX, numSamplesY); +} + void TerrainSystem::ProcessHeightsFromRegion( const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h index 7c6e0cd91e..2296d48843 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -163,6 +163,10 @@ namespace Terrain AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const override; + //! Returns the number of samples for a given region and step size. + virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const override; + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the //! coordinates in the region. virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion, From c95845d45b3523092ac61fc4eab5c9199749af0d Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Wed, 19 Jan 2022 20:02:50 -0800 Subject: [PATCH 263/272] chore: replace isspace Signed-off-by: Michael Pollind --- .../Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp index e1f1a0f801..e89c46bce7 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp @@ -45,7 +45,7 @@ namespace AZ::Debug } for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i) { - if (!::isspace(processStatusView[i])) + if (processStatusView[i] != ' ') { return processStatusView[i] != '0'; } From c98d14ad924d2e0efe9eeff650b899cdeb204cda Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Thu, 20 Jan 2022 00:10:07 -0600 Subject: [PATCH 264/272] =?UTF-8?q?Atom=20Tools:=20Removing=20unnecessary?= =?UTF-8?q?=20modules,=20components,=20and=20dead=20code=20from=20ME=20?= =?UTF-8?q?=E2=80=A2=20Working=20toward=20creating=20a=20standalone=20appl?= =?UTF-8?q?ication=20template=20Removing=20application=20level=20modules?= =?UTF-8?q?=20and=20system=20components=20that=20make=20it=20difficult=20t?= =?UTF-8?q?o=20navigate=20the=20project=20and=20add=20a=20lot=20of=20boile?= =?UTF-8?q?rplate=20code=20=E2=80=A2=20Temporarily=20keeping=20viewport=20?= =?UTF-8?q?module=20and=20components=20because=20shutting=20down=20the=20a?= =?UTF-8?q?pplication=20deactivates=20module=20entities=20before=20system?= =?UTF-8?q?=20entities=20without=20respecting=20component=20service=20depe?= =?UTF-8?q?ndency=20order.=20This=20caused=20several=20RPI=20assets=20and?= =?UTF-8?q?=20names=20to=20leak=20because=20they=20were=20not=20being=20de?= =?UTF-8?q?stroyed=20in=20the=20correct=20order.=20=E2=80=A2=20Fixing=20in?= =?UTF-8?q?clude=20paths=20not=20referenced=20source=20folders=20=E2=80=A2?= =?UTF-8?q?=20Mostly=20cleanup=20and=20reorganization,=20no=20behavioral?= =?UTF-8?q?=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guthrie Adams --- .../Application/AtomToolsApplication.cpp | 4 + .../AtomToolsFrameworkSystemComponent.cpp | 6 +- .../DynamicProperty/DynamicProperty.cpp | 2 +- .../Code/Source/Inspector/InspectorWidget.cpp | 2 +- .../Tools/MaterialEditor/Code/CMakeLists.txt | 80 ++----------- .../Atom/Document/MaterialDocumentModule.h | 29 ----- .../Atom/Window/MaterialEditorWindowModule.h | 28 ----- .../Code/Source/Document/MaterialDocument.h | 7 +- .../Document/MaterialDocumentModule.cpp | 30 ----- .../Document/MaterialDocumentRequestBus.h | 0 .../Document/MaterialDocumentSettings.cpp | 2 +- .../Document/MaterialDocumentSettings.h | 0 .../MaterialDocumentSystemComponent.cpp | 85 -------------- .../MaterialDocumentSystemComponent.h | 41 ------- .../Code/Source/MaterialEditorApplication.cpp | 107 ++++++++++++++---- .../Code/Source/MaterialEditorApplication.h | 19 ++++ .../Viewport/InputController/Behavior.cpp | 5 +- .../InputController/DollyCameraBehavior.cpp | 4 +- .../InputController/DollyCameraBehavior.h | 2 +- .../Viewport/InputController/IdleBehavior.cpp | 2 +- .../Viewport/InputController/IdleBehavior.h | 2 +- .../MaterialEditorViewportInputController.cpp | 24 ++-- .../MaterialEditorViewportInputController.h | 4 +- ...MaterialEditorViewportInputControllerBus.h | 0 .../InputController/MoveCameraBehavior.cpp | 6 +- .../InputController/MoveCameraBehavior.h | 2 +- .../InputController/OrbitCameraBehavior.cpp | 2 +- .../InputController/OrbitCameraBehavior.h | 2 +- .../InputController/PanCameraBehavior.cpp | 8 +- .../InputController/PanCameraBehavior.h | 2 +- .../RotateEnvironmentBehavior.cpp | 2 +- .../RotateEnvironmentBehavior.h | 2 +- .../InputController/RotateModelBehavior.cpp | 2 +- .../InputController/RotateModelBehavior.h | 2 +- .../Viewport/MaterialViewportComponent.cpp | 17 +-- .../Viewport/MaterialViewportComponent.h | 4 +- .../Viewport/MaterialViewportModule.cpp | 2 +- .../Viewport/MaterialViewportModule.h | 0 .../MaterialViewportNotificationBus.h | 0 .../Viewport/MaterialViewportRenderer.cpp | 36 +++--- .../Viewport/MaterialViewportRenderer.h | 2 +- .../Viewport/MaterialViewportRequestBus.h | 0 .../Viewport/MaterialViewportSettings.cpp | 2 +- .../Viewport/MaterialViewportSettings.h | 0 .../Viewport/PerformanceMetrics.h | 0 .../Viewport/PerformanceMonitorComponent.cpp | 2 +- .../Viewport/PerformanceMonitorComponent.h | 5 +- .../Viewport/PerformanceMonitorRequestBus.h | 3 +- .../CreateMaterialDialog.cpp | 2 +- .../CreateMaterialDialog.h | 2 +- .../Source/Window/HelpDialog/HelpDialog.cpp | 4 +- .../Source/Window/HelpDialog/HelpDialog.h | 2 +- .../Source/Window/MaterialEditorWindow.cpp | 4 +- .../Window/MaterialEditorWindowComponent.cpp | 89 --------------- .../Window/MaterialEditorWindowComponent.h | 58 ---------- .../Window/MaterialEditorWindowModule.cpp | 38 ------- .../Window/MaterialEditorWindowSettings.cpp | 2 +- .../Window/MaterialEditorWindowSettings.h | 0 .../MaterialInspector/MaterialInspector.cpp | 2 +- .../MaterialInspector/MaterialInspector.h | 2 +- .../PerformanceMonitorWidget.cpp | 9 +- .../LightingPresetBrowserDialog.cpp | 2 +- .../LightingPresetBrowserDialog.h | 2 +- .../ModelPresetBrowserDialog.cpp | 2 +- .../ModelPresetBrowserDialog.h | 2 +- .../Window/SettingsDialog/SettingsWidget.h | 2 +- .../Window/ToolBar/LightingPresetComboBox.cpp | 6 +- .../Window/ToolBar/LightingPresetComboBox.h | 2 +- .../Window/ToolBar/MaterialEditorToolBar.cpp | 8 +- .../Window/ToolBar/MaterialEditorToolBar.h | 2 +- .../Window/ToolBar/ModelPresetComboBox.cpp | 6 +- .../Window/ToolBar/ModelPresetComboBox.h | 2 +- .../ViewportSettingsInspector.cpp | 4 +- .../ViewportSettingsInspector.h | 6 +- .../Code/materialeditor_files.cmake | 82 ++++++++++++++ .../Code/materialeditordocument_files.cmake | 19 ---- .../Code/materialeditorviewport_files.cmake | 46 -------- .../Code/materialeditorwindow_files.cmake | 52 --------- .../ShaderManagementConsoleWindowComponent.h | 12 +- .../ShaderManagementConsoleToolBar.cpp | 4 +- 80 files changed, 327 insertions(+), 736 deletions(-) delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentModule.h delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowModule.h delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentModule.cpp rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Document/MaterialDocumentRequestBus.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Document/MaterialDocumentSettings.h (100%) delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/InputController/MaterialEditorViewportInputControllerBus.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/MaterialViewportModule.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/MaterialViewportNotificationBus.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/MaterialViewportRequestBus.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/MaterialViewportSettings.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/PerformanceMetrics.h (100%) rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Viewport/PerformanceMonitorRequestBus.h (95%) delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.h delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp rename Gems/Atom/Tools/MaterialEditor/Code/{Include/Atom => Source}/Window/MaterialEditorWindowSettings.h (100%) delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 51e8bc4dda..7b6be61050 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -158,6 +158,7 @@ namespace AtomToolsFramework components.end(), { azrtti_typeid(), + azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), @@ -187,6 +188,9 @@ namespace AtomToolsFramework AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast( &AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); + AzToolsFramework::SourceControlConnectionRequestBus::Broadcast( + &AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, true); + if (!AZ::RPI::RPISystemInterface::Get()->IsInitialized()) { AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AtomToolsFrameworkSystemComponent.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AtomToolsFrameworkSystemComponent.cpp index a8481ef5bd..adba947092 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AtomToolsFrameworkSystemComponent.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/AtomToolsFrameworkSystemComponent.cpp @@ -30,7 +30,7 @@ namespace AtomToolsFramework { ec->Class("AtomToolsFrameworkSystemComponent", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } @@ -39,12 +39,12 @@ namespace AtomToolsFramework void AtomToolsFrameworkSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("AtomToolsFrameworkSystemService")); + provided.push_back(AZ_CRC_CE("AtomToolsFrameworkSystemService")); } void AtomToolsFrameworkSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("AtomToolsFrameworkSystemService")); + incompatible.push_back(AZ_CRC_CE("AtomToolsFrameworkSystemService")); } void AtomToolsFrameworkSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp index d4599b68b7..830f71933c 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/DynamicProperty/DynamicProperty.cpp @@ -160,7 +160,7 @@ namespace AtomToolsFramework ApplyRangeEditDataAttributes(); break; case DynamicPropertyType::Color: - AddEditDataAttribute(AZ_CRC("ColorEditorConfiguration", 0xc8b9510e), AZ::RPI::ColorUtils::GetRgbEditorConfig()); + AddEditDataAttribute(AZ_CRC_CE("ColorEditorConfiguration"), AZ::RPI::ColorUtils::GetRgbEditorConfig()); break; case DynamicPropertyType::Enum: m_editData.m_elementId = AZ::Edit::UIHandlers::ComboBox; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp index fbe188364a..89f7e9d3bf 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include namespace AtomToolsFramework { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt b/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt index 1d9295f9b3..5a0d153578 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt +++ b/Gems/Atom/Tools/MaterialEditor/Code/CMakeLists.txt @@ -18,78 +18,12 @@ if(NOT PAL_TRAIT_ATOM_MATERIAL_EDITOR_APPLICATION_SUPPORTED) return() endif() - -ly_add_target( - NAME MaterialEditor.Document STATIC - NAMESPACE Gem - AUTOMOC - FILES_CMAKE - materialeditordocument_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PUBLIC - Gem::AtomToolsFramework.Static - Gem::AtomToolsFramework.Editor - Gem::Atom_RPI.Edit - Gem::Atom_RPI.Public - Gem::Atom_RHI.Reflect -) - -ly_add_target( - NAME MaterialEditor.Window STATIC - NAMESPACE Gem - AUTOMOC - AUTOUIC - AUTORCC - FILES_CMAKE - materialeditorwindow_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PUBLIC - Gem::AtomToolsFramework.Static - Gem::AtomToolsFramework.Editor - Gem::Atom_RPI.Public - Gem::Atom_Feature_Common.Public -) - -ly_add_target( - NAME MaterialEditor.Viewport STATIC - NAMESPACE Gem - AUTOMOC - AUTOUIC - FILES_CMAKE - materialeditorviewport_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - Source - Public - Include - BUILD_DEPENDENCIES - PUBLIC - Gem::AtomToolsFramework.Static - Gem::AtomToolsFramework.Editor - Gem::Atom_RHI.Public - Gem::Atom_RPI.Public - Gem::Atom_Feature_Common.Static - Gem::Atom_Component_DebugCamera.Static - Gem::AtomLyIntegration_CommonFeatures.Static -) - ly_add_target( NAME MaterialEditor EXECUTABLE NAMESPACE Gem AUTOMOC + AUTOUIC + AUTORCC FILES_CMAKE materialeditor_files.cmake ${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake @@ -106,9 +40,13 @@ ly_add_target( PRIVATE Gem::AtomToolsFramework.Static Gem::AtomToolsFramework.Editor - Gem::MaterialEditor.Window - Gem::MaterialEditor.Viewport - Gem::MaterialEditor.Document + Gem::Atom_RHI.Public + Gem::Atom_RHI.Reflect + Gem::Atom_RPI.Edit + Gem::Atom_RPI.Public + Gem::Atom_Feature_Common.Public + Gem::Atom_Component_DebugCamera.Static + Gem::AtomLyIntegration_CommonFeatures.Static RUNTIME_DEPENDENCIES Gem::AtomToolsFramework.Editor Gem::EditorPythonBindings.Editor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentModule.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentModule.h deleted file mode 100644 index 0813f8cab8..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentModule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace MaterialEditor -{ - //! Entry point for Material Editor Document library. This module is responsible for registering dependencies and logic needed - //! for the Material Document API - class MaterialDocumentModule - : public AZ::Module - { - public: - AZ_RTTI(MaterialDocumentModule, "{81D7A170-9284-4DE9-8D92-B6B94E8A2BDF}", AZ::Module); - AZ_CLASS_ALLOCATOR(MaterialDocumentModule, AZ::SystemAllocator, 0); - - MaterialDocumentModule(); - - //! Add required SystemComponents to the SystemEntity. - AZ::ComponentTypeList GetRequiredSystemComponents() const override; - }; -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowModule.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowModule.h deleted file mode 100644 index 611a993084..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowModule.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace MaterialEditor -{ - //! Entry point for Material Editor Window library. - class MaterialEditorWindowModule - : public AZ::Module - { - public: - AZ_RTTI(MaterialEditorWindowModule, "{57D6239C-AE03-4ED8-9125-35C5B1625503}", AZ::Module); - AZ_CLASS_ALLOCATOR(MaterialEditorWindowModule, AZ::SystemAllocator, 0); - - MaterialEditorWindowModule(); - - //! Add required SystemComponents to the SystemEntity. - AZ::ComponentTypeList GetRequiredSystemComponents() const override; - }; -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.h index ceb3190f26..c975824e22 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.h @@ -7,18 +7,17 @@ */ #pragma once -#include #include #include -#include +#include #include -#include #include #include #include -#include +#include #include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentModule.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentModule.cpp deleted file mode 100644 index c721798cfd..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentModule.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include - -namespace MaterialEditor -{ - MaterialDocumentModule::MaterialDocumentModule() - { - // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. - m_descriptors.insert(m_descriptors.end(), { - MaterialDocumentSystemComponent::CreateDescriptor(), - }); - } - - AZ::ComponentTypeList MaterialDocumentModule::GetRequiredSystemComponents() const - { - return AZ::ComponentTypeList{ - azrtti_typeid(), - azrtti_typeid(), - }; - } -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentRequestBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentRequestBus.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentRequestBus.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentRequestBus.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp index 4823b8c67c..256497de54 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp @@ -6,9 +6,9 @@ * */ -#include #include #include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp deleted file mode 100644 index 9302b5ac5c..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace MaterialEditor -{ - void MaterialDocumentSystemComponent::Reflect(AZ::ReflectContext* context) - { - MaterialDocumentSettings::Reflect(context); - - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0); - - if (AZ::EditContext* ec = serialize->GetEditContext()) - { - ec->Class("MaterialDocumentSystemComponent", "Tool for editing Atom material files") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; - } - } - - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("MaterialDocumentRequestBus") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "materialeditor") - ; - } - } - - void MaterialDocumentSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC_CE("AtomToolsDocumentSystemService")); - required.push_back(AZ_CRC_CE("AssetProcessorToolsConnection")); - required.push_back(AZ_CRC_CE("AssetDatabaseService")); - required.push_back(AZ_CRC_CE("PropertyManagerService")); - required.push_back(AZ_CRC_CE("RPISystem")); - } - - void MaterialDocumentSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC_CE("MaterialDocumentSystemService")); - } - - void MaterialDocumentSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC_CE("MaterialDocumentSystemService")); - } - - void MaterialDocumentSystemComponent::Init() - { - } - - void MaterialDocumentSystemComponent::Activate() - { - AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( - &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Handler::RegisterDocumentType, - []() - { - return aznew MaterialDocument(); - }); - } - - void MaterialDocumentSystemComponent::Deactivate() - { - } -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h deleted file mode 100644 index af19956088..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace MaterialEditor -{ - //! MaterialDocumentSystemComponent - class MaterialDocumentSystemComponent - : public AZ::Component - { - public: - AZ_COMPONENT(MaterialDocumentSystemComponent, "{E011DA51-855D-45FA-87A3-1C1CD6379091}"); - - MaterialDocumentSystemComponent() = default; - ~MaterialDocumentSystemComponent() = default; - MaterialDocumentSystemComponent(const MaterialDocumentSystemComponent&) = delete; - MaterialDocumentSystemComponent& operator=(const MaterialDocumentSystemComponent&) = delete; - - static void Reflect(AZ::ReflectContext* context); - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - private: - //////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - }; -} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 15a5ff1715..2e64740057 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -6,22 +6,73 @@ * */ -#include -#include -#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include +#include + +void InitMaterialEditorResources() +{ + // Must register qt resources from other modules + Q_INIT_RESOURCE(MaterialEditor); + Q_INIT_RESOURCE(InspectorWidget); + Q_INIT_RESOURCE(AtomToolsAssetBrowser); +} namespace MaterialEditor { - //! This function returns the build system target name of "MaterialEditor" - AZStd::string MaterialEditorApplication::GetBuildTargetName() const + MaterialEditorApplication::MaterialEditorApplication(int* argc, char*** argv) + : Base(argc, argv) { -#if !defined(LY_CMAKE_TARGET) -#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" -#endif - return AZStd::string{ LY_CMAKE_TARGET }; + InitMaterialEditorResources(); + + QApplication::setApplicationName("O3DE Material Editor"); + + // The settings registry has been created at this point, so add the CMake target + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( + *AZ::SettingsRegistry::Get(), GetBuildTargetName()); + + AzToolsFramework::EditorWindowRequestBus::Handler::BusConnect(); + AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusConnect(); + } + + MaterialEditorApplication::~MaterialEditorApplication() + { + AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusDisconnect(); + AzToolsFramework::EditorWindowRequestBus::Handler::BusDisconnect(); + m_window.reset(); + } + + void MaterialEditorApplication::Reflect(AZ::ReflectContext* context) + { + Base::Reflect(context); + MaterialDocumentSettings::Reflect(context); + MaterialEditorWindowSettings::Reflect(context); + + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->EBus("MaterialDocumentRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "Editor") + ->Attribute(AZ::Script::Attributes::Module, "materialeditor") + ; + } + } + + void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) + { + Base::CreateStaticModules(outModules); + outModules.push_back(aznew MaterialViewportModule); } const char* MaterialEditorApplication::GetCurrentConfigurationName() const @@ -35,26 +86,42 @@ namespace MaterialEditor #endif } - MaterialEditorApplication::MaterialEditorApplication(int* argc, char*** argv) - : Base(argc, argv) + void MaterialEditorApplication::StartCommon(AZ::Entity* systemEntity) { - QApplication::setApplicationName("O3DE Material Editor"); + Base::StartCommon(systemEntity); - // The settings registry has been created at this point, so add the CMake target - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( - *AZ::SettingsRegistry::Get(), GetBuildTargetName()); + AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( + &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Handler::RegisterDocumentType, + []() { return aznew MaterialDocument(); }); } - void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) + AZStd::string MaterialEditorApplication::GetBuildTargetName() const { - Base::CreateStaticModules(outModules); - outModules.push_back(aznew MaterialDocumentModule); - outModules.push_back(aznew MaterialViewportModule); - outModules.push_back(aznew MaterialEditorWindowModule); +#if !defined(LY_CMAKE_TARGET) +#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" +#endif + //! Returns the build system target name of "MaterialEditor" + return AZStd::string{ LY_CMAKE_TARGET }; } AZStd::vector MaterialEditorApplication::GetCriticalAssetFilters() const { return AZStd::vector({ "passes/", "config/", "MaterialEditor/" }); } + + void MaterialEditorApplication::CreateMainWindow() + { + m_materialEditorBrowserInteractions.reset(aznew MaterialEditorBrowserInteractions); + m_window.reset(aznew MaterialEditorWindow); + } + + void MaterialEditorApplication::DestroyMainWindow() + { + m_window.reset(); + } + + QWidget* MaterialEditorApplication::GetAppMainWindow() + { + return m_window.get(); + } } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index bf2e6f6ca1..060353e396 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -9,6 +9,10 @@ #pragma once #include +#include +#include +#include +#include namespace MaterialEditor { @@ -16,6 +20,8 @@ namespace MaterialEditor class MaterialEditorApplication : public AtomToolsFramework::AtomToolsDocumentApplication + , private AzToolsFramework::EditorWindowRequestBus::Handler + , private AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler { public: AZ_TYPE_INFO(MaterialEditor::MaterialEditorApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); @@ -23,13 +29,26 @@ namespace MaterialEditor using Base = AtomToolsFramework::AtomToolsDocumentApplication; MaterialEditorApplication(int* argc, char*** argv); + ~MaterialEditorApplication(); // AzFramework::Application overrides... + void Reflect(AZ::ReflectContext* context) override; void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; + void StartCommon(AZ::Entity* systemEntity) override; // AtomToolsFramework::AtomToolsApplication overrides... AZStd::string GetBuildTargetName() const override; AZStd::vector GetCriticalAssetFilters() const override; + + // AtomToolsMainWindowFactoryRequestBus::Handler overrides... + void CreateMainWindow() override; + void DestroyMainWindow() override; + + // AzToolsFramework::EditorWindowRequests::Bus::Handler + QWidget* GetAppMainWindow() override; + + AZStd::unique_ptr m_window; + AZStd::unique_ptr m_materialEditorBrowserInteractions; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp index 321b79ba87..a843c4965c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp @@ -6,10 +6,9 @@ * */ -#include #include - -#include +#include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.cpp index c0326bce2a..c69884c5c0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.cpp @@ -6,11 +6,11 @@ * */ +#include #include #include -#include +#include #include -#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.h index be226e5fde..5debfc4dd1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/DollyCameraBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.cpp index 64e2fe1fdc..0cd062d86d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.cpp @@ -6,7 +6,7 @@ * */ -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.h index 3eec594da2..16543a890d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/IdleBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp index 1784405ffa..ced59f1bf5 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp @@ -9,30 +9,30 @@ #include #include -#include #include #include +#include +#include #include #include -#include #include #include -#include +#include #include #include #include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h index b488c3bf29..a68666f06d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputControllerBus.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputControllerBus.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.cpp index a449d6f7ff..80b3409f57 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.cpp @@ -6,10 +6,10 @@ * */ -#include #include -#include -#include +#include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.h index b37350423f..ea0850ba16 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MoveCameraBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.cpp index 4d8a5b9343..1d93e4eafe 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.cpp @@ -7,8 +7,8 @@ */ #include -#include #include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.h index 98240aef96..a312d22e73 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/OrbitCameraBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp index 62839be13c..2b036a1319 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp @@ -6,11 +6,11 @@ * */ -#include -#include #include -#include -#include +#include +#include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.h index de8e2c3c43..93233511f0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.cpp index 17fb3f3e52..894841becd 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.h index 80989df520..56c7a5190a 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateEnvironmentBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace AZ { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.cpp index 032b412d6e..ed09ae8fa3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.h index 7653e10014..e2c20ab5fd 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/RotateModelBehavior.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index 9cf714b40e..b2f1cdc9c1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -9,19 +9,19 @@ #include #include #include -#include -#include #include #include #include #include #include +#include #include #include -#include #include #include #include +#include +#include namespace MaterialEditor { @@ -42,7 +42,7 @@ namespace MaterialEditor { editContext->Class("MaterialViewport", "Manages configurations for lighting and models displayed in the viewport") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } @@ -103,18 +103,19 @@ namespace MaterialEditor void MaterialViewportComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) { - required.push_back(AZ_CRC("PerformanceMonitorService", 0x6a44241a)); - required.push_back(AZ_CRC("AtomImageBuilderService", 0x76ded592)); + required.push_back(AZ_CRC_CE("RPISystem")); + required.push_back(AZ_CRC_CE("AssetDatabaseService")); + required.push_back(AZ_CRC_CE("PerformanceMonitorService")); } void MaterialViewportComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("MaterialViewportService", 0xed9b44d7)); + provided.push_back(AZ_CRC_CE("MaterialViewportService")); } void MaterialViewportComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("MaterialViewportService", 0xed9b44d7)); + incompatible.push_back(AZ_CRC_CE("MaterialViewportService")); } void MaterialViewportComponent::Init() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h index 68668bd804..7209dfa489 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h @@ -12,11 +12,11 @@ #include #include #include -#include -#include #include #include #include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.cpp index 7c3bc208ff..01a13519fb 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.cpp @@ -6,8 +6,8 @@ * */ -#include #include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportModule.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportModule.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportModule.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportNotificationBus.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportNotificationBus.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp index 409674f0bc..478fb92c55 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp @@ -8,51 +8,51 @@ #undef RC_INVOKED -#include #include +#include -#include #include +#include #include #include -#include +#include +#include #include #include #include #include -#include -#include +#include #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include -#include #include #include -#include -#include -#include -#include #include +#include #include #include -#include #include -#include +#include #include -#include +#include #include #include +#include -#include +#include +#include +#include +#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.h index c6380ddc00..35b7965a2e 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.h @@ -11,12 +11,12 @@ #include #include #include -#include #include #include #include #include #include +#include namespace AZ { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportRequestBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRequestBus.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportRequestBus.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRequestBus.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp index c2c35119c2..0f08716407 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp @@ -6,9 +6,9 @@ * */ -#include #include #include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/PerformanceMetrics.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMetrics.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/PerformanceMetrics.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMetrics.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp index 563b2754df..c8f12480b5 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.cpp @@ -31,7 +31,7 @@ namespace MaterialEditor void PerformanceMonitorComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("PerformanceMonitorService", 0x6a44241a)); + provided.push_back(AZ_CRC_CE("PerformanceMonitorService")); } void PerformanceMonitorComponent::Init() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.h index 88a6827bd1..3045bf9533 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorComponent.h @@ -8,11 +8,10 @@ #pragma once +#include #include #include - -#include -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/PerformanceMonitorRequestBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorRequestBus.h similarity index 95% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/PerformanceMonitorRequestBus.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorRequestBus.h index ae09064766..6001787d99 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/PerformanceMonitorRequestBus.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/PerformanceMonitorRequestBus.h @@ -8,8 +8,7 @@ #pragma once #include - -#include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp index 31ca873c48..0e6cf565e3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp @@ -6,7 +6,6 @@ * */ -#include #include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.h index 3453d8347c..ed3cb2773b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.h @@ -10,7 +10,7 @@ #include -#include +#include #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.cpp index 3ad41e4803..3e8cf19539 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.cpp @@ -6,7 +6,7 @@ * */ -#include +#include namespace MaterialEditor { @@ -20,4 +20,4 @@ namespace MaterialEditor HelpDialog::~HelpDialog() = default; } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.h index 5cca57ad2d..ec5b756df4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/HelpDialog/HelpDialog.h @@ -13,7 +13,7 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include -#include +#include AZ_POP_DISABLE_WARNING #endif diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 44adda432d..e1f8e713d4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -6,19 +6,19 @@ * */ -#include #include #include #include -#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp deleted file mode 100644 index 5359ba8e53..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace MaterialEditor -{ - void MaterialEditorWindowComponent::Reflect(AZ::ReflectContext* context) - { - MaterialEditorWindowSettings::Reflect(context); - - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0); - } - } - - void MaterialEditorWindowComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC_CE("AssetBrowserService")); - required.push_back(AZ_CRC_CE("PropertyManagerService")); - required.push_back(AZ_CRC_CE("SourceControlService")); - required.push_back(AZ_CRC_CE("AtomToolsMainWindowSystemService")); - } - - void MaterialEditorWindowComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC_CE("MaterialEditorWindowService")); - } - - void MaterialEditorWindowComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC_CE("MaterialEditorWindowService")); - } - - void MaterialEditorWindowComponent::Init() - { - } - - void MaterialEditorWindowComponent::Activate() - { - AzToolsFramework::EditorWindowRequestBus::Handler::BusConnect(); - AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusConnect(); - AzToolsFramework::SourceControlConnectionRequestBus::Broadcast(&AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, true); - } - - void MaterialEditorWindowComponent::Deactivate() - { - AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusDisconnect(); - AzToolsFramework::EditorWindowRequestBus::Handler::BusDisconnect(); - - m_window.reset(); - } - - void MaterialEditorWindowComponent::CreateMainWindow() - { - m_materialEditorBrowserInteractions.reset(aznew MaterialEditorBrowserInteractions); - - m_window.reset(aznew MaterialEditorWindow); - } - - void MaterialEditorWindowComponent::DestroyMainWindow() - { - m_window.reset(); - } - - QWidget* MaterialEditorWindowComponent::GetAppMainWindow() - { - return m_window.get(); - } - -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.h deleted file mode 100644 index 87f6160089..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -#include -#include -#include - -namespace MaterialEditor -{ - //! MaterialEditorWindowComponent is the entry point for the Material Editor gem user interface, and is mainly - //! used for initialization and registration of other classes, including MaterialEditorWindow. - class MaterialEditorWindowComponent - : public AZ::Component - , private AzToolsFramework::EditorWindowRequestBus::Handler - , private AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler - { - public: - AZ_COMPONENT(MaterialEditorWindowComponent, "{03976F19-3C74-49FE-A15F-7D3CADBA616C}"); - - static void Reflect(AZ::ReflectContext* context); - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - private: - //////////////////////////////////////////////////////////////////////// - // AtomToolsMainWindowFactoryRequestBus::Handler overrides... - void CreateMainWindow() override; - void DestroyMainWindow() override; - //////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // AzToolsFramework::EditorWindowRequests::Bus::Handler - QWidget* GetAppMainWindow() override; - ////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - AZStd::unique_ptr m_window; - AZStd::unique_ptr m_materialEditorBrowserInteractions; - }; -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp deleted file mode 100644 index 1562d11647..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowModule.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -void InitMaterialEditorResources() -{ - //Must register qt resources from other modules - Q_INIT_RESOURCE(MaterialEditor); - Q_INIT_RESOURCE(InspectorWidget); - Q_INIT_RESOURCE(AtomToolsAssetBrowser); -} - -namespace MaterialEditor -{ - MaterialEditorWindowModule::MaterialEditorWindowModule() - { - InitMaterialEditorResources(); - - // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. - m_descriptors.insert(m_descriptors.end(), { - MaterialEditorWindowComponent::CreateDescriptor(), - }); - } - - AZ::ComponentTypeList MaterialEditorWindowModule::GetRequiredSystemComponents() const - { - return AZ::ComponentTypeList{ - azrtti_typeid(), - }; - } -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp index 71c71e8b75..5ab17d7b26 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp @@ -6,9 +6,9 @@ * */ -#include #include #include +#include namespace MaterialEditor { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.h similarity index 100% rename from Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h rename to Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp index e99f456653..7790b9bef5 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp @@ -6,7 +6,6 @@ * */ -#include #include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h index a3b98e13d2..a4cd2b7616 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h @@ -9,12 +9,12 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include #include #include #include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp index 940790eb0a..8492ce5f1f 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp @@ -6,10 +6,9 @@ * */ -#include - -#include -#include +#include +#include +#include #include @@ -55,4 +54,4 @@ namespace MaterialEditor } } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp index f8ad038a85..cc7a851429 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h index f9d455d915..68b52b3a98 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h @@ -10,8 +10,8 @@ #if !defined(Q_MOC_RUN) #include -#include #include +#include #endif #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp index f5a1677462..e16b61d214 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp @@ -7,9 +7,9 @@ */ #include -#include #include #include +#include #include namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h index 67da7db262..a169d3053b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h @@ -10,8 +10,8 @@ #if !defined(Q_MOC_RUN) #include -#include #include +#include #endif #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h index fea98eeda1..e7c655ee21 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h @@ -9,10 +9,10 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include #include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.cpp index e0bb59cb82..20229cad37 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.cpp @@ -6,9 +6,9 @@ * */ -#include -#include #include +#include +#include namespace MaterialEditor { @@ -102,4 +102,4 @@ namespace MaterialEditor } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.h index 4c452dfb5b..f39b856085 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/LightingPresetComboBox.h @@ -10,7 +10,7 @@ #if !defined(Q_MOC_RUN) #include -#include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp index 10442e0c27..25877f910d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp @@ -6,21 +6,21 @@ * */ -#include -#include -#include #include +#include +#include +#include #include #include #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include +#include #include #include #include #include -#include AZ_POP_DISABLE_WARNING namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.h index c25b90eb80..056fb3ba80 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.h @@ -11,7 +11,7 @@ #if !defined(Q_MOC_RUN) #include #include -#include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.cpp index 1e8bfec485..1c9bd36be4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.cpp @@ -6,9 +6,9 @@ * */ -#include -#include #include +#include +#include namespace MaterialEditor { @@ -102,4 +102,4 @@ namespace MaterialEditor } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.h index e315854d75..bb71cec25b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/ModelPresetComboBox.h @@ -10,7 +10,7 @@ #if !defined(Q_MOC_RUN) #include -#include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index 613762c10a..512059f1f6 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -7,10 +7,10 @@ */ #include -#include #include #include #include +#include #include #include #include @@ -376,4 +376,4 @@ namespace MaterialEditor } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h index 6299ddb1f2..464a55aa7f 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h @@ -12,11 +12,11 @@ #include #include #include -#include -#include -#include #include #include +#include +#include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake index d4c4364ba7..9d1e2b22f8 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake @@ -10,4 +10,86 @@ set(FILES Source/main.cpp Source/MaterialEditorApplication.cpp Source/MaterialEditorApplication.h + + Source/Document/MaterialDocumentRequestBus.h + Source/Document/MaterialDocumentSettings.h + Source/Document/MaterialDocument.cpp + Source/Document/MaterialDocument.h + Source/Document/MaterialDocumentSettings.cpp + + Source/Viewport/MaterialViewportModule.h + Source/Viewport/MaterialViewportModule.cpp + Source/Viewport/InputController/MaterialEditorViewportInputControllerBus.h + Source/Viewport/MaterialViewportSettings.h + Source/Viewport/MaterialViewportRequestBus.h + Source/Viewport/MaterialViewportNotificationBus.h + Source/Viewport/PerformanceMetrics.h + Source/Viewport/PerformanceMonitorRequestBus.h + Source/Viewport/InputController/MaterialEditorViewportInputController.cpp + Source/Viewport/InputController/MaterialEditorViewportInputController.h + Source/Viewport/InputController/Behavior.cpp + Source/Viewport/InputController/Behavior.h + Source/Viewport/InputController/DollyCameraBehavior.cpp + Source/Viewport/InputController/DollyCameraBehavior.h + Source/Viewport/InputController/IdleBehavior.cpp + Source/Viewport/InputController/IdleBehavior.h + Source/Viewport/InputController/MoveCameraBehavior.cpp + Source/Viewport/InputController/MoveCameraBehavior.h + Source/Viewport/InputController/PanCameraBehavior.cpp + Source/Viewport/InputController/PanCameraBehavior.h + Source/Viewport/InputController/OrbitCameraBehavior.cpp + Source/Viewport/InputController/OrbitCameraBehavior.h + Source/Viewport/InputController/RotateEnvironmentBehavior.cpp + Source/Viewport/InputController/RotateEnvironmentBehavior.h + Source/Viewport/InputController/RotateModelBehavior.cpp + Source/Viewport/InputController/RotateModelBehavior.h + Source/Viewport/MaterialViewportSettings.cpp + Source/Viewport/MaterialViewportComponent.cpp + Source/Viewport/MaterialViewportComponent.h + Source/Viewport/MaterialViewportWidget.cpp + Source/Viewport/MaterialViewportWidget.h + Source/Viewport/MaterialViewportWidget.ui + Source/Viewport/MaterialViewportRenderer.cpp + Source/Viewport/MaterialViewportRenderer.h + Source/Viewport/PerformanceMonitorComponent.cpp + Source/Viewport/PerformanceMonitorComponent.h + + Source/Window/MaterialEditorWindowSettings.h + Source/Window/MaterialEditorBrowserInteractions.h + Source/Window/MaterialEditorBrowserInteractions.cpp + Source/Window/MaterialEditorWindow.h + Source/Window/MaterialEditorWindow.cpp + Source/Window/MaterialEditorWindowSettings.cpp + Source/Window/MaterialEditor.qrc + Source/Window/MaterialEditor.qss + Source/Window/SettingsDialog/SettingsDialog.cpp + Source/Window/SettingsDialog/SettingsDialog.h + Source/Window/SettingsDialog/SettingsWidget.cpp + Source/Window/SettingsDialog/SettingsWidget.h + Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp + Source/Window/CreateMaterialDialog/CreateMaterialDialog.h + Source/Window/CreateMaterialDialog/CreateMaterialDialog.ui + Source/Window/PresetBrowserDialogs/PresetBrowserDialog.cpp + Source/Window/PresetBrowserDialogs/PresetBrowserDialog.h + Source/Window/PresetBrowserDialogs/PresetBrowserDialog.ui + Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp + Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h + Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp + Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h + Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp + Source/Window/PerformanceMonitor/PerformanceMonitorWidget.h + Source/Window/PerformanceMonitor/PerformanceMonitorWidget.ui + Source/Window/ToolBar/MaterialEditorToolBar.h + Source/Window/ToolBar/MaterialEditorToolBar.cpp + Source/Window/ToolBar/ModelPresetComboBox.h + Source/Window/ToolBar/ModelPresetComboBox.cpp + Source/Window/ToolBar/LightingPresetComboBox.h + Source/Window/ToolBar/LightingPresetComboBox.cpp + Source/Window/MaterialInspector/MaterialInspector.h + Source/Window/MaterialInspector/MaterialInspector.cpp + Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h + Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp + Source/Window/HelpDialog/HelpDialog.h + Source/Window/HelpDialog/HelpDialog.cpp + Source/Window/HelpDialog/HelpDialog.ui ) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake deleted file mode 100644 index d86dd03749..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - Include/Atom/Document/MaterialDocumentModule.h - Include/Atom/Document/MaterialDocumentRequestBus.h - Include/Atom/Document/MaterialDocumentSettings.h - Source/Document/MaterialDocumentModule.cpp - Source/Document/MaterialDocumentSystemComponent.cpp - Source/Document/MaterialDocumentSystemComponent.h - Source/Document/MaterialDocument.cpp - Source/Document/MaterialDocument.h - Source/Document/MaterialDocumentSettings.cpp -) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake deleted file mode 100644 index ba34cabd90..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h - Include/Atom/Viewport/MaterialViewportModule.h - Include/Atom/Viewport/MaterialViewportSettings.h - Include/Atom/Viewport/MaterialViewportRequestBus.h - Include/Atom/Viewport/MaterialViewportNotificationBus.h - Include/Atom/Viewport/PerformanceMetrics.h - Include/Atom/Viewport/PerformanceMonitorRequestBus.h - Source/Viewport/InputController/MaterialEditorViewportInputController.cpp - Source/Viewport/InputController/MaterialEditorViewportInputController.h - Source/Viewport/InputController/Behavior.cpp - Source/Viewport/InputController/Behavior.h - Source/Viewport/InputController/DollyCameraBehavior.cpp - Source/Viewport/InputController/DollyCameraBehavior.h - Source/Viewport/InputController/IdleBehavior.cpp - Source/Viewport/InputController/IdleBehavior.h - Source/Viewport/InputController/MoveCameraBehavior.cpp - Source/Viewport/InputController/MoveCameraBehavior.h - Source/Viewport/InputController/PanCameraBehavior.cpp - Source/Viewport/InputController/PanCameraBehavior.h - Source/Viewport/InputController/OrbitCameraBehavior.cpp - Source/Viewport/InputController/OrbitCameraBehavior.h - Source/Viewport/InputController/RotateEnvironmentBehavior.cpp - Source/Viewport/InputController/RotateEnvironmentBehavior.h - Source/Viewport/InputController/RotateModelBehavior.cpp - Source/Viewport/InputController/RotateModelBehavior.h - Source/Viewport/MaterialViewportModule.cpp - Source/Viewport/MaterialViewportSettings.cpp - Source/Viewport/MaterialViewportComponent.cpp - Source/Viewport/MaterialViewportComponent.h - Source/Viewport/MaterialViewportWidget.cpp - Source/Viewport/MaterialViewportWidget.h - Source/Viewport/MaterialViewportWidget.ui - Source/Viewport/MaterialViewportRenderer.cpp - Source/Viewport/MaterialViewportRenderer.h - Source/Viewport/PerformanceMonitorComponent.cpp - Source/Viewport/PerformanceMonitorComponent.h -) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake deleted file mode 100644 index 3d21e71294..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. -# For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - Include/Atom/Window/MaterialEditorWindowModule.h - Include/Atom/Window/MaterialEditorWindowSettings.h - Source/Window/MaterialEditorBrowserInteractions.h - Source/Window/MaterialEditorBrowserInteractions.cpp - Source/Window/MaterialEditorWindow.h - Source/Window/MaterialEditorWindow.cpp - Source/Window/MaterialEditorWindowModule.cpp - Source/Window/MaterialEditorWindowSettings.cpp - Source/Window/MaterialEditor.qrc - Source/Window/MaterialEditor.qss - Source/Window/MaterialEditorWindowComponent.h - Source/Window/MaterialEditorWindowComponent.cpp - Source/Window/SettingsDialog/SettingsDialog.cpp - Source/Window/SettingsDialog/SettingsDialog.h - Source/Window/SettingsDialog/SettingsWidget.cpp - Source/Window/SettingsDialog/SettingsWidget.h - Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp - Source/Window/CreateMaterialDialog/CreateMaterialDialog.h - Source/Window/CreateMaterialDialog/CreateMaterialDialog.ui - Source/Window/PresetBrowserDialogs/PresetBrowserDialog.cpp - Source/Window/PresetBrowserDialogs/PresetBrowserDialog.h - Source/Window/PresetBrowserDialogs/PresetBrowserDialog.ui - Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp - Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h - Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp - Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h - Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp - Source/Window/PerformanceMonitor/PerformanceMonitorWidget.h - Source/Window/PerformanceMonitor/PerformanceMonitorWidget.ui - Source/Window/ToolBar/MaterialEditorToolBar.h - Source/Window/ToolBar/MaterialEditorToolBar.cpp - Source/Window/ToolBar/ModelPresetComboBox.h - Source/Window/ToolBar/ModelPresetComboBox.cpp - Source/Window/ToolBar/LightingPresetComboBox.h - Source/Window/ToolBar/LightingPresetComboBox.cpp - Source/Window/MaterialInspector/MaterialInspector.h - Source/Window/MaterialInspector/MaterialInspector.cpp - Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h - Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp - Source/Window/HelpDialog/HelpDialog.h - Source/Window/HelpDialog/HelpDialog.cpp - Source/Window/HelpDialog/HelpDialog.ui -) diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowComponent.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowComponent.h index 9b43babd9a..aab0f7ce37 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowComponent.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindowComponent.h @@ -8,15 +8,15 @@ #pragma once +#include +#include +#include + #include #include -#include - -#include -#include -#include -#include +#include +#include namespace ShaderManagementConsole { diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ToolBar/ShaderManagementConsoleToolBar.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ToolBar/ShaderManagementConsoleToolBar.cpp index d65ac7048d..5699713240 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ToolBar/ShaderManagementConsoleToolBar.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ToolBar/ShaderManagementConsoleToolBar.cpp @@ -7,7 +7,7 @@ */ #include -#include +#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -29,4 +29,4 @@ namespace ShaderManagementConsole } } // namespace ShaderManagementConsole -#include +#include From e1b245859140d8625e163da5181e39390dc6520f Mon Sep 17 00:00:00 2001 From: Ignacio Martinez <82394219+AMZN-Igarri@users.noreply.github.com> Date: Thu, 20 Jan 2022 14:09:00 +0100 Subject: [PATCH 265/272] Asset Browser Collapse All Fix (#6996) * Added Icon Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> * Fixed indent in ui file Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../Icons/AssetBrowser/Collapse_All.svg | 14 +++++++++++ .../AzAssetBrowser/AzAssetBrowserWindow.cpp | 22 +++++++++++++++- .../AzAssetBrowser/AzAssetBrowserWindow.ui | 25 ++++++++++++------- 3 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 Assets/Editor/Icons/AssetBrowser/Collapse_All.svg diff --git a/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg new file mode 100644 index 0000000000..7c7a7b85bd --- /dev/null +++ b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp index a7faea36f6..36e08982a7 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp @@ -32,6 +32,15 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserTableView); +namespace AzToolsFramework +{ + namespace AssetBrowser + { + static constexpr const char* CollapseAllIcon = "Assets/Editor/Icons/AssetBrowser/Collapse_All.svg"; + static constexpr const char* MenuIcon = ":/Menu/menu.svg"; + } // namespace AssetBrowser +} // namespace AzToolsFramework + class ListenerForShowAssetEditorEvent : public QObject , private AzToolsFramework::EditorEvents::Bus::Handler @@ -87,10 +96,21 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent) m_assetBrowserModel->SetFilterModel(m_filterModel.data()); + m_ui->m_collapseAllButton->setAutoRaise(true); // hover highlight + m_ui->m_collapseAllButton->setIcon(QIcon(AzAssetBrowser::CollapseAllIcon)); + + connect( + m_ui->m_collapseAllButton, &QToolButton::clicked, this, + [this]() + { + m_ui->m_assetBrowserTreeViewWidget->collapseAll(); + }); + if (ed_useNewAssetBrowserTableView) { m_ui->m_toggleDisplayViewBtn->setVisible(true); - m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg")); + m_ui->m_toggleDisplayViewBtn->setAutoRaise(true); + m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(AzAssetBrowser::MenuIcon)); m_tableModel->setFilterRole(Qt::DisplayRole); m_tableModel->setSourceModel(m_filterModel.data()); diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui index a345438aed..2cc7c57ccd 100644 --- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui +++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui @@ -72,6 +72,22 @@ + + + + Qt::ClickFocus + + + + + + 3 + + + + + + @@ -143,15 +159,6 @@ true - - false - - - true - - - false - From 3df7e239ac5e345b4b6815dee0eb56149b96d281 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Thu, 20 Jan 2022 09:32:42 -0800 Subject: [PATCH 266/272] Fix build error on PC Signed-off-by: amzn-sj --- .../Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp index 4232a37264..d9bdcb97bc 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -221,8 +221,8 @@ namespace Terrain numSamples, &AzFramework::Terrain::TerrainDataRequests::GetNumSamplesFromRegion, region, stepSize); - uint32_t updateWidth = numSamples.first; - uint32_t updateHeight = numSamples.second; + uint32_t updateWidth = static_cast(numSamples.first); + uint32_t updateHeight = static_cast(numSamples.second); AZStd::vector pixels; pixels.reserve(updateWidth * updateHeight); { From 730daae1e65426d26cba0d01e0070dac03e6e8c0 Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Thu, 20 Jan 2022 09:33:21 -0800 Subject: [PATCH 267/272] Added code comments. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../Code/Source/RPI.Reflect/Material/MaterialAsset.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index f2a9efd896..92fded1d5d 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -109,6 +109,9 @@ namespace AZ return m_wasPreFinalized; } + //! Attempts to convert a numeric MaterialPropertyValue to another numeric type @T, + //! since MaterialPropertyValue itself does not support any kind of casting. + //! If the original MaterialPropertyValue is not a numeric type, the original value is returned. template MaterialPropertyValue CastNumericMaterialPropertyValue(const MaterialPropertyValue& value) { @@ -135,7 +138,10 @@ namespace AZ return value; } } - + + //! Attempts to convert an AZ::Vector[2-4] MaterialPropertyValue to another AZ::Vector[2-4] type @T. + //! Any extra elements will be dropped or set to 0.0 as needed. + //! If the original MaterialPropertyValue is not a Vector type, the original value is returned. template MaterialPropertyValue CastVectorMaterialPropertyValue(const MaterialPropertyValue& value) { From 0a722b5a0616f6bf919f8644880333e522dd3f36 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Thu, 20 Jan 2022 09:48:15 -0800 Subject: [PATCH 268/272] Update comment for clarity Signed-off-by: amzn-sj --- Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h index 2296d48843..3e489730d0 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -163,7 +163,8 @@ namespace Terrain AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const override; - //! Returns the number of samples for a given region and step size. + //! Returns the number of samples for a given region and step size. The first and second + //! elements of the pair correspond to the X and Y sample counts respectively. virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2& stepSize) const override; From d6cdd1d053bc5abbea00dec0e4396b2fb0efb0b1 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Thu, 20 Jan 2022 09:51:38 -0800 Subject: [PATCH 269/272] Update another comment Signed-off-by: amzn-sj --- .../AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 9379485646..8b29f2a554 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -161,7 +161,8 @@ namespace AzFramework SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const = 0; - //! Returns the number of samples for a given region and step size. + //! Returns the number of samples for a given region and step size. The first and second + //! elements of the pair correspond to the X and Y sample counts respectively. virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2& stepSize) const = 0; From 8e08e42c86bf9ae30263065c1b5bff93ee832ae6 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Thu, 20 Jan 2022 11:01:00 -0800 Subject: [PATCH 270/272] Fix some warnings about unused parameters Signed-off-by: amzn-sj --- .../Code/Tests/TerrainPhysicsColliderTests.cpp | 13 ++++++------- Gems/Terrain/Code/Tests/TerrainSystemTest.cpp | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp index 2d0933c367..dc43544f05 100644 --- a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp +++ b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp @@ -72,7 +72,6 @@ protected: void ProcessRegionLoop(const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, - AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter, AzFramework::SurfaceData::SurfaceTagWeightList* surfaceTags, float mockHeight) { @@ -281,9 +280,9 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsRetu ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( [this](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, - AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + [[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, nullptr, 0.0f); + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, nullptr, 0.0f); } ); @@ -323,9 +322,9 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsRelativ ON_CALL(terrainListener, ProcessHeightsFromRegion).WillByDefault( [this, mockHeight](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, - AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + [[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, nullptr, mockHeight); + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, nullptr, mockHeight); } ); @@ -476,9 +475,9 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM ON_CALL(terrainListener, ProcessSurfacePointsFromRegion).WillByDefault( [this, mockHeight, &surfaceTags](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback, - AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) + [[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter) { - ProcessRegionLoop(inRegion, stepSize, perPositionCallback, sampleFilter, &surfaceTags, mockHeight); + ProcessRegionLoop(inRegion, stepSize, perPositionCallback, &surfaceTags, mockHeight); } ); diff --git a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp index ab0847e634..ddccdbc49c 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemTest.cpp @@ -969,7 +969,7 @@ namespace UnitTest AzFramework::SurfaceData::SurfaceTagWeightList expectedTags; SetupSurfaceWeightMocks(entity.get(), expectedTags); - auto perPositionCallback = [&expectedTags](size_t xIndex, size_t yIndex, + auto perPositionCallback = [&expectedTags]([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { constexpr float epsilon = 0.0001f; @@ -1015,7 +1015,7 @@ namespace UnitTest AzFramework::SurfaceData::SurfaceTagWeightList expectedTags; SetupSurfaceWeightMocks(entity.get(), expectedTags); - auto perPositionCallback = [&expectedTags](size_t xIndex, size_t yIndex, + auto perPositionCallback = [&expectedTags]([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { constexpr float epsilon = 0.0001f; From f4befb22426d84eba7172ebf17ac2cf97e8dd8be Mon Sep 17 00:00:00 2001 From: santorac <55155825+santorac@users.noreply.github.com> Date: Thu, 20 Jan 2022 11:39:28 -0800 Subject: [PATCH 271/272] Removed some dead code. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com> --- .../RPI.Edit/Material/MaterialPropertyValueSerializer.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp index 10b45ca8df..9980d8f2ff 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp @@ -54,12 +54,6 @@ namespace AZ MaterialSourceData::Property* property = reinterpret_cast(outputValue); AZ_Assert(property, "Output value for JsonMaterialPropertyValueSerializer can't be null."); - // Construct the full property name (groupName.propertyName) by parsing it from the JSON path string. - size_t startPropertyName = context.GetPath().Get().rfind('/'); - size_t startGroupName = context.GetPath().Get().rfind('/', startPropertyName-1); - AZStd::string_view groupName = context.GetPath().Get().substr(startGroupName + 1, startPropertyName - startGroupName - 1); - AZStd::string_view propertyName = context.GetPath().Get().substr(startPropertyName + 1); - JSR::ResultCode result(JSR::Tasks::ReadField); if (inputValue.IsBool()) From 59e43813f0b091f4456a0a90892bf08f7e7b5141 Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Thu, 20 Jan 2022 13:00:02 -0800 Subject: [PATCH 272/272] GCC Support for Linux Updates and fixes to support GCC for Linux Signed-off-by: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Editor/Include/SandboxAPI.h | 2 +- .../Platform/Common/GCC/editor_lib_gcc.cmake | 9 ++ Code/Editor/TopRendererWnd.h | 2 - Code/Framework/AzCore/AzCore/EBus/EBus.h | 9 +- .../AzCore/EBus/Internal/BusContainer.h | 10 +- .../AzCore/EBus/Internal/CallstackEntry.h | 2 +- Code/Framework/AzCore/AzCore/IO/Path/Path.inl | 94 ++++++------ .../AzCore/AzCore/Math/MathIntrinsics.h | 4 +- .../AzCore/AzCore/Memory/AllocatorManager.h | 4 +- .../AzCore/AzCore/Name/NameDictionary.h | 4 +- Code/Framework/AzCore/AzCore/PlatformDef.h | 92 +++++++++++- .../AzCore/AzCore/RTTI/BehaviorContext.h | 7 +- Code/Framework/AzCore/AzCore/RTTI/RTTI.h | 29 ++-- Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h | 36 +++-- .../AzCore/AzCore/Script/ScriptContext.h | 2 +- .../Serialization/Json/RegistrationContext.h | 6 + .../AzCore/AzCore/UnitTest/TestTypes.h | 11 +- .../AzCore/AzCore/azcore_files.cmake | 1 + Code/Framework/AzCore/AzCore/base.h | 61 +------- .../AzCore/std/containers/compressed_pair.h | 1 + .../AzCore/std/containers/fixed_vector.h | 2 +- .../AzCore/AzCore/std/containers/map.h | 2 +- .../AzCore/std/containers/node_handle.h | 7 +- .../AzCore/AzCore/std/containers/set.h | 2 +- .../AzCore/std/containers/unordered_map.h | 2 +- .../AzCore/std/containers/unordered_set.h | 2 +- .../AzCore/std/function/function_base.h | 4 +- .../AzCore/std/function/function_template.h | 2 +- .../AzCore/AzCore/std/function/invoke.h | 1 + .../AzCore/AzCore/std/string/fixed_string.inl | 20 ++- .../AzCore/AzCore/std/string/string.h | 8 +- .../AzCore/AzCore/std/string/string_view.h | 110 +++++++++++--- .../AzCore/std/typetraits/conjunction.h | 1 + .../AzCore/AzCore/std/typetraits/intrinsics.h | 7 +- Code/Framework/AzCore/AzCore/variadic.h | 64 +++++++++ .../OverrunDetectionAllocator_Unimplemented.h | 2 +- .../Platform/Linux/platform_linux.cmake | 3 +- Code/Framework/AzCore/Tests/AZStd/String.cpp | 54 +++---- Code/Framework/AzCore/Tests/EBus.cpp | 30 ++-- Code/Framework/AzCore/Tests/Serialization.cpp | 17 ++- .../TcpTransport/TcpConnection.cpp | 2 +- .../TcpTransport/TcpConnectionSet.cpp | 2 +- .../UdpTransport/UdpNetworkInterface.cpp | 2 +- .../Platform/Linux/AzTest_Traits_Linux.h | 2 - .../AssetBrowser/Entries/AssetBrowserEntry.h | 1 - .../Entity/EditorEntityHelpers.h | 2 +- .../AzToolsFramework/Slice/SliceUtilities.cpp | 2 +- .../AzToolsFramework/Thumbnails/Thumbnail.h | 2 +- .../Common/GCC/aztoolsframework_gcc.cmake} | 1 - Code/Framework/GridMate/CMakeLists.txt | 1 - .../GridMate/GridMate/Carrier/Carrier.cpp | 4 +- .../GridMate/Carrier/SecureSocketDriver.cpp | 2 + .../Carrier/StreamSecureSocketDriver.cpp | 5 + Code/Legacy/CrySystem/IDebugCallStack.cpp | 2 +- .../Common/GCC/projectmanager_gcc.cmake | 12 ++ .../GCC/pythonbindingsexample_gcc.cmake | 12 ++ .../Code/Include/Framework/AWSApiRequestJob.h | 93 ++++++------ .../Include/Framework/ServiceRequestJob.h | 135 +++++++++--------- ...mageprocessingatom_editor_static_gcc.cmake | 12 ++ .../GCC/atom_asset_shader_static_gcc.cmake | 12 ++ .../Feature/ParamMacros/MapParamCommon.inl | 1 + .../Common/atom_feature_common_gcc.cmake | 12 ++ .../Common/GCC/atom_feature_common_gcc.cmake | 13 ++ .../Include/Atom/RPI.Public/GpuQuery/Query.h | 4 +- .../Include/Atom/RPI.Public/Pass/ParentPass.h | 8 +- .../Common/GCC/atom_rpi_public_gcc.cmake | 12 +- .../GCC/editorpythonbindings_static_gcc.cmake | 12 ++ .../GCC/editorpythonbindings_tests_gcc.cmake | 12 ++ .../Code/Tests/ExpressionEngineTestFixture.h | 2 +- .../Code/Tests/MathExpressionTests.cpp | 44 +++--- .../GradientSignal/Code/Source/ImageAsset.cpp | 1 + .../Code/Source/Animation/AnimSplineTrack.h | 2 +- .../Code/Source/Cinematics/AnimSplineTrack.h | 2 +- .../Platform/Common/GCC/metastream_gcc.cmake | 10 ++ Gems/PhysX/Code/CMakeLists.txt | 2 + .../Clang/physx_editor_static_clang.cmake | 7 + .../Common/GCC/physx_editor_static_gcc.cmake | 12 ++ .../MSVC/physx_editor_static_msvc.cmake | 7 + .../GCC/pythonassetbuilder_static_gcc.cmake | 12 ++ .../GCC/pythonassetbuilder_tests_gcc.cmake | 12 ++ .../Platform/Common/GCC/qtforpython_gcc.cmake | 12 ++ .../Code/Editor/Components/EditorGraph.cpp | 2 +- .../Code/Editor/Components/GraphUpgrade.cpp | 2 +- .../Libraries/Core/ScriptEventBase.h | 2 +- ...scriptcanvastesting_editor_tests_gcc.cmake | 7 + .../Include/ScriptEvents/ScriptEventsAsset.h | 9 +- .../ScriptEventsSystemEditorComponent.cpp | 2 +- Gems/WhiteBox/Code/CMakeLists.txt | 1 + .../Common/Clang/whitebox_editor_clang.cmake | 7 + .../Common/GCC/whitebox_editor_gcc.cmake | 12 ++ .../Common/MSVC/whitebox_editor_msvc.cmake | 7 + .../Linux/BuiltInPackages_linux.cmake | 4 +- cmake/Configurations.cmake | 17 ++- .../Common/GCC/Configurations_gcc.cmake | 87 +++++++++++ .../Platform/Linux/Configurations_linux.cmake | 27 ++++ cmake/Platform/Linux/PAL_linux.cmake | 3 + .../build/Platform/Linux/build_config.json | 32 +++++ scripts/build/Platform/Linux/build_linux.sh | 27 +++- 98 files changed, 1050 insertions(+), 429 deletions(-) create mode 100644 Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake create mode 100644 Code/Framework/AzCore/AzCore/variadic.h rename Code/Framework/{GridMate/Platform/Common/gridmate_msvc.cmake => AzToolsFramework/Platform/Common/GCC/aztoolsframework_gcc.cmake} (99%) create mode 100644 Code/Tools/ProjectManager/Platform/Common/GCC/projectmanager_gcc.cmake create mode 100644 Code/Tools/PythonBindingsExample/source/Platform/Common/GCC/pythonbindingsexample_gcc.cmake create mode 100644 Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Platform/Common/GCC/imageprocessingatom_editor_static_gcc.cmake create mode 100644 Gems/Atom/Asset/Shader/Code/Source/Platform/Common/GCC/atom_asset_shader_static_gcc.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_gcc.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Common/GCC/atom_feature_common_gcc.cmake rename Code/Framework/GridMate/Platform/Common/gridmate_clang.cmake => Gems/Atom/RPI/Code/Source/Platform/Common/GCC/atom_rpi_public_gcc.cmake (52%) create mode 100644 Gems/EditorPythonBindings/Code/Source/Platform/Common/GCC/editorpythonbindings_static_gcc.cmake create mode 100644 Gems/EditorPythonBindings/Code/Source/Platform/Common/GCC/editorpythonbindings_tests_gcc.cmake create mode 100644 Gems/Metastream/Code/Source/Platform/Common/GCC/metastream_gcc.cmake create mode 100644 Gems/PhysX/Code/Source/Platform/Common/Clang/physx_editor_static_clang.cmake create mode 100644 Gems/PhysX/Code/Source/Platform/Common/GCC/physx_editor_static_gcc.cmake create mode 100644 Gems/PhysX/Code/Source/Platform/Common/MSVC/physx_editor_static_msvc.cmake create mode 100644 Gems/PythonAssetBuilder/Code/Source/Platform/Common/GCC/pythonassetbuilder_static_gcc.cmake create mode 100644 Gems/PythonAssetBuilder/Code/Source/Platform/Common/GCC/pythonassetbuilder_tests_gcc.cmake create mode 100644 Gems/QtForPython/Code/Source/Platform/Common/GCC/qtforpython_gcc.cmake create mode 100644 Gems/ScriptCanvasTesting/Code/Platform/Common/GCC/scriptcanvastesting_editor_tests_gcc.cmake create mode 100644 Gems/WhiteBox/Code/Source/Platform/Common/Clang/whitebox_editor_clang.cmake create mode 100644 Gems/WhiteBox/Code/Source/Platform/Common/GCC/whitebox_editor_gcc.cmake create mode 100644 Gems/WhiteBox/Code/Source/Platform/Common/MSVC/whitebox_editor_msvc.cmake create mode 100644 cmake/Platform/Common/GCC/Configurations_gcc.cmake diff --git a/Code/Editor/Include/SandboxAPI.h b/Code/Editor/Include/SandboxAPI.h index 4e0cafea4a..757b799837 100644 --- a/Code/Editor/Include/SandboxAPI.h +++ b/Code/Editor/Include/SandboxAPI.h @@ -21,7 +21,7 @@ #endif #if defined(SANDBOX_IMPORTS) && defined(SANDBOX_EXPORTS) -#error SANDBOX_EXPORTS and SANDBOX_IMPORTS can't be defined at the same time +#error SANDBOX_EXPORTS and SANDBOX_IMPORTS cannot be defined at the same time #endif #if defined(SANDBOX_EXPORTS) diff --git a/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake b/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake new file mode 100644 index 0000000000..bc945f55c9 --- /dev/null +++ b/Code/Editor/Platform/Common/GCC/editor_lib_gcc.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(LY_COMPILE_OPTIONS PRIVATE -fexceptions) diff --git a/Code/Editor/TopRendererWnd.h b/Code/Editor/TopRendererWnd.h index c5bc7a31f2..7bdf2eaff2 100644 --- a/Code/Editor/TopRendererWnd.h +++ b/Code/Editor/TopRendererWnd.h @@ -81,8 +81,6 @@ public: bool m_bShowStatObjects; bool m_bShowWater; bool m_bAutoScaleGreyRange; - - friend class QTopRendererWnd; }; #endif // CRYINCLUDE_EDITOR_TOPRENDERERWND_H diff --git a/Code/Framework/AzCore/AzCore/EBus/EBus.h b/Code/Framework/AzCore/AzCore/EBus/EBus.h index 67cffb4e41..4ab4f9a76c 100644 --- a/Code/Framework/AzCore/AzCore/EBus/EBus.h +++ b/Code/Framework/AzCore/AzCore/EBus/EBus.h @@ -23,6 +23,11 @@ #include #include + // Included for backwards compatibility purposes +#include +#include +#include + #include #include @@ -515,7 +520,7 @@ namespace AZ * This is not EBus Context Mutex when LocklessDispatch is set */ template - using DispatchLockGuard = typename ImplTraits::template DispatchLockGuard; + using DispatchLockGuardTemplate = typename ImplTraits::template DispatchLockGuard; ////////////////////////////////////////////////////////////////////////// // Check to help identify common mistakes @@ -645,7 +650,7 @@ namespace AZ * during broadcast/event dispatch. * @see EBusTraits::LocklessDispatch */ - using DispatchLockGuard = DispatchLockGuard; + using DispatchLockGuard = DispatchLockGuardTemplate; /** * The scoped lock guard to use during connection. Some specialized policies execute handler methods which diff --git a/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h b/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h index 2c57359c67..ce79b93805 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h +++ b/Code/Framework/AzCore/AzCore/EBus/Internal/BusContainer.h @@ -93,14 +93,14 @@ namespace AZ // This struct will hold the handlers per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder) using AddressStorage = AddressStoragePolicy; // Defines how handlers are stored per address (will be some sort of list) using HandlerStorage = HandlerStoragePolicy; using Handler = IdHandler; - using MultiHandler = MultiHandler; + using MultiHandler = AZ::Internal::MultiHandler; using BusPtr = AZStd::intrusive_ptr; EBusContainer() = default; @@ -774,13 +774,13 @@ namespace AZ // This struct will hold the handler per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handler holders are stored (will be some sort of map-like structure from id -> handler holder) using AddressStorage = AddressStoragePolicy; // No need for HandlerStorage, there's only 1 so it will always just be a HandlerNode* using Handler = IdHandler; - using MultiHandler = MultiHandler; + using MultiHandler = AZ::Internal::MultiHandler; using BusPtr = AZStd::intrusive_ptr; EBusContainer() = default; @@ -1316,7 +1316,7 @@ namespace AZ // This struct will hold the handlers per address struct HandlerHolder; // This struct will hold each handler - using HandlerNode = HandlerNode; + using HandlerNode = AZ::Internal::HandlerNode; // Defines how handlers are stored per address (will be some sort of list) using HandlerStorage = HandlerStoragePolicy; // No need for AddressStorage, there's only 1 diff --git a/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h b/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h index bcda78aef8..391a0ea18e 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h +++ b/Code/Framework/AzCore/AzCore/EBus/Internal/CallstackEntry.h @@ -161,7 +161,7 @@ namespace AZ template struct EBusCallstackStorage { - AZ_THREAD_LOCAL static C* s_entry; + static AZ_THREAD_LOCAL C* s_entry; EBusCallstackStorage() = default; ~EBusCallstackStorage() = default; diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 0dc1799528..ab991e1750 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl @@ -13,50 +13,6 @@ #include -// extern instantiations of Path templates to prevent implicit instantiations -namespace AZ::IO -{ - // Class templates explicit declarations - extern template class BasicPath; - extern template class BasicPath; - extern template class PathIterator; - extern template class PathIterator; - extern template class PathIterator; - - // Swap function explicit declarations - extern template void swap(Path& lhs, Path& rhs) noexcept; - extern template void swap(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept; - - // Hash function explicit declarations - extern template size_t hash_value(const Path& pathToHash); - extern template size_t hash_value(const FixedMaxPath& pathToHash); - - // Append operator explicit declarations - extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); - extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); - extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); - extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); - extern template BasicPath operator/(const BasicPath& lhs, - const typename BasicPath::value_type* rhs); - extern template BasicPath operator/(const BasicPath& lhs, - const typename BasicPath::value_type* rhs); - - // Iterator compare explicit declarations - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator==(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); - extern template bool operator!=(const PathIterator& lhs, - const PathIterator& rhs); -} - - //! PathView implementation namespace AZ::IO { @@ -939,13 +895,13 @@ namespace AZ::IO // then it has no root directory nor filename if (rootNameView.end() == m_path.end()) { - // has_root_directory || has_filename = false - // If the root name is of the form - // # C: - then it isn't absolute unless it has a root directory C:\ - // # \\?\ = is a UNC path that can't exist without a root directory - // # \\server - Is absolute, but has no root directory - // Therefore if the rootName is larger than three characters - // then append the path separator + /* has_root_directory || has_filename = false + If the root name is of the form + C: - then it isn't absolute unless it has a root directory C:\. + \\?\ = is a UNC path that can't exist without a root directory. + \\server - Is absolute, but has no root directory. + Therefore if the rootName is larger than three characters + then append the path separator. */ if (rootNameView.size() >= 3) { m_path.push_back(m_preferred_separator); @@ -1550,3 +1506,39 @@ namespace AZ::IO return AZStd::hash{}(pathToHash); } } + +// extern instantiations of Path templates to prevent implicit instantiations +namespace AZ::IO +{ + // Swap function explicit declarations + extern template void swap(Path& lhs, Path& rhs) noexcept; + extern template void swap(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept; + + // Hash function explicit declarations + extern template size_t hash_value(const Path& pathToHash); + extern template size_t hash_value(const FixedMaxPath& pathToHash); + + // Append operator explicit declarations + extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); + extern template BasicPath operator/(const BasicPath& lhs, const PathView& rhs); + extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); + extern template BasicPath operator/(const BasicPath& lhs, AZStd::string_view rhs); + extern template BasicPath operator/(const BasicPath& lhs, + const typename BasicPath::value_type* rhs); + extern template BasicPath operator/(const BasicPath& lhs, + const typename BasicPath::value_type* rhs); + + // Iterator compare explicit declarations + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator==(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); + extern template bool operator!=(const PathIterator& lhs, + const PathIterator& rhs); +} diff --git a/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h b/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h index 7b731a12b2..32441aaa32 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h +++ b/Code/Framework/AzCore/AzCore/Math/MathIntrinsics.h @@ -14,7 +14,7 @@ #define az_clz_u64(x) _lzcnt_u64(x) #define az_popcnt_u32(x) __popcnt(x) #define az_popcnt_u64(x) __popcnt64(x) -#elif defined(AZ_COMPILER_CLANG) +#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) #define az_ctz_u32(x) __builtin_ctz(x) #define az_ctz_u64(x) __builtin_ctzll(x) #define az_clz_u32(x) __builtin_clz(x) @@ -22,5 +22,5 @@ #define az_popcnt_u32(x) __builtin_popcount(x) #define az_popcnt_u64(x) __builtin_popcountll(x) #else - #error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isn't supported for this compiler + #error Count Leading Zeros, Count Trailing Zeros and Pop Count intrinsics isnt supported for this compiler #endif diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h index 14dec68ad1..50afce929a 100644 --- a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h +++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h @@ -39,6 +39,9 @@ namespace AZ template constexpr friend void AZStd::destroy_at(T*); public: + + AllocatorManager(); + typedef AZStd::function OutOfMemoryCBType; static void PreRegisterAllocator(IAllocator* allocator); // Only call if the environment is not yet attached @@ -185,7 +188,6 @@ namespace AZ AZ::Debug::AllocationRecords::Mode m_defaultTrackingRecordMode; AZStd::unique_ptr m_mallocSchema; - AllocatorManager(); ~AllocatorManager(); static AllocatorManager g_allocMgr; ///< The single instance of the allocator manager diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h index 8f9af4be3a..3df05f04b5 100644 --- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h +++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h @@ -45,7 +45,9 @@ namespace AZ //! that already exist. class NameDictionary final { + public: AZ_CLASS_ALLOCATOR(NameDictionary, AZ::OSAllocator, 0); + private: friend Module; friend Name; @@ -75,8 +77,8 @@ namespace AZ //! @return A Name instance. If the hash was not found, the Name will be empty. Name FindName(Name::Hash hash) const; - private: NameDictionary(); + private: ~NameDictionary(); void ReportStats() const; diff --git a/Code/Framework/AzCore/AzCore/PlatformDef.h b/Code/Framework/AzCore/AzCore/PlatformDef.h index 7f00f7e90e..8609ad5756 100644 --- a/Code/Framework/AzCore/AzCore/PlatformDef.h +++ b/Code/Framework/AzCore/AzCore/PlatformDef.h @@ -10,10 +10,17 @@ ////////////////////////////////////////////////////////////////////////// // Platforms +#include + #include "PlatformRestrictedFileDef.h" #if defined(__clang__) #define AZ_COMPILER_CLANG __clang_major__ +#elif defined(__GNUC__) + // Assign AZ_COMPILER_GCC to a number that represents the major+minor (2 digits) + path level (2 digits) i.e. 3.2.0 == 30200 + #define AZ_COMPILER_GCC (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) #elif defined(_MSC_VER) #define AZ_COMPILER_MSVC _MSC_VER #else @@ -29,7 +36,7 @@ #define AZ_DYNAMIC_LIBRARY_PREFIX AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX #define AZ_DYNAMIC_LIBRARY_EXTENSION AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION -#if defined(AZ_COMPILER_CLANG) +#if defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) #define AZ_DLL_EXPORT AZ_TRAIT_OS_DLL_EXPORT_CLANG #define AZ_DLL_IMPORT AZ_TRAIT_OS_DLL_IMPORT_CLANG #elif defined(AZ_COMPILER_MSVC) @@ -67,12 +74,36 @@ #if defined(AZ_COMPILER_MSVC) /// Disables a warning using push style. For use matched with an AZ_POP_WARNING -#define AZ_PUSH_DISABLE_WARNING(_msvcOption, __) \ - __pragma(warning(push)) \ + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG +#define AZ_POP_DISABLE_WARNING_MSVC \ + __pragma(warning(pop)) +#define AZ_POP_DISABLE_WARNING_GCC + + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_msvcOption) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) + +#define AZ_PUSH_DISABLE_WARNING_2(_msvcOption, _2) \ + __pragma(warning(push)) \ + __pragma(warning(disable : _msvcOption)) + +#define AZ_PUSH_DISABLE_WARNING_3(_msvcOption, _2, _3) \ + __pragma(warning(push)) \ __pragma(warning(disable : _msvcOption)) /// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING -#define AZ_POP_DISABLE_WARNING \ +#define AZ_POP_DISABLE_WARNING \ __pragma(warning(pop)) @@ -94,17 +125,62 @@ # define AZ_FUNCTION_SIGNATURE __FUNCSIG__ ////////////////////////////////////////////////////////////////////////// -#elif defined(AZ_COMPILER_CLANG) +#elif defined(AZ_COMPILER_CLANG) || defined(AZ_COMPILER_GCC) + +#if defined(AZ_COMPILER_CLANG) /// Disables a single warning using push style. For use matched with an AZ_POP_WARNING -#define AZ_PUSH_DISABLE_WARNING(__, _clangOption) \ - _Pragma("clang diagnostic push") \ + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) \ + _Pragma("clang diagnostic push") \ _Pragma(AZ_STRINGIZE(clang diagnostic ignored _clangOption)) +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG \ + _Pragma("clang diagnostic pop") +#define AZ_POP_DISABLE_WARNING_MSVC +#define AZ_POP_DISABLE_WARNING_GCC + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_1) +#define AZ_PUSH_DISABLE_WARNING_2(_1, _clangOption) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_3(_1, _clangOption, _2) AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) /// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING #define AZ_POP_DISABLE_WARNING \ _Pragma("clang diagnostic pop") +#else + +/// Disables a single warning using push style. For use matched with an AZ_POP_WARNING + +// Compiler specific AZ_PUSH_DISABLE_WARNING +#define AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) \ + _Pragma("GCC diagnostic push") \ + _Pragma(AZ_STRINGIZE(GCC diagnostic ignored _gccOption)) +#define AZ_PUSH_DISABLE_WARNING_CLANG(_clangOption) +#define AZ_PUSH_DISABLE_WARNING_MSVC(_msvcOption) + +/// Compiler specific AZ_POP_DISABLE_WARNING. This needs to be matched with the compiler specific AZ_PUSH_DISABLE_WARNINGs +#define AZ_POP_DISABLE_WARNING_CLANG +#define AZ_POP_DISABLE_WARNING_MSVC +#define AZ_POP_DISABLE_WARNING_GCC \ + _Pragma("GCC diagnostic pop") + +// Variadic definitions for AZ_PUSH_DISABLE_WARNING for the current compiler +#define AZ_PUSH_DISABLE_WARNING_1(_1) +#define AZ_PUSH_DISABLE_WARNING_2(_1, _2) +#define AZ_PUSH_DISABLE_WARNING_3(_1, _2, _gccOption) AZ_PUSH_DISABLE_WARNING_GCC(_gccOption) + +/// Pops the warning stack. For use matched with an AZ_PUSH_DISABLE_WARNING +#define AZ_POP_DISABLE_WARNING + _Pragma("GCC diagnostic pop") + +#endif // defined(AZ_COMPILER_CLANG) + #define AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING #define AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING #define AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING @@ -121,6 +197,8 @@ #error Compiler not supported #endif +#define AZ_PUSH_DISABLE_WARNING(...) AZ_MACRO_SPECIALIZE(AZ_PUSH_DISABLE_WARNING_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__)) + // We need to define AZ_DEBUG_BUILD in debug mode. We can also define it in debug optimized mode (left up to the user). // note that _DEBUG is not in fact always defined on all platforms, and only AZ_DEBUG_BUILD should be relied on. #if !defined(AZ_DEBUG_BUILD) && defined(_DEBUG) diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h index 7f48f301aa..0f7470eb39 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.h @@ -1541,7 +1541,7 @@ namespace AZ } template - static bool SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*) + static void SetClassEqualityComparer(BehaviorClass* behaviorClass, const T*) { behaviorClass->m_equalityComparer = &DefaultEqualityComparer; } @@ -2341,8 +2341,6 @@ namespace AZ // For some reason the Script.cpp test validates that an incomplete type can be used with the SetResult struct template static constexpr bool IsCopyAssignable = false; - template - static constexpr bool IsCopyAssignable() = AZStd::declval())>> = true; template static bool Set(BehaviorValueParameter& param, T&& result, bool IsValueCopy) @@ -2402,6 +2400,9 @@ namespace AZ } }; + template + constexpr bool SetResult::IsCopyAssignable() = AZStd::declval())>> = true; + AZ_FORCE_INLINE BehaviorValueParameter& BehaviorValueParameter::operator=(BehaviorValueParameter&& other) { *static_cast(this) = AZStd::move(static_cast(other)); diff --git a/Code/Framework/AzCore/AzCore/RTTI/RTTI.h b/Code/Framework/AzCore/AzCore/RTTI/RTTI.h index acf6f64f77..e8ccaa79cf 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/RTTI.h +++ b/Code/Framework/AzCore/AzCore/RTTI/RTTI.h @@ -977,26 +977,32 @@ namespace AZ { return AzGenericTypeInfo::Uuid(); } - + + #if defined(AZ_COMPILER_MSVC) + // There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template + // template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack. template class U, typename = void> + #else + template class U, typename = void> + #endif // defined(AZ_COMPILER_MSVC) inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); } - template class U, typename = void> + template class U, typename = void> inline const AZ::TypeId& RttiTypeId() { return AzGenericTypeInfo::Uuid(); @@ -1027,15 +1033,22 @@ namespace AZ } // Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match). + +#if defined(AZ_COMPILER_MSVC) + // There is a bug with the MSVC compiler when using the 'auto' keyword here. It appears that MSVC is unable to distinguish between a template + // template argument with a type variadic pack vs a template template argument with a non-type auto variadic pack. template class T, class U> - inline bool RttiIsTypeOf(const U&) +#else + template class T, class U> +#endif // defined(AZ_COMPILER_MSVC) + inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; return AzGenericTypeInfo::Uuid() == RttiTypeId(); } // Returns true if the type is contained, otherwise false. Safe to call for type not supporting AZRtti (returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; @@ -1043,7 +1056,7 @@ namespace AZ } // Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; @@ -1051,7 +1064,7 @@ namespace AZ } // Returns true if the type is contained, otherwise false.Safe to call for type not supporting AZRtti(returns false unless type fully match). - template class T, class U> + template class T, class U> inline bool RttiIsTypeOf(const U&) { using CheckType = typename AZ::Internal::RttiRemoveQualifiers::type; diff --git a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h index 022025a3df..2cff17a638 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h +++ b/Code/Framework/AzCore/AzCore/RTTI/TypeInfo.h @@ -148,11 +148,18 @@ namespace AZ { /// Needs to match declared parameter type. template