Address some review feedback, remove DomBackendRegistry
Signed-off-by: Nicholas Van Sickle <nvsickle@amazon.com>
This commit is contained in:
@@ -8,9 +8,7 @@
|
||||
|
||||
#include <AzCore/DOM/Backends/JSON/JsonBackend.h>
|
||||
|
||||
#include <AzCore/DOM/DomBackendRegistry.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
Visitor::Result JsonBackend::ReadFromStringInPlace(AZStd::string& buffer, Visitor* visitor)
|
||||
{
|
||||
@@ -26,12 +24,4 @@ namespace AZ::DOM
|
||||
{
|
||||
return Json::GetJsonStreamWriter(stream, Json::OutputFormatting::PrettyPrintedJson);
|
||||
}
|
||||
|
||||
void JsonBackend::Register()
|
||||
{
|
||||
if (auto backendRegistry = BackendRegistry::Get())
|
||||
{
|
||||
backendRegistry->RegisterBackend<JsonBackend>(kName, {kExtension});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <AzCore/DOM/DomBackend.h>
|
||||
#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
class JsonBackend final : public Backend
|
||||
{
|
||||
@@ -19,9 +19,5 @@ namespace AZ::DOM
|
||||
Visitor::Result ReadFromStringInPlace(AZStd::string& buffer, Visitor* visitor) override;
|
||||
Visitor::Result ReadFromString(AZStd::string_view buffer, Lifetime lifetime, Visitor* visitor) override;
|
||||
AZStd::unique_ptr<Visitor> CreateStreamWriter(AZ::IO::GenericStream* stream) override;
|
||||
|
||||
static constexpr const char* kName = "JSON";
|
||||
static constexpr const char* kExtension = ".json";
|
||||
static void Register();
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
} // namespace AZ::Dom
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
|
||||
namespace AZ::DOM::Json
|
||||
namespace AZ::Dom::Json
|
||||
{
|
||||
//
|
||||
// class DocumentWriter
|
||||
@@ -73,7 +73,7 @@ namespace AZ::DOM::Json
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentValue().SetString(value.data(), static_cast<rapidjson::SizeType>(value.size()));
|
||||
CurrentValue().SetString(value.data(), static_cast<rapidjson::SizeType>(value.length()));
|
||||
}
|
||||
return FinishWrite();
|
||||
}
|
||||
@@ -210,11 +210,11 @@ namespace AZ::DOM::Json
|
||||
{
|
||||
}
|
||||
|
||||
bool m_isObject;
|
||||
rapidjson::Value& m_container;
|
||||
rapidjson::Value m_value;
|
||||
AZ::u64 m_entryCount = 0;
|
||||
rapidjson::Value m_key;
|
||||
rapidjson::Value m_value;
|
||||
rapidjson::Value& m_container;
|
||||
AZ::u64 m_entryCount = 0;
|
||||
bool m_isObject;
|
||||
};
|
||||
|
||||
rapidjson::Document m_result;
|
||||
@@ -225,13 +225,13 @@ namespace AZ::DOM::Json
|
||||
// class StreamWriter
|
||||
//
|
||||
// Visitor that writes to a rapidjson::Writer
|
||||
template<class TWriter>
|
||||
template<class Writer>
|
||||
class StreamWriter : public Visitor
|
||||
{
|
||||
public:
|
||||
StreamWriter(AZ::IO::GenericStream* stream)
|
||||
: m_streamWriter(stream)
|
||||
, m_writer(TWriter(m_streamWriter))
|
||||
, m_writer(Writer(m_streamWriter))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -305,22 +305,25 @@ namespace AZ::DOM::Json
|
||||
private:
|
||||
Result CheckWrite(bool writeSucceeded)
|
||||
{
|
||||
if (!writeSucceeded)
|
||||
if (writeSucceeded)
|
||||
{
|
||||
return VisitorSuccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
return VisitorFailure(VisitorErrorCode::InternalError, "Failed to write JSON");
|
||||
}
|
||||
return VisitorSuccess();
|
||||
}
|
||||
|
||||
AZ::IO::RapidJSONStreamWriter m_streamWriter;
|
||||
TWriter m_writer;
|
||||
Writer m_writer;
|
||||
};
|
||||
|
||||
//
|
||||
// struct JsonReadHandler
|
||||
//
|
||||
// Handler for a rapidjson::Reader that translates reads into an AZ::DOM::Visitor
|
||||
struct JsonReadHandler : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, JsonReadHandler>
|
||||
// Handler for a rapidjson::Reader that translates reads into an AZ::Dom::Visitor
|
||||
struct JsonReadHandler
|
||||
{
|
||||
public:
|
||||
JsonReadHandler(Visitor* visitor, Lifetime stringLifetime)
|
||||
@@ -365,13 +368,13 @@ namespace AZ::DOM::Json
|
||||
return CheckResult(m_visitor->Double(d));
|
||||
}
|
||||
|
||||
bool RawNumber([[maybe_unused]] const Ch* str, [[maybe_unused]] rapidjson::SizeType length, [[maybe_unused]] bool copy)
|
||||
bool RawNumber([[maybe_unused]] const char* str, [[maybe_unused]] rapidjson::SizeType length, [[maybe_unused]] bool copy)
|
||||
{
|
||||
AZ_Assert(false, "Raw numbers are unsupported");
|
||||
AZ_Assert(false, "Raw numbers are unsupported in the rapidjson DOM backend");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool String(const Ch* str, rapidjson::SizeType length, bool copy)
|
||||
bool String(const char* str, rapidjson::SizeType length, bool copy)
|
||||
{
|
||||
Lifetime lifetime = m_stringLifetime;
|
||||
if (!copy)
|
||||
@@ -386,7 +389,7 @@ namespace AZ::DOM::Json
|
||||
return CheckResult(m_visitor->StartObject());
|
||||
}
|
||||
|
||||
bool Key(const Ch* str, rapidjson::SizeType length, [[maybe_unused]] bool copy)
|
||||
bool Key(const char* str, rapidjson::SizeType length, [[maybe_unused]] bool copy)
|
||||
{
|
||||
AZStd::string_view key = AZStd::string_view(str, length);
|
||||
if (!m_visitor->SupportsRawKeys())
|
||||
@@ -552,17 +555,18 @@ namespace AZ::DOM::Json
|
||||
|
||||
Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor* visitor, Lifetime lifetime)
|
||||
{
|
||||
enum class EndMarker
|
||||
struct EndArrayMarker
|
||||
{
|
||||
};
|
||||
struct EndObjectMarker
|
||||
{
|
||||
EndArray,
|
||||
EndObject
|
||||
};
|
||||
|
||||
// Processing stack consists of values comprised of one of a:
|
||||
// - rapidjson::Value to process
|
||||
// - EndMarker denoting the end of an array or object
|
||||
// - EndArrayMarker or EndObjectMarker denoting the end of an array or object
|
||||
// - string denoting a key at the beginning of a key/value pair
|
||||
using Entry = AZStd::variant<const rapidjson::Value*, EndMarker, AZStd::string_view>;
|
||||
using Entry = AZStd::variant<const rapidjson::Value*, EndArrayMarker, EndObjectMarker, AZStd::string_view>;
|
||||
AZStd::stack<Entry> entryStack;
|
||||
AZStd::stack<u64> entryCountStack;
|
||||
entryStack.push(&value);
|
||||
@@ -572,97 +576,99 @@ namespace AZ::DOM::Json
|
||||
const auto currentEntry = entryStack.top();
|
||||
entryStack.pop();
|
||||
|
||||
if (AZStd::holds_alternative<EndMarker>(currentEntry))
|
||||
{
|
||||
EndMarker marker = AZStd::get<EndMarker>(currentEntry);
|
||||
if (marker == EndMarker::EndArray)
|
||||
{
|
||||
visitor->EndArray(entryCountStack.top());
|
||||
}
|
||||
else
|
||||
{
|
||||
visitor->EndObject(entryCountStack.top());
|
||||
}
|
||||
entryCountStack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AZStd::holds_alternative<AZStd::string_view>(currentEntry))
|
||||
{
|
||||
AZStd::string_view key = AZStd::get<AZStd::string_view>(currentEntry);
|
||||
if (visitor->SupportsRawKeys())
|
||||
{
|
||||
visitor->RawKey(key, lifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
visitor->Key(AZ::Name(key));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const rapidjson::Value& currentValue = *AZStd::get<const rapidjson::Value*>(currentEntry);
|
||||
if (!entryCountStack.empty())
|
||||
{
|
||||
++entryCountStack.top();
|
||||
}
|
||||
|
||||
Visitor::Result result = AZ::Success();
|
||||
|
||||
switch (currentValue.GetType())
|
||||
{
|
||||
case rapidjson::kNullType:
|
||||
result = visitor->Null();
|
||||
break;
|
||||
case rapidjson::kFalseType:
|
||||
result = visitor->Bool(false);
|
||||
break;
|
||||
case rapidjson::kTrueType:
|
||||
result = visitor->Bool(true);
|
||||
break;
|
||||
case rapidjson::kObjectType:
|
||||
entryStack.push(EndMarker::EndObject);
|
||||
entryCountStack.push(0);
|
||||
result = visitor->StartObject();
|
||||
for (auto it = currentValue.MemberEnd(); it != currentValue.MemberBegin(); --it)
|
||||
AZStd::visit(
|
||||
[visitor, &entryStack, &entryCountStack, &result, lifetime](auto&& arg)
|
||||
{
|
||||
auto entry = (it - 1);
|
||||
const AZStd::string_view key(entry->name.GetString(), static_cast<size_t>(entry->name.GetStringLength()));
|
||||
entryStack.push(&entry->value);
|
||||
entryStack.push(key);
|
||||
}
|
||||
break;
|
||||
case rapidjson::kArrayType:
|
||||
entryStack.push(EndMarker::EndArray);
|
||||
entryCountStack.push(0);
|
||||
result = visitor->StartArray();
|
||||
for (auto it = currentValue.End(); it != currentValue.Begin(); --it)
|
||||
{
|
||||
auto entry = (it - 1);
|
||||
entryStack.push(entry);
|
||||
}
|
||||
break;
|
||||
case rapidjson::kStringType:
|
||||
result = visitor->String(
|
||||
AZStd::string_view(currentValue.GetString(), static_cast<size_t>(currentValue.GetStringLength())), lifetime);
|
||||
break;
|
||||
case rapidjson::kNumberType:
|
||||
if (currentValue.IsFloat() || currentValue.IsDouble())
|
||||
{
|
||||
result = visitor->Double(currentValue.GetDouble());
|
||||
}
|
||||
else if (currentValue.IsInt64() || currentValue.IsInt())
|
||||
{
|
||||
result = visitor->Int64(currentValue.GetInt64());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = visitor->Uint64(currentValue.GetUint64());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return AZ::Failure(VisitorError(VisitorErrorCode::InvalidData, "Value with invalid type specified"));
|
||||
}
|
||||
using Alternative = AZStd::decay_t<decltype(arg)>;
|
||||
if constexpr (AZStd::is_same_v<Alternative, const rapidjson::Value*>)
|
||||
{
|
||||
const rapidjson::Value& currentValue = *arg;
|
||||
if (!entryCountStack.empty())
|
||||
{
|
||||
++entryCountStack.top();
|
||||
}
|
||||
|
||||
switch (currentValue.GetType())
|
||||
{
|
||||
case rapidjson::kNullType:
|
||||
result = visitor->Null();
|
||||
break;
|
||||
case rapidjson::kFalseType:
|
||||
result = visitor->Bool(false);
|
||||
break;
|
||||
case rapidjson::kTrueType:
|
||||
result = visitor->Bool(true);
|
||||
break;
|
||||
case rapidjson::kObjectType:
|
||||
entryStack.push(EndObjectMarker{});
|
||||
entryCountStack.push(0);
|
||||
result = visitor->StartObject();
|
||||
for (auto it = currentValue.MemberEnd(); it != currentValue.MemberBegin(); --it)
|
||||
{
|
||||
auto entry = (it - 1);
|
||||
const AZStd::string_view key(entry->name.GetString(), static_cast<size_t>(entry->name.GetStringLength()));
|
||||
entryStack.push(&entry->value);
|
||||
entryStack.push(key);
|
||||
}
|
||||
break;
|
||||
case rapidjson::kArrayType:
|
||||
entryStack.push(EndArrayMarker{});
|
||||
entryCountStack.push(0);
|
||||
result = visitor->StartArray();
|
||||
for (auto it = currentValue.End(); it != currentValue.Begin(); --it)
|
||||
{
|
||||
auto entry = (it - 1);
|
||||
entryStack.push(entry);
|
||||
}
|
||||
break;
|
||||
case rapidjson::kStringType:
|
||||
result = visitor->String(
|
||||
AZStd::string_view(currentValue.GetString(), static_cast<size_t>(currentValue.GetStringLength())),
|
||||
lifetime);
|
||||
break;
|
||||
case rapidjson::kNumberType:
|
||||
if (currentValue.IsFloat() || currentValue.IsDouble())
|
||||
{
|
||||
result = visitor->Double(currentValue.GetDouble());
|
||||
}
|
||||
else if (currentValue.IsInt64() || currentValue.IsInt())
|
||||
{
|
||||
result = visitor->Int64(currentValue.GetInt64());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = visitor->Uint64(currentValue.GetUint64());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = AZ::Failure(VisitorError(VisitorErrorCode::InvalidData, "Value with invalid type specified"));
|
||||
}
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Alternative, EndArrayMarker>)
|
||||
{
|
||||
result = visitor->EndArray(entryCountStack.top());
|
||||
entryCountStack.pop();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Alternative, EndObjectMarker>)
|
||||
{
|
||||
result = visitor->EndObject(entryCountStack.top());
|
||||
entryCountStack.pop();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Alternative, AZStd::string_view>)
|
||||
{
|
||||
if (visitor->SupportsRawKeys())
|
||||
{
|
||||
visitor->RawKey(arg, lifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
visitor->Key(AZ::Name(arg));
|
||||
}
|
||||
}
|
||||
},
|
||||
currentEntry);
|
||||
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
@@ -672,4 +678,4 @@ namespace AZ::DOM::Json
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
} // namespace AZ::DOM::Json
|
||||
} // namespace AZ::Dom::Json
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ::DOM::Json
|
||||
namespace AZ::Dom::Json
|
||||
{
|
||||
//! Specifies how JSON should be formatted when serialized.
|
||||
enum class OutputFormatting
|
||||
@@ -57,4 +57,4 @@ namespace AZ::DOM::Json
|
||||
//! before the visitor is finished using these values, Lifetime::Temporary should be specified.
|
||||
//! \return The aggregate result specifying whether the visitor operations were successful.
|
||||
Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor* visitor, Lifetime lifetime);
|
||||
} // namespace AZ::DOM::Json
|
||||
} // namespace AZ::Dom::Json
|
||||
|
||||
@@ -12,20 +12,8 @@
|
||||
#include <AzCore/IO/ByteContainerStream.h>
|
||||
#include "DomBackend.h"
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
Visitor::Result Backend::ReadFromPath(AZ::IO::PathView pathName, Visitor* visitor, size_t maxFileSize)
|
||||
{
|
||||
auto readResult = AZ::Utils::ReadFile(pathName.Native(), maxFileSize);
|
||||
if (!readResult.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(VisitorError(VisitorErrorCode::InternalError, readResult.TakeError()));
|
||||
}
|
||||
|
||||
AZStd::string fileContents = readResult.TakeValue();
|
||||
return ReadFromString(fileContents, Lifetime::Temporary, visitor);
|
||||
}
|
||||
|
||||
Visitor::Result Backend::ReadFromStream(AZ::IO::GenericStream* stream, Visitor* visitor, size_t maxSize)
|
||||
{
|
||||
size_t length = stream->GetLength();
|
||||
@@ -34,7 +22,7 @@ namespace AZ::DOM
|
||||
return AZ::Failure(VisitorError(VisitorErrorCode::InternalError, "Stream is too large."));
|
||||
}
|
||||
AZStd::string buffer;
|
||||
buffer.resize(maxSize);
|
||||
buffer.resize(length);
|
||||
stream->Read(length, buffer.data());
|
||||
return ReadFromString(buffer, Lifetime::Temporary, visitor);
|
||||
}
|
||||
@@ -50,24 +38,6 @@ namespace AZ::DOM
|
||||
return callback(writer.get());
|
||||
}
|
||||
|
||||
Visitor::Result Backend::WriteToPath(AZ::IO::PathView pathName, WriteCallback callback)
|
||||
{
|
||||
AZStd::string buffer;
|
||||
auto serializeResult = WriteToString(buffer, callback);
|
||||
if (!serializeResult.IsSuccess())
|
||||
{
|
||||
return serializeResult;
|
||||
}
|
||||
|
||||
auto writeResult = AZ::Utils::WriteFile(buffer, pathName.Native());
|
||||
if (!writeResult.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(VisitorError(VisitorErrorCode::InternalError, writeResult.TakeError()));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
Visitor::Result Backend::WriteToString(AZStd::string& buffer, WriteCallback callback)
|
||||
{
|
||||
AZ::IO::ByteContainerStream<AZStd::string> stream{&buffer};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
//! Backends are registered centrally and used to transition DOM formats to and from a textual format.
|
||||
class Backend
|
||||
@@ -22,9 +22,6 @@ namespace AZ::DOM
|
||||
public:
|
||||
virtual ~Backend() = default;
|
||||
|
||||
//! Attempt to read this format from the given file into the target Visitor.
|
||||
Visitor::Result ReadFromPath(
|
||||
AZ::IO::PathView pathName, Visitor* visitor, size_t maxFileSize = AZStd::numeric_limits<size_t>::max());
|
||||
//! Attempt to read this format from the given stream into the target Visitor.
|
||||
//! The base implementation reads the stream into memory and calls ReadFromString.
|
||||
virtual Visitor::Result ReadFromStream(
|
||||
@@ -46,9 +43,7 @@ namespace AZ::DOM
|
||||
using WriteCallback = AZStd::function<Visitor::Result(Visitor*)>;
|
||||
//! Attempt to write a value to a stream using a write callback.
|
||||
Visitor::Result WriteToStream(AZ::IO::GenericStream* stream, WriteCallback callback);
|
||||
//! Attempt to write a value to a file using a write callback.
|
||||
Visitor::Result WriteToPath(AZ::IO::PathView pathName, WriteCallback callback);
|
||||
//! Attempt to write a value to a string using a write callback.
|
||||
Visitor::Result WriteToString(AZStd::string& buffer, WriteCallback callback);
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
} // namespace AZ::Dom
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomBackendRegistry.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
BackendRegistry* BackendRegistry::s_instance = nullptr;
|
||||
|
||||
BackendRegistryInterface* BackendRegistry::Get()
|
||||
{
|
||||
return AZ::Interface<BackendRegistryInterface>::Get();
|
||||
}
|
||||
|
||||
void BackendRegistry::Create()
|
||||
{
|
||||
AZ_Assert(!s_instance, "Attempted to register BackendRegistry when it's already registered");
|
||||
s_instance = aznew BackendRegistry;
|
||||
AZ::Interface<BackendRegistryInterface>::Register(s_instance);
|
||||
}
|
||||
|
||||
void BackendRegistry::Destroy()
|
||||
{
|
||||
AZ_Assert(s_instance, "Attempted to unregister a non-existent BackendRegistry");
|
||||
AZ::Interface<BackendRegistryInterface>::Unregister(s_instance);
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Backend> BackendRegistry::GetBackendByName(AZStd::string_view name)
|
||||
{
|
||||
auto backendIterator = m_nameToBackend.find(name);
|
||||
if (backendIterator != m_nameToBackend.end())
|
||||
{
|
||||
return backendIterator->second();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Backend> BackendRegistry::GetBackendForExtension(AZStd::string_view extension)
|
||||
{
|
||||
auto extensionIterator = m_extensionToName.find(extension);
|
||||
if (extensionIterator != m_extensionToName.end())
|
||||
{
|
||||
return GetBackendByName(extensionIterator->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BackendRegistry::RegisterBackendInternal(
|
||||
BackendRegistryInterface::BackendFactory factory, AZStd::string name, AZStd::vector<AZStd::string> extensions)
|
||||
{
|
||||
AZ_Assert(m_nameToBackend.find(name) == m_nameToBackend.end(), "DOM Backend %s already registered", name.c_str());
|
||||
m_nameToBackend.insert({name, factory});
|
||||
for (AZStd::string& extension : extensions)
|
||||
{
|
||||
AZ_Assert(m_extensionToName.find(extension) == m_extensionToName.end(), "DOM Extensions already registered", extension.c_str());
|
||||
m_extensionToName.insert({AZStd::move(extension), name});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/DOM/DomBackendRegistryInterface.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
//! DOM backend registry implementation.
|
||||
//! \see BackendRegistryInterface
|
||||
class BackendRegistry final : public BackendRegistryInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BackendRegistry, "{95533861-6201-4E45-BD03-097A20850C48}", BackendRegistryInterface);
|
||||
AZ_CLASS_ALLOCATOR(BackendRegistry, AZ::SystemAllocator, 0);
|
||||
|
||||
AZStd::unique_ptr<Backend> GetBackendByName(AZStd::string_view name) override;
|
||||
AZStd::unique_ptr<Backend> GetBackendForExtension(AZStd::string_view extension) override;
|
||||
|
||||
//! Convenience method, gets the current instance of the BackendRegistry via AZ::Interface.
|
||||
static BackendRegistryInterface* Get();
|
||||
//! Creates a singleton BackendRegistry and registers it via AZ::Interface.
|
||||
static void Create();
|
||||
//! Destroys the singleton BackendRegistry created by Create and unregisters it from AZ::Interface.
|
||||
static void Destroy();
|
||||
|
||||
protected:
|
||||
void RegisterBackendInternal(BackendFactory factory, AZStd::string name, AZStd::vector<AZStd::string> extensions) override;
|
||||
|
||||
private:
|
||||
using BackendFactory = AZStd::function<AZStd::unique_ptr<Backend>()>;
|
||||
AZStd::unordered_map<AZStd::string, BackendFactory> m_nameToBackend;
|
||||
AZStd::unordered_map<AZStd::string, AZStd::string> m_extensionToName;
|
||||
|
||||
static BackendRegistry* s_instance;
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/DOM/DomBackend.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
{
|
||||
//! Central interface for registering and looking up backend types by file extension.
|
||||
class BackendRegistryInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BackendRegistryInterface, "{B72A88AC-DF15-4F92-9489-ABCDEA3D94E6}")
|
||||
using BackendFactory = AZStd::function<AZStd::unique_ptr<Backend>()>;
|
||||
|
||||
virtual ~BackendRegistryInterface() = default;
|
||||
|
||||
//! Registers a factory for a given backend.
|
||||
//! \param name A unique name to identify this backend.
|
||||
//! \param extensions A set of file extensions this backend supports.
|
||||
//! Extensions should by the entire file suffix including any dots (.), for example:
|
||||
//! ".json" or ".tar.gz"
|
||||
template<class TBackend>
|
||||
void RegisterBackend(AZStd::string name, AZStd::vector<AZStd::string> extensions);
|
||||
|
||||
//! Looks up a DOM backend based on its name.
|
||||
virtual AZStd::unique_ptr<Backend> GetBackendByName(AZStd::string_view name) = 0;
|
||||
|
||||
//! Looks up a DOM backend based on a file extension.
|
||||
virtual AZStd::unique_ptr<Backend> GetBackendForExtension(AZStd::string_view extension) = 0;
|
||||
|
||||
protected:
|
||||
//! Registers a factory for a given backend, called by RegisterBackend.
|
||||
//! \param factory The factory function to create new backend instances.
|
||||
//! \param name The unique name to identify this backend.
|
||||
//! \param extensions A set of file extensions this backend supports.
|
||||
//! \see RegisterBackend
|
||||
virtual void RegisterBackendInternal(BackendFactory factory, AZStd::string name, AZStd::vector<AZStd::string> extensions) = 0;
|
||||
};
|
||||
|
||||
template<class TBackend>
|
||||
void BackendRegistryInterface::RegisterBackend(AZStd::string name, AZStd::vector<AZStd::string> extensions)
|
||||
{
|
||||
RegisterBackendInternal([](){
|
||||
return AZStd::make_unique<TBackend>();
|
||||
}, AZStd::move(name), AZStd::move(extensions));
|
||||
}
|
||||
} // namespace AZ::DOM
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <AzCore/DOM/DomVisitor.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
const char* VisitorError::CodeToString(VisitorErrorCode code)
|
||||
{
|
||||
@@ -236,4 +236,4 @@ namespace AZ::DOM
|
||||
{
|
||||
return (GetVisitorFlags() & VisitorFlags::SupportsOpaqueValues) != VisitorFlags::Null;
|
||||
}
|
||||
} // namespace AZ::DOM
|
||||
} // namespace AZ::Dom
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ::DOM
|
||||
namespace AZ::Dom
|
||||
{
|
||||
//
|
||||
// Lifetime enum
|
||||
@@ -243,4 +243,4 @@ namespace AZ::DOM
|
||||
//! Helper method, constructs a success \ref Result.
|
||||
static Result VisitorSuccess();
|
||||
};
|
||||
} // namespace AZ::DOM
|
||||
} // namespace AZ::Dom
|
||||
|
||||
@@ -127,9 +127,6 @@ set(FILES
|
||||
Debug/TraceReflection.h
|
||||
DOM/DomBackend.cpp
|
||||
DOM/DomBackend.h
|
||||
DOM/DomBackendRegistry.cpp
|
||||
DOM/DomBackendRegistry.h
|
||||
DOM/DomBackendRegistryInterface.h
|
||||
DOM/DomVisitor.cpp
|
||||
DOM/DomVisitor.h
|
||||
DOM/Backends/JSON/JsonBackend.cpp
|
||||
|
||||
@@ -20,31 +20,31 @@ namespace Benchmark
|
||||
class DomJsonBenchmark : public UnitTest::AllocatorsBenchmarkFixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& st) override
|
||||
void SetUp(const ::benchmark::State& st) override
|
||||
{
|
||||
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
|
||||
AZ::NameDictionary::Create();
|
||||
}
|
||||
|
||||
void SetUp([[maybe_unused]] ::benchmark::State& st) override
|
||||
void SetUp(::benchmark::State& st) override
|
||||
{
|
||||
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
|
||||
AZ::NameDictionary::Create();
|
||||
}
|
||||
|
||||
void TearDown([[maybe_unused]] ::benchmark::State& st) override
|
||||
void TearDown(::benchmark::State& st) override
|
||||
{
|
||||
AZ::NameDictionary::Destroy();
|
||||
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
|
||||
}
|
||||
|
||||
void TearDown([[maybe_unused]] const ::benchmark::State& st) override
|
||||
void TearDown(const ::benchmark::State& st) override
|
||||
{
|
||||
AZ::NameDictionary::Destroy();
|
||||
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
|
||||
}
|
||||
|
||||
AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount = 100, int64_t stringTemplateLength = 5)
|
||||
AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
|
||||
{
|
||||
rapidjson::Document document;
|
||||
document.SetObject();
|
||||
@@ -120,7 +120,7 @@ namespace Benchmark
|
||||
|
||||
BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocumentInPlace)(benchmark::State& state)
|
||||
{
|
||||
AZ::DOM::JsonBackend backend;
|
||||
AZ::Dom::JsonBackend backend;
|
||||
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
|
||||
|
||||
for (auto _ : state)
|
||||
@@ -129,8 +129,8 @@ namespace Benchmark
|
||||
AZStd::string payloadCopy = serializedPayload;
|
||||
state.ResumeTiming();
|
||||
|
||||
auto result = AZ::DOM::Json::WriteToRapidJsonDocument(
|
||||
[&](AZ::DOM::Visitor* visitor)
|
||||
auto result = AZ::Dom::Json::WriteToRapidJsonDocument(
|
||||
[&](AZ::Dom::Visitor* visitor)
|
||||
{
|
||||
return backend.ReadFromStringInPlace(payloadCopy, visitor);
|
||||
});
|
||||
@@ -144,15 +144,15 @@ namespace Benchmark
|
||||
|
||||
BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocument)(benchmark::State& state)
|
||||
{
|
||||
AZ::DOM::JsonBackend backend;
|
||||
AZ::Dom::JsonBackend backend;
|
||||
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
auto result = AZ::DOM::Json::WriteToRapidJsonDocument(
|
||||
[&](AZ::DOM::Visitor* visitor)
|
||||
auto result = AZ::Dom::Json::WriteToRapidJsonDocument(
|
||||
[&](AZ::Dom::Visitor* visitor)
|
||||
{
|
||||
return backend.ReadFromString(serializedPayload, AZ::DOM::Lifetime::Temporary, visitor);
|
||||
return backend.ReadFromString(serializedPayload, AZ::Dom::Lifetime::Temporary, visitor);
|
||||
});
|
||||
|
||||
benchmark::DoNotOptimize(result.GetValue());
|
||||
@@ -164,7 +164,7 @@ namespace Benchmark
|
||||
|
||||
BENCHMARK_DEFINE_F(DomJsonBenchmark, JsonUtilsDeserializeToDocument)(benchmark::State& state)
|
||||
{
|
||||
AZ::DOM::JsonBackend backend;
|
||||
AZ::Dom::JsonBackend backend;
|
||||
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
|
||||
|
||||
for (auto _ : state)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace AZ::DOM::Tests
|
||||
namespace AZ::Dom::Tests
|
||||
{
|
||||
class DomJsonTests : public UnitTest::AllocatorsFixture
|
||||
{
|
||||
@@ -125,7 +125,7 @@ namespace AZ::DOM::Tests
|
||||
AZStd::string canonicalSerializedDocument;
|
||||
AZ::JsonSerializationUtils::WriteJsonString(*m_document, canonicalSerializedDocument);
|
||||
|
||||
auto visitDocumentFn = [this](AZ::DOM::Visitor* visitor)
|
||||
auto visitDocumentFn = [this](AZ::Dom::Visitor* visitor)
|
||||
{
|
||||
return Json::VisitRapidJsonValue(*m_document, visitor, Lifetime::Persistent);
|
||||
};
|
||||
@@ -149,10 +149,10 @@ namespace AZ::DOM::Tests
|
||||
// string -> Document
|
||||
{
|
||||
auto result = Json::WriteToRapidJsonDocument(
|
||||
[&canonicalSerializedDocument](AZ::DOM::Visitor* visitor)
|
||||
[&canonicalSerializedDocument](AZ::Dom::Visitor* visitor)
|
||||
{
|
||||
JsonBackend backend;
|
||||
return backend.ReadFromString(canonicalSerializedDocument, AZ::DOM::Lifetime::Temporary, visitor);
|
||||
return backend.ReadFromString(canonicalSerializedDocument, AZ::Dom::Lifetime::Temporary, visitor);
|
||||
});
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(DeepCompare(*m_document, result.GetValue()));
|
||||
@@ -164,9 +164,9 @@ namespace AZ::DOM::Tests
|
||||
JsonBackend backend;
|
||||
auto result = backend.WriteToString(
|
||||
serializedDocument,
|
||||
[&backend, &canonicalSerializedDocument](AZ::DOM::Visitor* visitor)
|
||||
[&backend, &canonicalSerializedDocument](AZ::Dom::Visitor* visitor)
|
||||
{
|
||||
return backend.ReadFromString(canonicalSerializedDocument, AZ::DOM::Lifetime::Temporary, visitor);
|
||||
return backend.ReadFromString(canonicalSerializedDocument, AZ::Dom::Lifetime::Temporary, visitor);
|
||||
});
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(canonicalSerializedDocument, serializedDocument);
|
||||
@@ -285,4 +285,4 @@ namespace AZ::DOM::Tests
|
||||
m_document->AddMember(CreateString("long_string"), CreateString("abcdefghijklmnopqrstuvwxyz0123456789"), m_document->GetAllocator());
|
||||
PerformSerializationChecks();
|
||||
}
|
||||
} // namespace AZ::DOM::Tests
|
||||
} // namespace AZ::Dom::Tests
|
||||
|
||||
Reference in New Issue
Block a user