From f36255b22ad0115c2cd86b184ff9f8518419857e Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 8 Dec 2021 13:57:24 -0800 Subject: [PATCH 01/66] 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 02/66] 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 03/66] 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 04/66] 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 05/66] 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 06/66] 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 07/66] 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 08/66] 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 09/66] 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 c53c97cf5f80bda645654cc4613be86a9eccc373 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Sat, 11 Dec 2021 15:54:57 -0800 Subject: [PATCH 10/66] 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 11/66] 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 12/66] 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 13/66] 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 14/66] 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 15/66] 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 16/66] 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 17/66] 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 18/66] 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 19/66] 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 20/66] 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 21/66] 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 9b5dcf82b5972037daf9f114e79dee6618de88e7 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 16 Dec 2021 20:46:12 -0800 Subject: [PATCH 22/66] 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 23/66] 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 bbd00adadeaf315a615b1e08259f44763a5272fb Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Mon, 20 Dec 2021 16:54:06 -0800 Subject: [PATCH 24/66] 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 25/66] 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 26/66] 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 27/66] 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 28/66] 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 29/66] 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 30/66] 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 31/66] 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 a7d173db3d530dbf0d5f0067e05e4bd8ea422406 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Mon, 3 Jan 2022 16:15:35 -0800 Subject: [PATCH 32/66] 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 a891993c35091f4eb3f18ff1ac91c944b08d22ef Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Tue, 4 Jan 2022 09:58:30 -0800 Subject: [PATCH 33/66] 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 34/66] 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 35/66] 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 36/66] 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 8ed3da5b7f9916474e3e1de2188d23093bf68549 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 10:24:53 -0800 Subject: [PATCH 37/66] 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 acc6248ec98ef8cd24ea057f679d90ca6be812e5 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 5 Jan 2022 11:31:09 -0800 Subject: [PATCH 38/66] 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 d347a9d2c034dea3878ce357060b7e040bee6885 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 5 Jan 2022 12:56:22 -0800 Subject: [PATCH 39/66] 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 7d9f9f99e657af79cbe6000ccadfa79272c4410f Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 14:50:03 -0800 Subject: [PATCH 40/66] 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 0bcb514c27299df1f09c8cdfe8e6e94247ff2f89 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Wed, 5 Jan 2022 15:56:53 -0800 Subject: [PATCH 41/66] 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 5f9a4a5eed421480094884b2b78ac309d2d77fde Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 5 Jan 2022 17:21:55 -0800 Subject: [PATCH 42/66] 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 f1c8fbe7c07fadb288466909877f8a445b04e469 Mon Sep 17 00:00:00 2001 From: mrieggeramzn Date: Thu, 6 Jan 2022 13:45:54 -0800 Subject: [PATCH 43/66] 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 44/66] 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 e7f573d22a37321ecdd6de0578d527f0186115a6 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Thu, 6 Jan 2022 16:48:07 -0800 Subject: [PATCH 45/66] 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 46/66] 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 47/66] 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 2492c0a4f4db175268742fe9dcf4191d4ad44bea Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 6 Jan 2022 17:56:00 -0800 Subject: [PATCH 48/66] 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 8b9e3d2175bb7766e0e9e81f0bba310cafd14a90 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 7 Jan 2022 09:53:14 -0800 Subject: [PATCH 49/66] 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 aebf93d8824a8b1d8b8e31d7a808161b21357dd8 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 12 Jan 2022 13:13:52 -0800 Subject: [PATCH 50/66] 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 a43cd9531328d006f8487f449555318750712115 Mon Sep 17 00:00:00 2001 From: moraaar Date: Fri, 14 Jan 2022 10:01:38 +0000 Subject: [PATCH 51/66] 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 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 52/66] 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 53/66] [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 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 54/66] 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 55/66] 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 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 56/66] 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 57/66] 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 58/66] 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 59/66] [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 60/66] 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 61/66] 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 62/66] 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 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 63/66] 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 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 64/66] [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 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 65/66] 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 17:41:18 -0800 Subject: [PATCH 66/66] 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