Implemented a deferred LoadLevel queue for the SpawnableLevelSystem (#4561)
* Moved the SettingsRegistryTests.cpp and SettingsRegistryMergeUtilsTests.cpp to the Settings folder Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Implemented a deferred level load queue, that allows the SpawnableLevelSystem to re-run the last LoadLevel command that occured before it was constructed. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added SettingsRegistryVisitorUtils to reduce Array and Object visitor boilerplate. The VisitArray and VisitObject functions allows iteration over each element of array and object respectively via a callback. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed the queuing logic for levels that attempt to load before the SpawnableLevelSystem is available Only the last level name that could not load is stored off and deferred until the SpawnableLevelsystem is created. Made the FieldVisitor AggregateTypes constructor protected and added a comment specifying the expected values. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Bring in the SettingsRegistry::Visitor::Visit functions into scope to fix MSVC compilation errors. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Changed the list of supported SettingsRegistry types to visit to an enum to constrain the values to Array and/or Object. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
e4d3ab118c
commit
7b1dd01d1d
@@ -204,14 +204,14 @@ namespace AZ
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called before a file is merged.
|
||||
//! @callback The function to call before a file is merged.
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent (PreMergeEventCallback&& callback) = 0;
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(PreMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent (PostMergeEventCallback&& callback) = 0;
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(PostMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Gets the boolean value at the provided path.
|
||||
//! @param result The target to write the result to.
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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/Settings/SettingsRegistryVisitorUtils.h>
|
||||
|
||||
|
||||
namespace AZ::SettingsRegistryVisitorUtils
|
||||
{
|
||||
// Field Visitor implementation
|
||||
FieldVisitor::FieldVisitor() = default;
|
||||
FieldVisitor::FieldVisitor(VisitFieldType visitFieldType)
|
||||
: m_visitFieldType{ visitFieldType }
|
||||
{
|
||||
}
|
||||
|
||||
auto FieldVisitor::Traverse(AZStd::string_view path, AZStd::string_view valueName,
|
||||
VisitAction action, Type type) -> VisitResponse
|
||||
{
|
||||
// A default response skip prevents visiting grand children(depth 2 or lower)
|
||||
VisitResponse visitResponse = VisitResponse::Skip;
|
||||
if (action == VisitAction::Begin)
|
||||
{
|
||||
// Invoke FieldVisitor override if the root path has been set
|
||||
if (m_rootPath.has_value())
|
||||
{
|
||||
Visit(path, valueName, type);
|
||||
}
|
||||
// To make sure only the direct children are visited(depth 1)
|
||||
// set the root path once and set the VisitReponsoe
|
||||
// to Continue to recurse into is fields
|
||||
if (!m_rootPath.has_value())
|
||||
{
|
||||
bool visitableFieldType{};
|
||||
switch (m_visitFieldType)
|
||||
{
|
||||
case VisitFieldType::Array:
|
||||
visitableFieldType = type == Type::Array;
|
||||
break;
|
||||
case VisitFieldType::Object:
|
||||
visitableFieldType = type == Type::Object;
|
||||
break;
|
||||
case VisitFieldType::ArrayOrObject:
|
||||
visitableFieldType = type == Type::Array || type ==Type::Object;
|
||||
break;
|
||||
default:
|
||||
AZ_Error("FieldVisitor", false, "The field visitation type value is invalid");
|
||||
break;
|
||||
}
|
||||
|
||||
if (visitableFieldType)
|
||||
{
|
||||
m_rootPath = path;
|
||||
visitResponse = VisitResponse::Continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action == VisitAction::Value)
|
||||
{
|
||||
// Invoke FieldVisitor override if the root path has been set
|
||||
if (m_rootPath.has_value())
|
||||
{
|
||||
Visit(path, valueName, type);
|
||||
}
|
||||
}
|
||||
else if (action == VisitAction::End)
|
||||
{
|
||||
// Reset m_rootPath back to null when the root path has finished being visited
|
||||
if (m_rootPath.has_value() && *m_rootPath == path)
|
||||
{
|
||||
m_rootPath = AZStd::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return visitResponse;
|
||||
}
|
||||
|
||||
// Array Visitor implementation
|
||||
ArrayVisitor::ArrayVisitor()
|
||||
: FieldVisitor(VisitFieldType::Array)
|
||||
{
|
||||
}
|
||||
|
||||
// Object Visitor implementation
|
||||
ObjectVisitor::ObjectVisitor()
|
||||
: FieldVisitor(VisitFieldType::Object)
|
||||
{
|
||||
}
|
||||
|
||||
// Generic VisitField Callback implemention
|
||||
template <typename BaseVisitor>
|
||||
bool VisitFieldCallback(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
|
||||
{
|
||||
struct VisitFieldVisitor
|
||||
: BaseVisitor
|
||||
{
|
||||
using BaseVisitor::Visit;
|
||||
VisitFieldVisitor(const VisitorCallback& visitCallback)
|
||||
: m_visitCallback{ visitCallback }
|
||||
{}
|
||||
|
||||
void Visit(AZStd::string_view path, AZStd::string_view fieldIndex, typename BaseVisitor::Type type) override
|
||||
{
|
||||
m_visitCallback(path, fieldIndex, type);
|
||||
}
|
||||
|
||||
const VisitorCallback& m_visitCallback;
|
||||
};
|
||||
|
||||
VisitFieldVisitor visitor{ visitCallback };
|
||||
return settingsRegistry.Visit(visitor, path);
|
||||
}
|
||||
|
||||
// VisitField implementation
|
||||
bool VisitField(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
|
||||
{
|
||||
return VisitFieldCallback<FieldVisitor>(settingsRegistry, visitCallback, path);
|
||||
}
|
||||
|
||||
// VisitArray implementation
|
||||
bool VisitArray(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
|
||||
{
|
||||
return VisitFieldCallback<ArrayVisitor>(settingsRegistry, visitCallback, path);
|
||||
}
|
||||
|
||||
// VisitObject implementation
|
||||
bool VisitObject(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
|
||||
{
|
||||
return VisitFieldCallback<ObjectVisitor>(settingsRegistry, visitCallback, path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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/Settings/SettingsRegistry.h>
|
||||
|
||||
|
||||
namespace AZ::SettingsRegistryVisitorUtils
|
||||
{
|
||||
//! Interface for visiting the fields of an array or object
|
||||
//! To access the values, use the SettingsRegistryInterface Get/GetObject methods
|
||||
struct FieldVisitor
|
||||
: public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using VisitResponse = AZ::SettingsRegistryInterface::VisitResponse;
|
||||
using VisitAction = AZ::SettingsRegistryInterface::VisitAction;
|
||||
using Type = AZ::SettingsRegistryInterface::Type;
|
||||
|
||||
FieldVisitor();
|
||||
|
||||
// Bring the base class visitor functions into scope
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
virtual void Visit(AZStd::string_view path, AZStd::string_view arrayIndex, Type type) = 0;
|
||||
|
||||
protected:
|
||||
// VisitFieldType is used for filtering the type of referenced by the root path
|
||||
enum class VisitFieldType
|
||||
{
|
||||
Array,
|
||||
Object,
|
||||
ArrayOrObject
|
||||
};
|
||||
FieldVisitor(const VisitFieldType visitFieldType);
|
||||
private:
|
||||
VisitResponse Traverse(AZStd::string_view path, AZStd::string_view valueName,
|
||||
VisitAction action, Type type) override;
|
||||
|
||||
VisitFieldType m_visitFieldType{ VisitFieldType::ArrayOrObject };
|
||||
AZStd::optional<AZ::SettingsRegistryInterface::FixedValueString> m_rootPath;
|
||||
};
|
||||
|
||||
//! Interface for visiting the fields of an array
|
||||
//! To access the values, use the SettingsRegistryInterface Get/GetObject methods
|
||||
struct ArrayVisitor
|
||||
: public FieldVisitor
|
||||
{
|
||||
ArrayVisitor();
|
||||
};
|
||||
|
||||
//! Interface for visiting the fields of an object
|
||||
//! To access the values, use the SettingsRegistryInterface Get/GetObject methods
|
||||
struct ObjectVisitor
|
||||
: public FieldVisitor
|
||||
{
|
||||
ObjectVisitor();
|
||||
};
|
||||
|
||||
//! Signature of callback funcition invoked when visiting an element of an array or object
|
||||
using VisitorCallback = AZStd::function<void(AZStd::string_view path, AZStd::string_view fieldName,
|
||||
AZ::SettingsRegistryInterface::Type)>;
|
||||
|
||||
//! Invokes the visitor callback for each element of either the array or object at @path
|
||||
//! If @path is not an array or object, then no elements are visited
|
||||
//! This function will not recurse into children of elements
|
||||
//! @visitCallback functor that is invoked for each array or object element found
|
||||
bool VisitField(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
|
||||
//! Invokes the visitor callback for each element of the array at @path
|
||||
//! If @path is not an array, then no elements are visited
|
||||
//! This function will not recurse into children of elements
|
||||
//! @visitCallback functor that is invoked for each array element found
|
||||
bool VisitArray(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
|
||||
//! Invokes the visitor callback for each element of the object at @path
|
||||
//! If @path is not an object, then no elements are visited
|
||||
//! This function will not recurse into children of elements
|
||||
//! @visitCallback functor that is invoked for each object element found
|
||||
bool VisitObject(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
|
||||
}
|
||||
@@ -566,6 +566,8 @@ set(FILES
|
||||
Settings/SettingsRegistryMergeUtils.h
|
||||
Settings/SettingsRegistryScriptUtils.cpp
|
||||
Settings/SettingsRegistryScriptUtils.h
|
||||
Settings/SettingsRegistryVisitorUtils.cpp
|
||||
Settings/SettingsRegistryVisitorUtils.h
|
||||
State/HSM.cpp
|
||||
State/HSM.h
|
||||
Statistics/NamedRunningStatistic.h
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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/Settings/SettingsRegistryImpl.h>
|
||||
#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace SettingsRegistryVisitorUtilsTests
|
||||
{
|
||||
struct VisitCallbackParams
|
||||
{
|
||||
AZStd::string_view m_inputJsonDocument;
|
||||
using VisitFieldFunction = bool(*)(AZ::SettingsRegistryInterface&,
|
||||
const AZ::SettingsRegistryVisitorUtils::VisitorCallback&,
|
||||
AZStd::string_view);
|
||||
|
||||
static inline constexpr size_t MaxFieldCount = 10;
|
||||
using ObjectFields = AZStd::fixed_vector<AZStd::pair<AZStd::string_view, AZStd::string_view>, MaxFieldCount>;
|
||||
using ArrayFields = AZStd::fixed_vector<AZStd::string_view, MaxFieldCount>;
|
||||
ObjectFields m_objectFields;
|
||||
ArrayFields m_arrayFields;
|
||||
};
|
||||
|
||||
template <typename VisitorParams>
|
||||
class SettingsRegistryVisitorUtilsParamFixture
|
||||
: public UnitTest::ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<VisitorParams>
|
||||
{
|
||||
public:
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
m_registry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_registry.reset();
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::SettingsRegistryImpl> m_registry;
|
||||
};
|
||||
|
||||
using SettingsRegistryVisitCallbackFixture = SettingsRegistryVisitorUtilsParamFixture<VisitCallbackParams>;
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitFieldsOfArrayType_ReturnsFields)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, VisitCallbackParams::MaxFieldCount> testArrayFields;
|
||||
auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testArrayFields.emplace_back(AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitField(*m_registry, visitorCallback, "/Test/Array");
|
||||
|
||||
const AZStd::fixed_vector<AZStd::string, VisitCallbackParams::MaxFieldCount> expectedFields{
|
||||
visitParams.m_arrayFields.begin(), visitParams.m_arrayFields.end() };
|
||||
EXPECT_THAT(testArrayFields, ::testing::ContainerEq(expectedFields));
|
||||
}
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitFieldsOfObjectType_ReturnsFields)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::pair<AZStd::string, AZStd::string>, VisitCallbackParams::MaxFieldCount> testObjectFields;
|
||||
auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitField(*m_registry, visitorCallback, "/Test/Object");
|
||||
|
||||
const AZStd::fixed_vector<AZStd::pair<AZStd::string, AZStd::string>, VisitCallbackParams::MaxFieldCount> expectedFields{
|
||||
visitParams.m_objectFields.begin(), visitParams.m_objectFields.end() };
|
||||
EXPECT_THAT(testObjectFields, ::testing::ContainerEq(expectedFields));
|
||||
}
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitArrayOfArrayType_ReturnsFields)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, VisitCallbackParams::MaxFieldCount> testArrayFields;
|
||||
auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testArrayFields.emplace_back(AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitArray(*m_registry, visitorCallback, "/Test/Array");
|
||||
|
||||
const AZStd::fixed_vector<AZStd::string, VisitCallbackParams::MaxFieldCount> expectedArrayFields{
|
||||
visitParams.m_arrayFields.begin(), visitParams.m_arrayFields.end() };
|
||||
EXPECT_THAT(testArrayFields, ::testing::ContainerEq(expectedArrayFields));
|
||||
}
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitArrayOfObjectType_ReturnsEmpty)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, VisitCallbackParams::MaxFieldCount> testArrayFields;
|
||||
auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testArrayFields.emplace_back(AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitArray(*m_registry, visitorCallback, "/Test/Object");
|
||||
|
||||
EXPECT_TRUE(testArrayFields.empty());
|
||||
}
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitObjectOfArrayType_ReturnsEmpty)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::pair<AZStd::string, AZStd::string>, VisitCallbackParams::MaxFieldCount> testObjectFields;
|
||||
auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitObject(*m_registry, visitorCallback, "/Test/Array");
|
||||
|
||||
EXPECT_TRUE(testObjectFields.empty());
|
||||
}
|
||||
|
||||
TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitObjectOfObjectType_ReturnsFields)
|
||||
{
|
||||
const VisitCallbackParams& visitParams = GetParam();
|
||||
|
||||
ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
|
||||
|
||||
AZStd::fixed_vector<AZStd::pair<AZStd::string, AZStd::string>, VisitCallbackParams::MaxFieldCount> testObjectFields;
|
||||
auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
AZStd::string fieldValue;
|
||||
EXPECT_TRUE(m_registry->Get(fieldValue, path));
|
||||
testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
|
||||
};
|
||||
|
||||
AZ::SettingsRegistryVisitorUtils::VisitObject(*m_registry, visitorCallback, "/Test/Object");
|
||||
|
||||
const AZStd::fixed_vector<AZStd::pair<AZStd::string, AZStd::string>, VisitCallbackParams::MaxFieldCount> expectedObjectFields{
|
||||
visitParams.m_objectFields.begin(), visitParams.m_objectFields.end() };
|
||||
EXPECT_THAT(testObjectFields, ::testing::ContainerEq(expectedObjectFields));
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VisitField,
|
||||
SettingsRegistryVisitCallbackFixture,
|
||||
::testing::Values(
|
||||
VisitCallbackParams
|
||||
{
|
||||
R"({)" "\n"
|
||||
R"( "Test":)" "\n"
|
||||
R"( {)" "\n"
|
||||
R"( "Array": [ "Hello", "World" ],)" "\n"
|
||||
R"( "Object": { "Foo": "Hello", "Bar": "World"})" "\n"
|
||||
R"( })" "\n"
|
||||
R"(})" "\n",
|
||||
VisitCallbackParams::ObjectFields{{"Foo", "Hello"}, {"Bar", "World"}},
|
||||
VisitCallbackParams::ArrayFields{"Hello", "World"}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -75,11 +75,12 @@ set(FILES
|
||||
Name/NameJsonSerializerTests.cpp
|
||||
Name/NameTests.cpp
|
||||
RTTI/TypeSafeIntegralTests.cpp
|
||||
SettingsRegistryTests.cpp
|
||||
SettingsRegistryMergeUtilsTests.cpp
|
||||
Settings/CommandLineTests.cpp
|
||||
Settings/SettingsRegistryTests.cpp
|
||||
Settings/SettingsRegistryConsoleUtilsTests.cpp
|
||||
Settings/SettingsRegistryMergeUtilsTests.cpp
|
||||
Settings/SettingsRegistryScriptUtilsTests.cpp
|
||||
Settings/SettingsRegistryVisitorUtilsTests.cpp
|
||||
Streamer/BlockCacheTests.cpp
|
||||
Streamer/DedicatedCacheTests.cpp
|
||||
Streamer/FullDecompressorTests.cpp
|
||||
|
||||
@@ -22,22 +22,33 @@
|
||||
#include <LyShine/ILyShine.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
|
||||
namespace LegacyLevelSystem
|
||||
{
|
||||
constexpr AZStd::string_view DeferredLoadLevelKey = "/O3DE/Runtime/SpawnableLevelSystem/DeferredLoadLevel";
|
||||
//------------------------------------------------------------------------
|
||||
static void LoadLevel(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
AZ_Error("SpawnableLevelSystem", !arguments.empty(), "LoadLevel requires a level file name to be provided.");
|
||||
AZ_Error("SpawnableLevelSystem", arguments.size() == 1, "LoadLevel requires a single level file name to be provided.");
|
||||
|
||||
if (!arguments.empty() && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
|
||||
if (!arguments.empty() && gEnv && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
|
||||
{
|
||||
gEnv->pSystem->GetILevelSystem()->LoadLevel(arguments[0].data());
|
||||
}
|
||||
else if (!arguments.empty())
|
||||
{
|
||||
// The SpawnableLevelSystem isn't available yet.
|
||||
// Defer the level load until later by storing it in the SettingsRegistry
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Set(DeferredLoadLevelKey, arguments.front());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@@ -45,7 +56,7 @@ namespace LegacyLevelSystem
|
||||
{
|
||||
AZ_Warning("SpawnableLevelSystem", !arguments.empty(), "UnloadLevel doesn't use any arguments.");
|
||||
|
||||
if (gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
|
||||
if (gEnv && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
|
||||
{
|
||||
gEnv->pSystem->GetILevelSystem()->UnloadLevel();
|
||||
}
|
||||
@@ -73,6 +84,24 @@ namespace LegacyLevelSystem
|
||||
}
|
||||
|
||||
AzFramework::RootSpawnableNotificationBus::Handler::BusConnect();
|
||||
|
||||
// If there were LoadLevel command invocations before the creation of the level system
|
||||
// then those invocations were queued.
|
||||
// load the last level in the queue, since only one level can be loaded at a time
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if (AZ::SettingsRegistryInterface::FixedValueString deferredLevelName;
|
||||
settingsRegistry->Get(deferredLevelName, DeferredLoadLevelKey) && !deferredLevelName.empty())
|
||||
{
|
||||
// since this is the constructor any derived classes vtables aren't setup yet
|
||||
// call this class LoadLevel function
|
||||
AZ_TracePrintf("SpawnableLevelSystem", "The Level System is now available."
|
||||
" Loading level %s which could not be loaded earlier\n", deferredLevelName.c_str());
|
||||
SpawnableLevelSystem::LoadLevel(deferredLevelName.c_str());
|
||||
// Delete the key with the deferred level name
|
||||
settingsRegistry->Remove(DeferredLoadLevelKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@@ -173,7 +202,7 @@ namespace LegacyLevelSystem
|
||||
}
|
||||
|
||||
// Make sure a spawnable level exists that matches levelname
|
||||
AZStd::string validLevelName = "";
|
||||
AZStd::string validLevelName;
|
||||
AZ::Data::AssetId rootSpawnableAssetId;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
rootSpawnableAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, levelName, nullptr, false);
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"Excludes":
|
||||
[
|
||||
"/Amazon/AzCore/Runtime",
|
||||
"/Amazon/AzCore/Bootstrap/project_path"
|
||||
"/Amazon/AzCore/Bootstrap/project_path",
|
||||
"/O3DE/Runtime",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user