Merge branch 'development' into TIF/Runtime
This commit is contained in:
@@ -292,8 +292,13 @@ namespace AZ
|
||||
const typename VecType::FloatType cmp2 = VecType::AndNot(cmp0, cmp1);
|
||||
|
||||
// -1/x
|
||||
// this step is calculated for all values of x, but only used if x > Sqrt(2) + 1
|
||||
// in order to avoid a division by zero, detect if xabs is zero here and replace it with an arbitrary value
|
||||
// if xabs does equal zero, the value here doesn't matter because the result will be thrown away
|
||||
typename VecType::FloatType xabsSafe =
|
||||
VecType::Add(xabs, VecType::And(VecType::CmpEq(xabs, VecType::ZeroFloat()), FastLoadConstant<VecType>(Simd::g_vec1111)));
|
||||
const typename VecType::FloatType y0 = VecType::And(cmp0, FastLoadConstant<VecType>(Simd::g_HalfPi));
|
||||
typename VecType::FloatType x0 = VecType::Div(FastLoadConstant<VecType>(Simd::g_vec1111), xabs);
|
||||
typename VecType::FloatType x0 = VecType::Div(FastLoadConstant<VecType>(Simd::g_vec1111), xabsSafe);
|
||||
x0 = VecType::Xor(x0, VecType::CastToFloat(FastLoadConstant<VecType>(Simd::g_negateMask)));
|
||||
|
||||
const typename VecType::FloatType y1 = VecType::And(cmp2, FastLoadConstant<VecType>(Simd::g_QuarterPi));
|
||||
@@ -368,8 +373,12 @@ namespace AZ
|
||||
|
||||
typename VecType::FloatType offset = VecType::And(x_lt_0, offset1);
|
||||
|
||||
// the result of this part of the computation is thrown away if x equals 0,
|
||||
// but if x does equal 0, it will cause a division by zero
|
||||
// so replace zero by an arbitrary value here in that case
|
||||
typename VecType::FloatType xSafe = VecType::Add(x, VecType::And(x_eq_0, FastLoadConstant<VecType>(Simd::g_vec1111)));
|
||||
const typename VecType::FloatType atan_mask = VecType::Not(VecType::Or(x_eq_0, y_eq_0));
|
||||
const typename VecType::FloatType atan_arg = VecType::Div(y, x);
|
||||
const typename VecType::FloatType atan_arg = VecType::Div(y, xSafe);
|
||||
typename VecType::FloatType atan_result = VecType::Atan(atan_arg);
|
||||
atan_result = VecType::Add(atan_result, offset);
|
||||
atan_result = VecType::AndNot(pio2_mask, atan_result);
|
||||
|
||||
@@ -471,6 +471,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec2::FloatType Vec2::Reciprocal(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(Sse::ReplaceThird(value, 1.0f), 1.0f);
|
||||
return Sse::Reciprocal(value);
|
||||
}
|
||||
|
||||
@@ -513,6 +514,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec2::FloatType Vec2::SqrtInv(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(Sse::ReplaceThird(value, 1.0f), 1.0f);
|
||||
return Sse::SqrtInv(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -507,6 +507,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec3::FloatType Vec3::Reciprocal(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(value, 1.0f);
|
||||
return Sse::Reciprocal(value);
|
||||
}
|
||||
|
||||
@@ -549,6 +550,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec3::FloatType Vec3::SqrtInv(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(value, 1.0f);
|
||||
return Sse::SqrtInv(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,12 @@
|
||||
#endif
|
||||
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) __declspec(align(_alignment)) _decl
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
__declspec(align(_alignment)) \
|
||||
_decl \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof(_type)
|
||||
/// Pointer will be aliased.
|
||||
@@ -123,7 +128,12 @@
|
||||
|
||||
# define AZ_FORCE_INLINE inline
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) _decl __attribute__((aligned(_alignment)))
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
_decl \
|
||||
__attribute__((aligned(_alignment)))
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof__(_type)
|
||||
/// Pointer will be aliased.
|
||||
|
||||
@@ -161,7 +161,56 @@ namespace AZ
|
||||
return "A pair is an fixed size collection of two elements.";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
void GetTypeNamesFold(AZStd::vector<AZStd::string>& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
result.push_back(OnDemandPrettyName<T>::Get(context));
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
void GetTypeNames(AZStd::vector<AZStd::string>& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
(GetTypeNamesFold<T>(result, context), ...);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void GetTypeNamesFold(AZStd::string& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
if (!result.empty())
|
||||
{
|
||||
result += ", ";
|
||||
}
|
||||
|
||||
result += OnDemandPrettyName<T>::Get(context);
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
void GetTypeNames(AZStd::string& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
(GetTypeNamesFold<T>(result, context), ...);
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct OnDemandPrettyName<AZStd::tuple<T...>>
|
||||
{
|
||||
static AZStd::string Get(AZ::BehaviorContext& context)
|
||||
{
|
||||
AZStd::string typeNames;
|
||||
GetTypeNames<T...>(typeNames, context);
|
||||
return AZStd::string::format("Tuple<%s>", typeNames.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct OnDemandToolTip<AZStd::tuple<T...>>
|
||||
{
|
||||
static AZStd::string Get(AZ::BehaviorContext&)
|
||||
{
|
||||
return "A tuple is an fixed size collection of any number of any type of element.";
|
||||
}
|
||||
};
|
||||
|
||||
template<class Key, class MappedType, class Hasher, class EqualKey, class Allocator>
|
||||
struct OnDemandPrettyName< AZStd::unordered_map<Key, MappedType, Hasher, EqualKey, Allocator> >
|
||||
{
|
||||
|
||||
@@ -813,20 +813,27 @@ namespace AZ
|
||||
{
|
||||
using ContainerType = AZStd::tuple<T...>;
|
||||
|
||||
template<size_t Index>
|
||||
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder)
|
||||
template<typename Targ, size_t Index>
|
||||
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder, const AZStd::vector<AZStd::string>& typeNames)
|
||||
{
|
||||
const AZStd::string methodName = AZStd::string::format("Get%zu", Index);
|
||||
builder->Method(methodName.data(), [](ContainerType& value) { return AZStd::get<Index>(value); })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
builder->Method(methodName.data(), [](ContainerType& thisPointer) { return AZStd::get<Index>(thisPointer); })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, Index)
|
||||
;
|
||||
|
||||
builder->Property
|
||||
( AZStd::string::format("element_%zu_%s", Index, typeNames[Index].c_str()).c_str()
|
||||
, [](ContainerType& thisPointer) { return AZStd::get<Index>(thisPointer); }
|
||||
, [](ContainerType& thisPointer, const Targ& element) { AZStd::get<Index>(thisPointer) = element; });
|
||||
}
|
||||
|
||||
template<size_t... Indices>
|
||||
template<typename... Targ, size_t... Indices>
|
||||
static void ReflectUnpackMethods(BehaviorContext::ClassBuilder<ContainerType>& builder, AZStd::index_sequence<Indices...>)
|
||||
{
|
||||
(ReflectUnpackMethodFold<Indices>(builder), ...);
|
||||
AZStd::vector<AZStd::string> typeNames;
|
||||
ScriptCanvasOnDemandReflection::GetTypeNames<T...>(typeNames, *builder.m_context);
|
||||
(ReflectUnpackMethodFold<Targ, Indices>(builder, typeNames), ...);
|
||||
}
|
||||
|
||||
static void Reflect(ReflectContext* context)
|
||||
@@ -851,9 +858,10 @@ namespace AZ
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleConstructorFunction, constructorHolder)
|
||||
;
|
||||
|
||||
ReflectUnpackMethods(builder, AZStd::make_index_sequence<sizeof...(T)>{});
|
||||
ReflectUnpackMethods<T...>(builder, AZStd::make_index_sequence<sizeof...(T)>{});
|
||||
|
||||
builder->Method("GetSize", []() { return AZStd::tuple_size<ContainerType>::value; })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ namespace AZ
|
||||
{
|
||||
using Callable = AZStd::conditional_t<AZStd::function_traits<Invocable>::value, AZStd::function<typename AZStd::function_traits<Invocable>::function_type>, Invocable>;
|
||||
public:
|
||||
AZ_RTTI((AttributeInvocable<Invocable>, "{60D5804F-9AF4-4EB1-8F5A-62AFB4883F9D}"), AZ::Attribute);
|
||||
AZ_RTTI((AttributeInvocable<Invocable>, "{60D5804F-9AF4-4EB1-8F5A-62AFB4883F9D}", Invocable), AZ::Attribute);
|
||||
AZ_CLASS_ALLOCATOR(AttributeInvocable<Invocable>, SystemAllocator, 0);
|
||||
template<typename CallableType>
|
||||
explicit AttributeInvocable(CallableType&& invocable)
|
||||
|
||||
@@ -150,8 +150,13 @@ namespace AZ
|
||||
// also needs to be an overload for every version because they all represent overloads for different non-types.
|
||||
namespace AzGenericTypeInfo
|
||||
{
|
||||
template<typename...>
|
||||
constexpr bool false_v = false;
|
||||
/// Needs to match declared parameter type.
|
||||
template <template <typename...> class> constexpr bool false_v1 = false;
|
||||
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
|
||||
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
|
||||
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
|
||||
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
|
||||
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
|
||||
|
||||
template<typename T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
@@ -162,7 +167,7 @@ namespace AZ
|
||||
template<template<typename...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v1<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -170,7 +175,7 @@ namespace AZ
|
||||
template<template<AZStd::size_t...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -178,7 +183,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -186,7 +191,7 @@ namespace AZ
|
||||
template<template<typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -194,7 +199,7 @@ namespace AZ
|
||||
template<template<typename, typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -202,7 +207,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t, typename> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,12 @@
|
||||
#include <AzCore/Serialization/Json/StringSerializer.h>
|
||||
#include <AzCore/Serialization/Json/TupleSerializer.h>
|
||||
#include <AzCore/Serialization/Json/UnorderedSetSerializer.h>
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/forward_list.h>
|
||||
@@ -33,12 +38,11 @@
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -98,6 +102,13 @@ namespace AZ
|
||||
jsonContext->Serializer<JsonArraySerializer>()
|
||||
->HandlesType<AZStd::array>();
|
||||
|
||||
jsonContext->Serializer<JsonAnySerializer>()
|
||||
->HandlesType<AZStd::any>();
|
||||
jsonContext->Serializer<JsonVariantSerializer>()
|
||||
->HandlesType<AZStd::variant>();
|
||||
jsonContext->Serializer<JsonOptionalSerializer>()
|
||||
->HandlesType<AZStd::optional>();
|
||||
|
||||
MathReflect(jsonContext);
|
||||
}
|
||||
else if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(reflectContext))
|
||||
|
||||
@@ -33,34 +33,31 @@ namespace AZ
|
||||
, m_serializerIter(serializerMapIter)
|
||||
{}
|
||||
|
||||
JsonRegistrationContext::SerializerBuilder* JsonRegistrationContext::SerializerBuilder::HandlesTypeId(const Uuid& uuid)
|
||||
JsonRegistrationContext::SerializerBuilder* JsonRegistrationContext::SerializerBuilder::HandlesTypeId(
|
||||
const Uuid& uuid, bool overwriteExisting)
|
||||
{
|
||||
if (!m_context->IsRemovingReflection())
|
||||
{
|
||||
auto serializer = m_serializerIter->second.get();
|
||||
if (uuid.IsNull())
|
||||
{
|
||||
AZ_Error("Serialization", false,
|
||||
"Could not register Json serializer %s. Its Uuid is null.",
|
||||
serializer->RTTI_GetTypeName()
|
||||
);
|
||||
AZ_Assert(false, "Could not register Json serializer %s. Its Uuid is null.", serializer->RTTI_GetTypeName());
|
||||
return this;
|
||||
}
|
||||
|
||||
auto serializerIter = m_context->m_handledTypesMap.find(uuid);
|
||||
|
||||
if (serializerIter == m_context->m_handledTypesMap.end())
|
||||
if (!overwriteExisting)
|
||||
{
|
||||
m_context->m_handledTypesMap.emplace(uuid, serializer);
|
||||
return this;
|
||||
auto emplaceResult = m_context->m_handledTypesMap.try_emplace(uuid, serializer);
|
||||
AZ_Assert(
|
||||
emplaceResult.second,
|
||||
"Couldn't register Json serializer %s. Another serializer (%s) has already been registered for the same Uuid (%s).",
|
||||
serializer->RTTI_GetTypeName(), emplaceResult.first->second->RTTI_GetTypeName(),
|
||||
uuid.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context->m_handledTypesMap.insert_or_assign(uuid, serializer);
|
||||
}
|
||||
|
||||
AZ_Error("Serialization", false,
|
||||
"Couldn't register Json serializer %s. Another serializer (%s) has already been registered for the same Uuid (%s).",
|
||||
serializer->RTTI_GetTypeName(),
|
||||
serializerIter->second->RTTI_GetTypeName(),
|
||||
serializerIter->first.ToString<OSString>().c_str()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -63,52 +63,50 @@ namespace AZ
|
||||
SerializerBuilder* operator->();
|
||||
|
||||
template <typename T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template <template<typename...> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<AZStd::size_t...> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, typename, typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, AZStd::size_t, typename> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct Placeholder { AZ_TYPE_INFO(PlaceHolder, "{4425191C-F497-411A-A7C3-52928E720B0A}"); };
|
||||
|
||||
SerializerBuilder(JsonRegistrationContext* context, SerializerMap::const_iterator serializerMapIter);
|
||||
SerializerBuilder* HandlesTypeId(const AZ::Uuid& uuid);
|
||||
SerializerBuilder* HandlesTypeId(const AZ::Uuid& uuid, bool overwriteExisting);
|
||||
|
||||
JsonRegistrationContext* m_context = nullptr;
|
||||
SerializerMap::const_iterator m_serializerIter;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonUnsupportedTypesSerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonAnySerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonVariantSerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonOptionalSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result JsonUnsupportedTypesSerializer::Load(void*, const Uuid&, const rapidjson::Value&,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Invalid, GetMessage());
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonUnsupportedTypesSerializer::Store(rapidjson::Value&, const void*, const void*, const Uuid&,
|
||||
JsonSerializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Invalid, GetMessage());
|
||||
}
|
||||
|
||||
AZStd::string_view JsonAnySerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::any by design. The Json Serialization attempts to minimize the use of $type, "
|
||||
"in particular the guid version, but no way has yet been found to use AZStd::any without explicitly and always requiring "
|
||||
"one.";
|
||||
}
|
||||
|
||||
AZStd::string_view JsonVariantSerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::variant by design. The Json Serialization attempts to minimize the use of "
|
||||
"$type, in particular the guid version. While combinations of AZStd::variant can be constructed that don't require a $type, "
|
||||
"this cannot be guaranteed in general.";
|
||||
}
|
||||
|
||||
AZStd::string_view JsonOptionalSerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::optional by design. No JSON format has yet been found that wasn't deemed too "
|
||||
"complex or overly verbose.";
|
||||
}
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class JsonUnsupportedTypesSerializer : public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonUnsupportedTypesSerializer, "{AFCC76B9-1F28-429D-8B4E-020BFD95ADAC}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
JsonSerializationResult::Result Load(
|
||||
void* outputValue,
|
||||
const Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context) override;
|
||||
JsonSerializationResult::Result Store(
|
||||
rapidjson::Value& outputValue,
|
||||
const void* inputValue,
|
||||
const void* defaultValue,
|
||||
const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context) override;
|
||||
|
||||
protected:
|
||||
virtual AZStd::string_view GetMessage() const = 0;
|
||||
};
|
||||
|
||||
class JsonAnySerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonAnySerializer, "{699A0864-C4E2-4266-8141-99793C76870F}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
|
||||
class JsonVariantSerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonVariantSerializer, "{08F8E746-F8A4-4E83-8902-713E90F3F498}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
|
||||
class JsonOptionalSerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonOptionalSerializer, "{F8AF1C95-BD1B-44D2-9B4A-F5726133A104}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
} // namespace AZ
|
||||
@@ -175,4 +175,11 @@ namespace AZ::Utils
|
||||
path /= ".o3de";
|
||||
return path.Native();
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString GetO3deLogsDirectory()
|
||||
{
|
||||
AZ::IO::FixedMaxPath path = GetO3deManifestDirectory();
|
||||
path /= "Logs";
|
||||
return path.Native();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,9 @@ namespace AZ
|
||||
//! Retrieves the full path where the manifest file lives, i.e. "<userhome>/.o3de/o3de_manifest.json"
|
||||
AZ::IO::FixedMaxPathString GetEngineManifestPath();
|
||||
|
||||
//! Retrieves the full directory to the O3DE logs directory, i.e. "<userhome>/.o3de/Logs"
|
||||
AZ::IO::FixedMaxPathString GetO3deLogsDirectory();
|
||||
|
||||
//! Retrieves the App root path to use on the current platform
|
||||
//! If the optional is not engaged the AppRootPath should be calculated based
|
||||
//! on the location of the bootstrap.cfg file
|
||||
@@ -113,7 +116,8 @@ namespace AZ
|
||||
//! Save a string to a file. Otherwise returns a failure with error message.
|
||||
AZ::Outcome<void, AZStd::string> WriteFile(AZStd::string_view content, AZStd::string_view filePath);
|
||||
|
||||
//! Read a file into a string. Returns a failure with error message if the content could not be loaded.
|
||||
//! Read a file into a string. Returns a failure with error message if the content could not be loaded or if
|
||||
//! the file size is larger than the max file size provided.
|
||||
template<typename Container = AZStd::string>
|
||||
AZ::Outcome<Container, AZStd::string> ReadFile(AZStd::string_view filePath, size_t maxFileSize = DefaultMaxFileSize);
|
||||
}
|
||||
|
||||
@@ -544,6 +544,8 @@ set(FILES
|
||||
Serialization/Json/TupleSerializer.cpp
|
||||
Serialization/Json/UnorderedSetSerializer.h
|
||||
Serialization/Json/UnorderedSetSerializer.cpp
|
||||
Serialization/Json/UnsupportedTypesSerializer.h
|
||||
Serialization/Json/UnsupportedTypesSerializer.cpp
|
||||
Serialization/std/VariantReflection.inl
|
||||
Settings/CommandLine.cpp
|
||||
Settings/CommandLine.h
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace AZStd
|
||||
using std::exp2;
|
||||
using std::floor;
|
||||
using std::fmod;
|
||||
using std::pow;
|
||||
using std::round;
|
||||
using std::sin;
|
||||
using std::sqrt;
|
||||
|
||||
@@ -2010,6 +2010,28 @@ TEST_F(SerializeBasicTest, BasicTypeTest_Succeed)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This test will dynamic cast (azrtti_cast) between incompatible types, which should always result in nullptr.
|
||||
If this test fails, the RTTI declaration for the relevant type is incorrect.
|
||||
*/
|
||||
TEST_F(Serialization, AttributeRTTI)
|
||||
{
|
||||
{
|
||||
AttributeInvocable<AZStd::function<AZStd::string(AZStd::string)>> fn([](AZStd::string x) { return x + x; });
|
||||
Attribute* fnDownCast = &fn;
|
||||
auto fnUpCast = azrtti_cast<AttributeInvocable<AZStd::function<int(int)>>*>(fnDownCast);
|
||||
EXPECT_EQ(fnUpCast, nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
AttributeFunction<AZStd::string(AZStd::string)> fn([](AZStd::string x) { return x + x; });
|
||||
Attribute* fnDownCast = &fn;
|
||||
auto fnUpCast = azrtti_cast<AttributeFunction<int(int)>*>(fnDownCast);
|
||||
EXPECT_EQ(fnUpCast, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecation
|
||||
*/
|
||||
|
||||
@@ -95,6 +95,20 @@ namespace JsonSerializationTests
|
||||
}
|
||||
};
|
||||
|
||||
class SerializerWithOneDuplicatedTypeWithOverride
|
||||
: public JsonSerializerTemplatedMock<SerializerWithOneDuplicatedTypeWithOverride>
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(SerializerWithOneDuplicatedTypeWithOverride, "{4218D591-E578-499B-B578-ACA70C9944AB}", BaseJsonSerializer);
|
||||
~SerializerWithOneDuplicatedTypeWithOverride() override = default;
|
||||
|
||||
static void Reflect(AZ::JsonRegistrationContext* context)
|
||||
{
|
||||
context->Serializer<SerializerWithOneDuplicatedTypeWithOverride>()
|
||||
->HandlesType<bool>(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Attempts to register the same type twice
|
||||
class SerializerWithTwoSameTypes
|
||||
: public JsonSerializerTemplatedMock<SerializerWithTwoSameTypes>
|
||||
@@ -271,13 +285,29 @@ namespace JsonSerializationTests
|
||||
|
||||
EXPECT_EQ(1, m_jsonRegistrationContext->GetRegisteredSerializers().size());
|
||||
AZ::BaseJsonSerializer* mockSerializer = m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<bool>());
|
||||
EXPECT_NE(mockSerializer, nullptr);
|
||||
ASSERT_NE(mockSerializer, nullptr);
|
||||
EXPECT_EQ(AZ::AzTypeInfo<SerializerWithOneType>::Uuid(), mockSerializer->RTTI_GetType());
|
||||
|
||||
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedType::Unreflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
TEST_F(JsonRegistrationContextTests, OverwriteRegisterSameUuidWithMultipleSerializers_Succeeds)
|
||||
{
|
||||
EXPECT_NE(AZ::AzTypeInfo<SerializerWithOneDuplicatedTypeWithOverride>::Uuid(), AZ::AzTypeInfo<SerializerWithOneType>::Uuid());
|
||||
|
||||
SerializerWithOneType::Reflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedTypeWithOverride::Reflect(m_jsonRegistrationContext.get());
|
||||
|
||||
EXPECT_EQ(1, m_jsonRegistrationContext->GetRegisteredSerializers().size());
|
||||
AZ::BaseJsonSerializer* mockSerializer = m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<bool>());
|
||||
ASSERT_NE(mockSerializer, nullptr);
|
||||
EXPECT_EQ(AZ::AzTypeInfo<SerializerWithOneDuplicatedTypeWithOverride>::Uuid(), mockSerializer->RTTI_GetType());
|
||||
|
||||
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedTypeWithOverride::Unreflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
TEST_F(JsonRegistrationContextTests, RegisterSameUuidWithSameSerializers_Fails)
|
||||
{
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
|
||||
|
||||
namespace JsonSerializationTests
|
||||
{
|
||||
struct AnyInfo
|
||||
{
|
||||
using Type = AZStd::any;
|
||||
using Serializer = AZ::JsonAnySerializer;
|
||||
};
|
||||
|
||||
struct VariantInfo
|
||||
{
|
||||
using Type = AZStd::variant<AZStd::monostate, int, double>;
|
||||
using Serializer = AZ::JsonVariantSerializer;
|
||||
};
|
||||
|
||||
struct OptionalInfo
|
||||
{
|
||||
using Type = AZStd::optional<int>;
|
||||
using Serializer = AZ::JsonVariantSerializer;
|
||||
};
|
||||
|
||||
template<typename Info>
|
||||
class JsonUnsupportedTypesSerializerTests : public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
using Type = typename Info::Type;
|
||||
using Serializer = typename Info::Serializer;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseJsonSerializerFixture::SetUp();
|
||||
this->m_serializer = AZStd::make_unique<Serializer>();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
this->m_serializer.reset();
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<Serializer> m_serializer;
|
||||
Type m_instance{};
|
||||
};
|
||||
|
||||
using UnsupportedTypesTestTypes = ::testing::Types<AnyInfo, VariantInfo, OptionalInfo>;
|
||||
TYPED_TEST_CASE(JsonUnsupportedTypesSerializerTests, UnsupportedTypesTestTypes);
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Load_CallDirectly_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_jsonDeserializationContext->PushReporter(AZStd::move(callback));
|
||||
|
||||
JSR::Result result = this->m_serializer->Load(
|
||||
&this->m_instance, azrtti_typeid(this->m_instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext);
|
||||
this->m_jsonDeserializationContext->PopReporter();
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetResultCode().GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Load_CallThroughFrontEnd_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_deserializationSettings->m_reporting = AZStd::move(callback);
|
||||
|
||||
JSR::ResultCode result = AZ::JsonSerialization::Load(this->m_instance, *this->m_jsonDocument, *this->m_deserializationSettings);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Save_CallDirectly_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_jsonSerializationContext->PushReporter(AZStd::move(callback));
|
||||
|
||||
JSR::Result result = this->m_serializer->Store(
|
||||
*this->m_jsonDocument, &this->m_instance, nullptr, azrtti_typeid(this->m_instance), *this->m_jsonSerializationContext);
|
||||
this->m_jsonSerializationContext->PopReporter();
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetResultCode().GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Save_CallThroughFrontEnd_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_serializationSettings->m_reporting = AZStd::move(callback);
|
||||
|
||||
JSR::ResultCode result = AZ::JsonSerialization::Store(
|
||||
*this->m_jsonDocument, this->m_jsonDocument->GetAllocator(), this->m_instance, *this->m_serializationSettings);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
} // namespace JsonSerializationTests
|
||||
@@ -128,6 +128,7 @@ set(FILES
|
||||
Serialization/Json/TransformSerializerTests.cpp
|
||||
Serialization/Json/TupleSerializerTests.cpp
|
||||
Serialization/Json/UnorderedSetSerializerTests.cpp
|
||||
Serialization/Json/UnsupportedTypesSerializerTests.cpp
|
||||
Serialization/Json/UuidSerializerTests.cpp
|
||||
Math/AabbTests.cpp
|
||||
Math/ColorTests.cpp
|
||||
|
||||
Reference in New Issue
Block a user