Separated initializing new and all objects in the Json Serialization

Introduced OperationFlags::InitializeNewInstance to the Json Serialization which allows custom json serializers to indicate that they need to set defaults only to new instances. Objects created to fill in a pointer are considered new objects and serializer can use the new ContinuationFlags::LoadAsNewInstance to also inform that the load is happening on a new object. Serializer that use the InitializeNewInstance flag know that a new object is begin initialized if they're called with an explicit default object.
main
AMZN-koppersr 5 years ago
parent fcd989c295
commit f00fa26e12

@ -103,7 +103,7 @@ namespace AZ
auto JsonColorSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
JsonSerializationResult::Result JsonColorSerializer::LoadObject(Color& output, const rapidjson::Value& inputValue,

@ -393,7 +393,7 @@ namespace AZ
auto BaseJsonMatrixSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}

@ -206,7 +206,7 @@ namespace AZ
auto BaseJsonVectorSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}

@ -148,7 +148,7 @@ namespace AZ
auto JsonTransformSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
} // namespace AZ

@ -35,7 +35,7 @@ namespace AZ
auto JsonUuidSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
JsonSerializationResult::Result JsonUuidSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,

@ -216,9 +216,10 @@ namespace AZ
JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading(
void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags)
{
bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance;
return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer
? JsonDeserializer::LoadToPointer(object, typeId, value, context)
: JsonDeserializer::Load(object, typeId, value, context);
: JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, context);
}
JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring(

@ -163,15 +163,20 @@ namespace AZ
enum class ContinuationFlags
{
None = 0, //! No extra flags.
ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
ReplaceDefault = 1 << 1 //! The default value provided for storing will be replaced with a newly created one.
None = 0, //! No extra flags.
ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one.
LoadAsNewInstance = 1 << 2 //! Treats the value as if it's a newly created instance. This may trigger serializers marked with
//! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to
//! an array.
};
enum class OperationFlags
{
None = 0, //! No flags that control how the custom json serializer is used.
ManualDefault = 1 << 0 //! Even if an (explicit) default is found the custom json serializer will still be called.
None = 0, //! No flags that control how the custom json serializer is used.
ManualDefault = 1 << 0, //! Even if an (explicit) default is found the custom json serializer will still be called.
InitializeNewInstance = 1 << 1 //! If set, the custom json serializer will be called with an explicit default if a new
//! instance of its target type is created.
};
virtual ~BaseJsonSerializer() = default;

@ -154,6 +154,6 @@ namespace AZ
auto JsonBoolSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
} // namespace AZ

@ -166,7 +166,7 @@ namespace AZ
auto JsonDoubleSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
JsonSerializationResult::Result JsonFloatSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
@ -191,6 +191,6 @@ namespace AZ
auto JsonFloatSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
} // namespace AZ

@ -135,7 +135,7 @@ namespace AZ
auto BaseJsonIntegerSerializer::GetOperationsFlags() const -> OperationFlags
{
return OperationFlags::ManualDefault;
return OperationFlags::InitializeNewInstance;
}
JsonSerializationResult::Result JsonCharSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,

@ -24,20 +24,24 @@
namespace AZ
{
JsonSerializationResult::ResultCode JsonDeserializer::DeserializerDefaultCheck(BaseJsonSerializer* serializer, void* object,
const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context)
const Uuid& typeId,const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context)
{
using namespace AZ::JsonSerializationResult;
bool isExplicitDefault = IsExplicitDefault(value);
bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) ==
BaseJsonSerializer::OperationFlags::ManualDefault;
return !isExplicitDefault || (isExplicitDefault && manuallyDefaults)
bool initializeNewInstance = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) ==
BaseJsonSerializer::OperationFlags::InitializeNewInstance;
return
!isExplicitDefault || (isExplicitDefault && manuallyDefaults) || (isExplicitDefault && isNewInstance && initializeNewInstance)
? serializer->Load(object, typeId, value, context)
: context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default.");
}
JsonSerializationResult::ResultCode JsonDeserializer::Load(void* object, const Uuid& typeId, const rapidjson::Value& value,
JsonDeserializerContext& context)
JsonSerializationResult::ResultCode JsonDeserializer::Load(
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context)
{
using namespace AZ::JsonSerializationResult;
@ -50,7 +54,7 @@ namespace AZ
BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId);
if (serializer)
{
return DeserializerDefaultCheck(serializer, object, typeId, value, context);
return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
}
const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId);
@ -72,7 +76,7 @@ namespace AZ
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
if (serializer)
{
return DeserializerDefaultCheck(serializer, object, typeId, value, context);
return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
}
}
@ -133,7 +137,7 @@ namespace AZ
const SerializeContext::ClassData* resolvedClassData = context.GetSerializeContext()->FindClassData(resolvedTypeId);
if (resolvedClassData)
{
status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, context);
status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, context);
*objectPtr = resolvedClassData->m_azRtti->Cast(*objectPtr, typeId);
@ -174,7 +178,7 @@ namespace AZ
}
else
{
return Load(object, classElement.m_typeId, value, context);
return Load(object, classElement.m_typeId, value, false, context);
}
}

@ -58,8 +58,8 @@ namespace AZ
JsonDeserializer(const JsonDeserializer& rhs) = delete;
JsonDeserializer(JsonDeserializer&& rhs) = delete;
static JsonSerializationResult::ResultCode Load(void* object, const Uuid& typeId, const rapidjson::Value& value,
JsonDeserializerContext& context);
static JsonSerializationResult::ResultCode Load(
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context);
static JsonSerializationResult::ResultCode LoadToPointer(void* object, const Uuid& typeId, const rapidjson::Value& value,
JsonDeserializerContext& context);
@ -120,6 +120,7 @@ namespace AZ
void* object,
const Uuid& typeId,
const rapidjson::Value& value,
bool isNewInstance,
JsonDeserializerContext& context);
};
} // namespace AZ

@ -249,7 +249,7 @@ namespace AZ
{
StackedString path(StackedString::Format::JsonPointer);
JsonDeserializerContext context(settings);
result = JsonDeserializer::Load(object, objectType, root, context);
result = JsonDeserializer::Load(object, objectType, root, false, context);
}
return result;
}

Loading…
Cancel
Save