Merge branch 'main' into Atom/dmcdiar/ATOM-14933
This commit is contained in:
@@ -25,7 +25,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Main.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -39,7 +39,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Periodic.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -71,7 +71,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -85,7 +85,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Sandbox.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -101,7 +101,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -120,7 +120,7 @@ endif()
|
||||
# TEST_SUITE main
|
||||
# TEST_SERIAL
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py
|
||||
# TIMEOUT 3600
|
||||
# TIMEOUT 1500
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# Legacy::Editor
|
||||
# Legacy::CryRenderNULL
|
||||
@@ -136,7 +136,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -154,7 +154,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
@@ -173,7 +173,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL TRUE
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -196,7 +196,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 36000
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -212,7 +212,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 36000
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -228,7 +228,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -244,7 +244,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -259,7 +259,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -274,7 +274,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -292,7 +292,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/editor
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
|
||||
@@ -100,7 +100,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
@@ -123,7 +123,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 3600
|
||||
TIMEOUT 1500
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessorBatch
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <AzCore/Jobs/JobManagerComponent.h>
|
||||
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
|
||||
#include <AzCore/Memory/MemoryComponent.h>
|
||||
#include <AzCore/NativeUI/NativeUISystemComponent.h>
|
||||
#include <AzCore/Script/ScriptSystemComponent.h>
|
||||
#include <AzCore/Slice/SliceComponent.h>
|
||||
#include <AzCore/Slice/SliceSystemComponent.h>
|
||||
@@ -43,7 +42,6 @@ namespace AZ
|
||||
AssetManagerComponent::CreateDescriptor(),
|
||||
UserSettingsComponent::CreateDescriptor(),
|
||||
Debug::FrameProfilerComponent::CreateDescriptor(),
|
||||
NativeUI::NativeUISystemComponent::CreateDescriptor(),
|
||||
SliceComponent::CreateDescriptor(),
|
||||
SliceSystemComponent::CreateDescriptor(),
|
||||
SliceMetadataInfoComponent::CreateDescriptor(),
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <AzCore/Memory/AllocatorManager.h>
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
@@ -424,7 +426,7 @@ namespace AZ
|
||||
|
||||
// Now that the Allocators are initialized, the Command Line parameters can be parsed
|
||||
m_commandLine.Parse(m_argC, m_argV);
|
||||
ParseCommandLine(m_commandLine);
|
||||
SettingsRegistryMergeUtils::ParseCommandLine(m_commandLine);
|
||||
|
||||
// Create the settings registry and register it with the AZ interface system
|
||||
// This is done after the AppRoot has been calculated so that the Bootstrap.cfg
|
||||
@@ -527,10 +529,42 @@ namespace AZ
|
||||
DestroyAllocator();
|
||||
}
|
||||
|
||||
|
||||
void ReportBadEngineRoot()
|
||||
{
|
||||
AZStd::string errorMessage = {"Unable to determine a valid path to the engine.\n"
|
||||
"Check parameters such as --project-path and --engine-path and make sure they are valid.\n"};
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString filePathErrorStr;
|
||||
if (registry->Get(filePathErrorStr, AZ::SettingsRegistryMergeUtils::FilePathKey_ErrorText); !filePathErrorStr.empty())
|
||||
{
|
||||
errorMessage += "Additional Info:\n";
|
||||
errorMessage += filePathErrorStr.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI != nullptr)
|
||||
{
|
||||
nativeUI->DisplayOkDialog("O3DE Fatal Error", errorMessage.c_str(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ComponentApplication", false, "O3DE Fatal Error: %s\n", errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Entity* ComponentApplication::Create(const Descriptor& descriptor, const StartupParameters& startupParameters)
|
||||
{
|
||||
AZ_Assert(!m_isStarted, "Component application already started!");
|
||||
|
||||
if (m_engineRoot.empty())
|
||||
{
|
||||
ReportBadEngineRoot();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_startupParameters = startupParameters;
|
||||
|
||||
m_descriptor = descriptor;
|
||||
@@ -871,46 +905,6 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::ParseCommandLine(const AZ::CommandLine& commandLine)
|
||||
{
|
||||
struct OptionKeyToRegsetKey
|
||||
{
|
||||
AZStd::string_view m_optionKey;
|
||||
AZStd::string m_regsetKey;
|
||||
};
|
||||
|
||||
// Provide overrides for the engine root, the project root and the project cache root
|
||||
AZStd::array commandOptions = {
|
||||
OptionKeyToRegsetKey{ "engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
|
||||
OptionKeyToRegsetKey{ "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
|
||||
OptionKeyToRegsetKey{ "project-cache-path", AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) }
|
||||
};
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
|
||||
|
||||
for (auto&& [optionKey, regsetKey] : commandOptions)
|
||||
{
|
||||
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
|
||||
{
|
||||
// Use the last supplied command option value to override previous values
|
||||
auto overrideArg = AZStd::string::format(R"(--regset="%s=%s")", regsetKey.c_str(),
|
||||
commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
|
||||
overrideArgs.emplace_back(AZStd::move(overrideArg));
|
||||
}
|
||||
}
|
||||
|
||||
if (!overrideArgs.empty())
|
||||
{
|
||||
// Dump the input command line, add the additional option overrides
|
||||
// and Parse the new command line into the Component Application command line
|
||||
AZ::CommandLine::ParamContainer commandLineArgs;
|
||||
commandLine.Dump(commandLineArgs);
|
||||
commandLineArgs.insert(commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()),
|
||||
AZStd::make_move_iterator(overrideArgs.end()));
|
||||
m_commandLine.Parse(commandLineArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
|
||||
{
|
||||
SettingsRegistryInterface::Specializations specializations;
|
||||
|
||||
@@ -328,9 +328,6 @@ namespace AZ
|
||||
/// Create the drillers
|
||||
void CreateDrillers();
|
||||
|
||||
/// Parse ComponentApplication specific command line arguments
|
||||
void ParseCommandLine(const AZ::CommandLine& commandLine);
|
||||
|
||||
virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
|
||||
|
||||
//! Sets the specializations that will be used when loading the Settings Registry. Extend this in derived
|
||||
|
||||
@@ -15,45 +15,49 @@
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::NativeUI
|
||||
{
|
||||
namespace NativeUI
|
||||
enum AssertAction
|
||||
{
|
||||
enum AssertAction
|
||||
{
|
||||
IGNORE_ASSERT = 0,
|
||||
IGNORE_ALL_ASSERTS,
|
||||
BREAK,
|
||||
NONE,
|
||||
};
|
||||
IGNORE_ASSERT = 0,
|
||||
IGNORE_ALL_ASSERTS,
|
||||
BREAK,
|
||||
NONE,
|
||||
};
|
||||
|
||||
class NativeUIRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
class NativeUIRequests
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(NativeUIRequests, "{48361EE6-C1E7-4965-A13A-7425B2691817}");
|
||||
virtual ~NativeUIRequests() = default;
|
||||
|
||||
// Waits for user to select an option before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
|
||||
// Waits for user to select an option before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
|
||||
|
||||
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
|
||||
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
|
||||
|
||||
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
|
||||
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
|
||||
// Returns the option string selected by the user
|
||||
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
|
||||
|
||||
// Displays an assert dialog box
|
||||
// Returns the action selected by the user
|
||||
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
|
||||
};
|
||||
// Displays an assert dialog box
|
||||
// Returns the action selected by the user
|
||||
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
|
||||
};
|
||||
|
||||
using NativeUIRequestBus = AZ::EBus<NativeUIRequests>;
|
||||
}
|
||||
}
|
||||
class NativeUIEBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
};
|
||||
|
||||
using NativeUIRequestBus = AZ::EBus<NativeUIRequests, NativeUIEBusTraits>;
|
||||
} // namespace AZ::NativeUI
|
||||
|
||||
@@ -15,50 +15,19 @@
|
||||
|
||||
#include <AzCore/NativeUI/NativeUISystemComponent.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::NativeUI
|
||||
{
|
||||
using namespace AZ::NativeUI;
|
||||
|
||||
void NativeUISystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
NativeUISystem::NativeUISystem()
|
||||
{
|
||||
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serialize->Class<NativeUISystemComponent, AZ::Component>()
|
||||
->Version(0)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* ec = serialize->GetEditContext())
|
||||
{
|
||||
ec->Class<NativeUISystemComponent>("NativeUI", "Adds basic support for native (platform specific) UI dialog boxes")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
;
|
||||
}
|
||||
}
|
||||
NativeUIRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
NativeUISystem::~NativeUISystem()
|
||||
{
|
||||
provided.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
|
||||
NativeUIRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
(void)required;
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
(void)dependent;
|
||||
}
|
||||
|
||||
AssertAction NativeUISystemComponent::DisplayAssertDialog(const AZStd::string& message) const
|
||||
AssertAction NativeUISystem::DisplayAssertDialog(const AZStd::string& message) const
|
||||
{
|
||||
static const char* buttonNames[3] = { "Ignore", "Ignore All", "Break" };
|
||||
AZStd::vector<AZStd::string> options;
|
||||
@@ -80,7 +49,7 @@ namespace AZ
|
||||
return AssertAction::NONE;
|
||||
}
|
||||
|
||||
AZStd::string NativeUISystemComponent::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
|
||||
AZStd::string NativeUISystem::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
|
||||
{
|
||||
AZStd::vector<AZStd::string> options;
|
||||
|
||||
@@ -93,7 +62,7 @@ namespace AZ
|
||||
return DisplayBlockingDialog(title, message, options);
|
||||
}
|
||||
|
||||
AZStd::string NativeUISystemComponent::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
|
||||
AZStd::string NativeUISystem::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
|
||||
{
|
||||
AZStd::vector<AZStd::string> options;
|
||||
|
||||
@@ -106,18 +75,4 @@ namespace AZ
|
||||
|
||||
return DisplayBlockingDialog(title, message, options);
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::Activate()
|
||||
{
|
||||
NativeUIRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void NativeUISystemComponent::Deactivate()
|
||||
{
|
||||
NativeUIRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
}
|
||||
} // namespace AZ::NativeUI
|
||||
|
||||
@@ -15,40 +15,24 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::NativeUI
|
||||
{
|
||||
namespace NativeUI
|
||||
class NativeUISystem
|
||||
: public NativeUIRequestBus::Handler
|
||||
{
|
||||
class NativeUISystemComponent
|
||||
: public AZ::Component
|
||||
, public NativeUIRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(NativeUISystemComponent, "{E996C058-4AFE-4C8C-816F-98D864D8576D}");
|
||||
public:
|
||||
AZ_RTTI(NativeUISystem, "{FF534B2C-11BE-4DEA-A5B7-A4FA96FE1EDE}", NativeUIRequests);
|
||||
AZ_CLASS_ALLOCATOR(NativeUISystem, AZ::OSAllocator, 0);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
NativeUISystem();
|
||||
~NativeUISystem() override;
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// NativeUIRequestBus interface implementation
|
||||
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
|
||||
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
|
||||
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
|
||||
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component interface implementation
|
||||
void Init() override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// NativeUIRequestBus interface implementation
|
||||
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
|
||||
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
|
||||
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
|
||||
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
} // namespace AZ::NativeUI
|
||||
|
||||
@@ -699,6 +699,10 @@ Data::AssetHandler::LoadResult ScriptSystemComponent::LoadAssetData(
|
||||
script->m_scriptBuffer.resize(scriptDataLength);
|
||||
stream->Read(scriptDataLength, script->m_scriptBuffer.data());
|
||||
|
||||
// Clear cached references in the event of a successful load. This function has to be queued on
|
||||
// AssetBus where NotifyAssetReloaded is also queued, to ensure its execution before NotifyAssetReloaded
|
||||
Data::AssetBus::QueueFunction(&ScriptSystemComponent::ClearAssetReferences, this, asset.GetId());
|
||||
|
||||
return Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ namespace AZ
|
||||
|
||||
//! Remove the value at the provided path
|
||||
//! @param path The path to a value that should be removed
|
||||
//! @return Whether or not the value was stored at the provided path. An invalid path will return false;
|
||||
//! @return Whether or not the path was found and removed. An invalid path will return false;
|
||||
virtual bool Remove(AZStd::string_view path) = 0;
|
||||
|
||||
//! Structure which contains configuration settings for how to parse a single command line argument
|
||||
|
||||
@@ -32,17 +32,12 @@
|
||||
namespace AZ::Internal
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString GetEngineMonikerForProject(
|
||||
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
|
||||
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectJsonPath)
|
||||
{
|
||||
// projectPath needs to be an absolute path here.
|
||||
using namespace AZ::SettingsRegistryMergeUtils;
|
||||
bool projectJsonMerged = false;
|
||||
auto projectJsonPath = projectPath / "project.json";
|
||||
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
projectJsonMerged = settingsRegistry.MergeSettingsFile(
|
||||
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
|
||||
}
|
||||
bool projectJsonMerged = settingsRegistry.MergeSettingsFile(
|
||||
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString engineMoniker;
|
||||
if (projectJsonMerged)
|
||||
@@ -105,12 +100,12 @@ namespace AZ::Internal
|
||||
|
||||
const auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine_name", EngineSettingsRootKey);
|
||||
|
||||
AZStd::set<AZ::IO::FixedMaxPath> projectPathsNotFound;
|
||||
|
||||
for (EngineInfo& engineInfo : pathVisitor.m_enginePaths)
|
||||
{
|
||||
AZ::IO::FixedMaxPath engineSettingsPath{engineInfo.m_path};
|
||||
engineSettingsPath /= "engine.json";
|
||||
|
||||
if (AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
|
||||
if (auto engineSettingsPath = AZ::IO::FixedMaxPath{engineInfo.m_path} / "engine.json";
|
||||
AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
|
||||
{
|
||||
if (settingsRegistry.MergeSettingsFile(
|
||||
engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineSettingsRootKey))
|
||||
@@ -119,12 +114,61 @@ namespace AZ::Internal
|
||||
}
|
||||
}
|
||||
|
||||
auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, engineInfo.m_path / projectPath);
|
||||
if (!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
|
||||
if (auto projectJsonPath = (engineInfo.m_path / projectPath / "project.json").LexicallyNormal();
|
||||
AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
engineRoot = engineInfo.m_path;
|
||||
break;
|
||||
if (auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, projectJsonPath);
|
||||
!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
|
||||
{
|
||||
engineRoot = engineInfo.m_path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
projectPathsNotFound.insert(projectJsonPath);
|
||||
}
|
||||
|
||||
// Continue looking for candidates, remove the previous engine and project settings that were merged above.
|
||||
settingsRegistry.Remove(ProjectSettingsRootKey);
|
||||
settingsRegistry.Remove(EngineSettingsRootKey);
|
||||
}
|
||||
|
||||
if (engineRoot.empty())
|
||||
{
|
||||
AZStd::string errorStr;
|
||||
if (!projectPathsNotFound.empty())
|
||||
{
|
||||
// This case is usually encountered when a project path is given as a relative path,
|
||||
// which is assumed to be relative to an engine root.
|
||||
// When no project.json files are found this way, dump this error message about
|
||||
// which project paths were checked.
|
||||
AZStd::string projectPathsTested;
|
||||
for (const auto& path : projectPathsNotFound)
|
||||
{
|
||||
projectPathsTested.append(AZStd::string::format(" %s\n", path.c_str()));
|
||||
}
|
||||
errorStr = AZStd::string::format("No valid project was found at these locations:\n%s"
|
||||
"Please supply a valid --project-path to the application.",
|
||||
projectPathsTested.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The other case is that a project.json was found, but after checking all the registered engines
|
||||
// none of them matched the engine moniker.
|
||||
AZStd::string enginePathsChecked;
|
||||
for (const auto& engineInfo : pathVisitor.m_enginePaths)
|
||||
{
|
||||
enginePathsChecked.append(AZStd::string::format(" %s (%s)\n", engineInfo.m_path.c_str(), engineInfo.m_moniker.c_str()));
|
||||
}
|
||||
errorStr = AZStd::string::format(
|
||||
"No engine was found in o3de_manifest.json with a name that matches the one set in the project.json.\n"
|
||||
"Engines that were checked:\n%s"
|
||||
"Please check that your engine and project have both been registered with scripts/o3de.py.", enginePathsChecked.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
settingsRegistry.Set(FilePathKey_ErrorText, errorStr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +202,7 @@ namespace AZ::Internal
|
||||
return {};
|
||||
}
|
||||
|
||||
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
void InjectSettingToCommandLineBack(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
AZStd::string_view path, AZStd::string_view value)
|
||||
{
|
||||
AZ::CommandLine commandLine;
|
||||
@@ -168,7 +212,7 @@ namespace AZ::Internal
|
||||
|
||||
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
|
||||
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
|
||||
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
|
||||
paramContainer.emplace(paramContainer.end(), AZStd::move(projectPathOverride));
|
||||
commandLine.Parse(paramContainer);
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
}
|
||||
@@ -197,8 +241,8 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
if (!engineRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.Native());
|
||||
// Inject the engine root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
// Inject the engine root at the end of the command line settings
|
||||
Internal::InjectSettingToCommandLineBack(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
return engineRoot;
|
||||
}
|
||||
}
|
||||
@@ -244,8 +288,8 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
if (!projectRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
// Inject the project root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
// Inject the project root at the end of the command line settings
|
||||
Internal::InjectSettingToCommandLineBack(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
return projectRoot;
|
||||
}
|
||||
}
|
||||
@@ -874,6 +918,49 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParseCommandLine(AZ::CommandLine& commandLine)
|
||||
{
|
||||
struct OptionKeyToRegsetKey
|
||||
{
|
||||
AZStd::string_view m_optionKey;
|
||||
AZStd::string m_regsetKey;
|
||||
};
|
||||
|
||||
// Provide overrides for the engine root, the project root and the project cache root
|
||||
AZStd::array commandOptions = {
|
||||
OptionKeyToRegsetKey{
|
||||
"engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
|
||||
OptionKeyToRegsetKey{
|
||||
"project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
|
||||
OptionKeyToRegsetKey{
|
||||
"project-cache-path",
|
||||
AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}};
|
||||
|
||||
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
|
||||
|
||||
for (auto&& [optionKey, regsetKey] : commandOptions)
|
||||
{
|
||||
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
|
||||
{
|
||||
// Use the last supplied command option value to override previous values
|
||||
auto overrideArg = AZStd::string::format(
|
||||
R"(--regset="%s=%s")", regsetKey.c_str(), commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
|
||||
overrideArgs.emplace_back(AZStd::move(overrideArg));
|
||||
}
|
||||
}
|
||||
|
||||
if (!overrideArgs.empty())
|
||||
{
|
||||
// Dump the input command line, add the additional option overrides
|
||||
// and Parse the new command line args (write back) into the input command line.
|
||||
AZ::CommandLine::ParamContainer commandLineArgs;
|
||||
commandLine.Dump(commandLineArgs);
|
||||
commandLineArgs.insert(
|
||||
commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()), AZStd::make_move_iterator(overrideArgs.end()));
|
||||
commandLine.Parse(commandLineArgs);
|
||||
}
|
||||
}
|
||||
|
||||
bool DumpSettingsRegistryToStream(SettingsRegistryInterface& registry, AZStd::string_view key,
|
||||
AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings)
|
||||
{
|
||||
|
||||
@@ -55,6 +55,9 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! Development write storage path may be considered temporary or cache storage on some platforms
|
||||
inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage";
|
||||
|
||||
//! Stores error text regarding engine boot sequence when engine and project roots cannot be determined
|
||||
inline static constexpr char FilePathKey_ErrorText[] = "/Amazon/AzCore/Runtime/FilePaths/ErrorText";
|
||||
|
||||
//! Root key for where command line are stored at within the settings registry
|
||||
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
|
||||
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
|
||||
@@ -219,6 +222,9 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! into the AZ::CommandLine instance
|
||||
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine);
|
||||
|
||||
//! Parse a CommandLine and transform certain options into formal "regset" options
|
||||
void ParseCommandLine(AZ::CommandLine& commandLine);
|
||||
|
||||
//! Structure for configuring how values should be dumped from the Settings Registry
|
||||
struct DumperSettings
|
||||
{
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ namespace AZ
|
||||
{
|
||||
namespace NativeUI
|
||||
{
|
||||
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
AZ::Android::JNI::Object object("com/amazon/lumberyard/NativeUI/LumberyardNativeUI");
|
||||
object.RegisterStaticMethod("DisplayDialog", "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
|
||||
|
||||
+4
-9
@@ -12,16 +12,11 @@
|
||||
|
||||
#include <AzCore/NativeUI/NativeUISystemComponent.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::NativeUI
|
||||
{
|
||||
namespace NativeUI
|
||||
AZStd::string NativeUISystem::DisplayBlockingDialog([[maybe_unused]] const AZStd::string& title, [[maybe_unused]] const AZStd::string& message,
|
||||
[[maybe_unused]] const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
AZ_UNUSED(title);
|
||||
AZ_UNUSED(message);
|
||||
AZ_UNUSED(options);
|
||||
return "";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace AZ
|
||||
{
|
||||
namespace NativeUI
|
||||
{
|
||||
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
__block NSModalResponse response = -1;
|
||||
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ namespace AZ
|
||||
{
|
||||
namespace NativeUI
|
||||
{
|
||||
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
if (options.size() >= MAX_ITEMS)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace AZ
|
||||
{
|
||||
namespace NativeUI
|
||||
{
|
||||
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
|
||||
{
|
||||
__block AZStd::string userSelection = "";
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
// Initializes the IArchive for reading archive(.pak) files
|
||||
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); !archive)
|
||||
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); archive == nullptr)
|
||||
{
|
||||
m_archive = AZStd::make_unique<AZ::IO::Archive>();
|
||||
AZ::Interface<AZ::IO::IArchive>::Register(m_archive.get());
|
||||
@@ -189,6 +189,12 @@ namespace AzFramework
|
||||
SetFileIOAliases();
|
||||
}
|
||||
|
||||
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI == nullptr)
|
||||
{
|
||||
m_nativeUI = AZStd::make_unique<AZ::NativeUI::NativeUISystem>();
|
||||
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Register(m_nativeUI.get());
|
||||
}
|
||||
|
||||
ApplicationRequests::Bus::Handler::BusConnect();
|
||||
AZ::UserSettingsFileLocatorBus::Handler::BusConnect();
|
||||
NetSystemRequestBus::Handler::BusConnect();
|
||||
@@ -205,12 +211,17 @@ namespace AzFramework
|
||||
AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect();
|
||||
ApplicationRequests::Bus::Handler::BusDisconnect();
|
||||
|
||||
if (AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get() == m_nativeUI.get())
|
||||
{
|
||||
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Unregister(m_nativeUI.get());
|
||||
}
|
||||
m_nativeUI.reset();
|
||||
|
||||
// Unset the Archive file IO if it is set as the direct instance
|
||||
if (AZ::IO::FileIOBase::GetInstance() == m_archiveFileIO.get())
|
||||
{
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
}
|
||||
|
||||
m_archiveFileIO.reset();
|
||||
|
||||
// Destroy the IArchive instance
|
||||
@@ -303,7 +314,6 @@ namespace AzFramework
|
||||
azrtti_typeid<AZ::AssetManagerComponent>(),
|
||||
azrtti_typeid<AZ::UserSettingsComponent>(),
|
||||
azrtti_typeid<AZ::Debug::FrameProfilerComponent>(),
|
||||
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
|
||||
azrtti_typeid<AZ::SliceComponent>(),
|
||||
azrtti_typeid<AZ::SliceSystemComponent>(),
|
||||
|
||||
@@ -372,7 +382,6 @@ namespace AzFramework
|
||||
azrtti_typeid<AZ::UserSettingsComponent>(),
|
||||
azrtti_typeid<AZ::ScriptSystemComponent>(),
|
||||
azrtti_typeid<AZ::JobManagerComponent>(),
|
||||
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
|
||||
azrtti_typeid<AZ::SliceSystemComponent>(),
|
||||
|
||||
azrtti_typeid<AzFramework::AssetCatalogComponent>(),
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/UserSettings/UserSettings.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
@@ -187,6 +188,7 @@ namespace AzFramework
|
||||
AZStd::unique_ptr<AZ::IO::FileIOBase> m_archiveFileIO; ///> The Default file IO instance is a ArchiveFileIO.
|
||||
AZStd::unique_ptr<AZ::IO::Archive> m_archive; ///> The AZ::IO::Instance
|
||||
AZStd::unique_ptr<Implementation> m_pimpl;
|
||||
AZStd::unique_ptr<AZ::NativeUI::NativeUIRequests> m_nativeUI;
|
||||
bool m_ownsConsole = false;
|
||||
|
||||
bool m_exitMainLoopRequested = false;
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace AzFramework
|
||||
{
|
||||
// Read the wait for connection boolean from the Settings Registry
|
||||
AZ::s64 waitForConnect64{};
|
||||
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
|
||||
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
|
||||
{
|
||||
outputConnectionSettings.m_waitForConnect = waitForConnect64 != 0;
|
||||
}
|
||||
|
||||
+16
-18
@@ -17,7 +17,7 @@
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <AzFramework/Entity/GameEntityContextComponent.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -50,36 +50,34 @@ namespace AzFramework
|
||||
|
||||
void AzFrameworkConfigurationSystemComponent::Activate()
|
||||
{
|
||||
// Create the defaults scene and associate the GameEntityContext with it.
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("SceneSystemRequests bus not responding.");
|
||||
SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequests::CreateScene, "default");
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome =
|
||||
SceneSystemInterface::Get()->CreateScene(Scene::MainSceneName);
|
||||
if (createSceneOutcome)
|
||||
{
|
||||
Scene* scene = createSceneOutcome.GetValue();
|
||||
bool success = false;
|
||||
EntityContextId gameEntityContextId = EntityContextId::CreateNull();
|
||||
GameEntityContextRequestBus::BroadcastResult(gameEntityContextId, &GameEntityContextRequests::GetGameEntityContextId);
|
||||
|
||||
if (!gameEntityContextId.IsNull())
|
||||
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
|
||||
EntityContext* gameEntityContext = nullptr;
|
||||
GameEntityContextRequestBus::BroadcastResult(gameEntityContext, &GameEntityContextRequests::GetGameEntityContextInstance);
|
||||
if (gameEntityContext != nullptr)
|
||||
{
|
||||
SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequests::SetSceneForEntityContextId, gameEntityContextId, scene);
|
||||
[[maybe_unused]] bool result = scene->SetSubsystem<EntityContext::SceneStorageType&>(gameEntityContext);
|
||||
AZ_Assert(result, "Unable to register main entity context with the main scene.");
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Unable to retrieve the game entity context instance.");
|
||||
}
|
||||
AZ_Assert(success, "The application was unable to setup a scene for the game entity context, this should always work");
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "%s", createSceneOutcome.GetError().data());
|
||||
AZ_Assert(false, "Unable to create main scene due to: %s", createSceneOutcome.GetError().c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AzFrameworkConfigurationSystemComponent::Deactivate()
|
||||
{
|
||||
bool success = false;
|
||||
SceneSystemRequestBus::BroadcastResult(
|
||||
success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, "default");
|
||||
|
||||
AZ_Assert(success, "\"default\" scene was not removed");
|
||||
[[maybe_unused]] bool success = SceneSystemInterface::Get()->RemoveScene(Scene::MainSceneName);
|
||||
AZ_Assert(success, "Unable to remove the main scene.");
|
||||
}
|
||||
|
||||
void AzFrameworkConfigurationSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/std/containers/stack.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
|
||||
#include "EntityContext.h"
|
||||
|
||||
@@ -37,6 +39,30 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Scene> EntityContext::FindContainingScene(const EntityContextId& contextId)
|
||||
{
|
||||
auto sceneSystem = SceneSystemInterface::Get();
|
||||
AZ_Assert(sceneSystem, "Attempting to retrieve the scene containing a entity context before the scene system is available.");
|
||||
|
||||
AZStd::shared_ptr<Scene> result;
|
||||
sceneSystem->IterateActiveScenes([&result, &contextId](const AZStd::shared_ptr<Scene>& scene)
|
||||
{
|
||||
EntityContext** entityContext = scene->FindSubsystemInScene<EntityContext::SceneStorageType>();
|
||||
if (entityContext && (*entityContext)->GetContextId() == contextId)
|
||||
{
|
||||
result = scene;
|
||||
// Result found, returning.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match, continuing to search for containing scene.
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// EntityContext ctor
|
||||
//=========================================================================
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/Component/EntityBus.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
#include <AzCore/Serialization/IdUtils.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzFramework/Entity/SliceEntityOwnershipService.h>
|
||||
|
||||
@@ -27,7 +28,7 @@ namespace AZ
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class EntityContext;
|
||||
class Scene;
|
||||
|
||||
/**
|
||||
* Provides services for a group of entities under the umbrella of a given context.
|
||||
@@ -47,9 +48,11 @@ namespace AzFramework
|
||||
, public EntityOwnershipServiceNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_TYPE_INFO(EntityContext, "{4F98A6B9-C7B5-450E-8A8A-30EEFC411EF5}");
|
||||
|
||||
/// The type used to store entity in AzFramework::Scene.
|
||||
using SceneStorageType = EntityContext*;
|
||||
|
||||
EntityContext(AZ::SerializeContext* serializeContext = nullptr);
|
||||
EntityContext(const EntityContextId& contextId, AZ::SerializeContext* serializeContext = nullptr);
|
||||
EntityContext(const EntityContextId& contextId, AZStd::unique_ptr<EntityOwnershipService> entityOwnershipService,
|
||||
@@ -75,6 +78,7 @@ namespace AzFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static AZStd::shared_ptr<Scene> FindContainingScene(const EntityContextId& contextId);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace AzFramework
|
||||
*/
|
||||
virtual EntityContextId GetGameEntityContextId() = 0;
|
||||
|
||||
virtual EntityContext* GetGameEntityContextInstance() = 0;
|
||||
|
||||
/**
|
||||
* Creates an entity in the game context.
|
||||
* @param name A name for the new entity.
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace AzFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GameEntityContextRequestBus
|
||||
AZ::Uuid GetGameEntityContextId() override { return GetContextId(); }
|
||||
EntityContext* GetGameEntityContextInstance() override { return this; }
|
||||
void ResetGameContext() override;
|
||||
AZ::Entity* CreateGameEntity(const char* name) override;
|
||||
BehaviorEntity CreateGameEntityForBehaviorContext(const char* name) override;
|
||||
|
||||
@@ -41,9 +41,10 @@ namespace AzFramework::ProjectManager
|
||||
// at the end of the function
|
||||
AZ::CommandLine commandLine;
|
||||
commandLine.Parse(argc, argv);
|
||||
AZ::SettingsRegistryImpl settingsRegistry;
|
||||
// Store the Command line to the Setting Registry
|
||||
AZ::SettingsRegistryMergeUtils::ParseCommandLine(commandLine);
|
||||
|
||||
// Store the Command line to the Setting Registry
|
||||
AZ::SettingsRegistryImpl settingsRegistry;
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
@@ -68,7 +69,14 @@ namespace AzFramework::ProjectManager
|
||||
// If we were able to locate a path to a project, we're done
|
||||
if (!projectRootPath.empty())
|
||||
{
|
||||
return ProjectPathCheckResult::ProjectPathFound;
|
||||
AZ::IO::FixedMaxPath projectJsonPath = engineRootPath / projectRootPath / "project.json";
|
||||
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
return ProjectPathCheckResult::ProjectPathFound;
|
||||
}
|
||||
AZ_TracePrintf(
|
||||
"ProjectManager", "Did not find a project file at location '%s', launching the Project Manager...",
|
||||
projectJsonPath.c_str());
|
||||
}
|
||||
|
||||
if (LaunchProjectManager(engineRootPath))
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
#include <AzFramework/Render/Intersector.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Visibility/BoundsBus.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -30,11 +30,11 @@ namespace AzFramework
|
||||
{
|
||||
IntersectorBus::Handler::BusConnect(m_contextId);
|
||||
IntersectionNotificationBus::Handler::BusConnect(m_contextId);
|
||||
Scene* scene = nullptr;
|
||||
SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, m_contextId);
|
||||
|
||||
AZStd::shared_ptr<Scene> scene = EntityContext::FindContainingScene(m_contextId);
|
||||
if (scene)
|
||||
{
|
||||
scene->SetSubsystem<IntersectorInterface>(this);
|
||||
scene->SetSubsystem(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +42,12 @@ namespace AzFramework
|
||||
{
|
||||
IntersectorBus::Handler::BusDisconnect();
|
||||
IntersectionNotificationBus::Handler::BusDisconnect();
|
||||
Scene* scene = nullptr;
|
||||
SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, m_contextId);
|
||||
|
||||
AZStd::shared_ptr<Scene> scene = EntityContext::FindContainingScene(m_contextId);
|
||||
if (scene)
|
||||
{
|
||||
scene->UnsetSubsystem<IntersectorInterface>();
|
||||
[[maybe_unused]] bool result = scene->UnsetSubsystem(this);
|
||||
AZ_Assert(result, "Failed to unregister Intersector with scene");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace AzFramework
|
||||
, protected IntersectionNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(AzFramework::RenderGeometry::Intersector, "{4CCA7971-CD83-4856-ADEA-89CEB41FB197}");
|
||||
|
||||
Intersector(AzFramework::EntityContextId contextId);
|
||||
~Intersector();
|
||||
|
||||
|
||||
@@ -14,13 +14,102 @@
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
Scene::Scene(AZStd::string_view name)
|
||||
: m_name(name)
|
||||
Scene::Scene(AZStd::string name)
|
||||
: m_name(AZStd::move(name))
|
||||
{
|
||||
}
|
||||
|
||||
const AZStd::string& Scene::GetName()
|
||||
Scene::Scene(AZStd::string name, AZStd::shared_ptr<Scene> parent)
|
||||
: m_name(AZStd::move(name))
|
||||
, m_parent(AZStd::move(parent))
|
||||
{
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
m_removalEvent.Signal(*this, RemovalEventType::Destroyed);
|
||||
}
|
||||
|
||||
const AZStd::string& Scene::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const AZStd::shared_ptr<Scene>& Scene::GetParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<const Scene> Scene::GetParent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
bool Scene::IsAlive() const
|
||||
{
|
||||
return m_isAlive;
|
||||
}
|
||||
|
||||
void Scene::ConnectToEvents(RemovalEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_removalEvent);
|
||||
}
|
||||
|
||||
void Scene::ConnectToEvents(SubsystemEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_subsystemEvent);
|
||||
}
|
||||
|
||||
AZStd::any* Scene::FindSubsystem(const AZ::TypeId& typeId)
|
||||
{
|
||||
AZStd::any* result = FindSubsystemInScene(typeId);
|
||||
return (!result && m_parent) ? m_parent->FindSubsystem(typeId) : result;
|
||||
}
|
||||
|
||||
const AZStd::any* Scene::FindSubsystem(const AZ::TypeId& typeId) const
|
||||
{
|
||||
return const_cast<Scene*>(this)->FindSubsystem(typeId);
|
||||
}
|
||||
|
||||
AZStd::any* Scene::FindSubsystemInScene(const AZ::TypeId& typeId)
|
||||
{
|
||||
// Spot check that the internal arrays remain consistent.
|
||||
AZ_Assert(
|
||||
m_systemKeys.size() == m_systemObjects.size(), "Key and object list in AzFramework::Scene '%s' have gone out of sync.",
|
||||
m_name.c_str());
|
||||
|
||||
const size_t m_systemKeysCount = m_systemKeys.size();
|
||||
for (size_t i = 0; i < m_systemKeysCount; ++i)
|
||||
{
|
||||
if (m_systemKeys[i] != typeId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &m_systemObjects[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const AZStd::any* Scene::FindSubsystemInScene(const AZ::TypeId& typeId) const
|
||||
{
|
||||
return const_cast<Scene*>(this)->FindSubsystemInScene(typeId);
|
||||
}
|
||||
|
||||
void Scene::MarkForDestruction()
|
||||
{
|
||||
m_isAlive = false;
|
||||
m_removalEvent.Signal(*this, RemovalEventType::Zombified);
|
||||
}
|
||||
|
||||
void Scene::RemoveSubsystem(size_t index, const AZ::TypeId& subsystemType)
|
||||
{
|
||||
m_systemKeys[index] = m_systemKeys.back();
|
||||
m_systemObjects[index] = AZStd::move(m_systemObjects.back());
|
||||
m_systemKeys.pop_back();
|
||||
m_systemObjects.pop_back();
|
||||
m_subsystemEvent.Signal(*this, SubsystemEventType::Removed, subsystemType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,14 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -24,71 +28,100 @@ namespace AzFramework
|
||||
AZ_TYPE_INFO(Scene, "{DB449BB3-7A95-434D-BC61-47ACBB1F3436}");
|
||||
AZ_CLASS_ALLOCATOR(Scene, AZ::SystemAllocator, 0);
|
||||
|
||||
explicit Scene(AZStd::string_view name);
|
||||
friend class ISceneSystem;
|
||||
|
||||
const AZStd::string& GetName();
|
||||
constexpr static AZStd::string_view MainSceneName = "Main";
|
||||
constexpr static AZStd::string_view EditorMainSceneName = "Editor";
|
||||
|
||||
enum class RemovalEventType
|
||||
{
|
||||
Zombified, // The scene has be marked for destruction and is no longer visible in the scene system.
|
||||
Destroyed, // The scene has been destroyed.
|
||||
};
|
||||
using RemovalEvent = AZ::Event<Scene&, RemovalEventType>;
|
||||
enum class SubsystemEventType
|
||||
{
|
||||
Added,
|
||||
Removed
|
||||
};
|
||||
using SubsystemEvent = AZ::Event<Scene&, SubsystemEventType, const AZ::TypeId&>;
|
||||
|
||||
explicit Scene(AZStd::string name);
|
||||
Scene(AZStd::string name, AZStd::shared_ptr<Scene> parent);
|
||||
~Scene();
|
||||
|
||||
[[nodiscard]] const AZStd::string& GetName() const;
|
||||
|
||||
[[nodiscard]] const AZStd::shared_ptr<Scene>& GetParent();
|
||||
[[nodiscard]] AZStd::shared_ptr<const Scene> GetParent() const;
|
||||
|
||||
[[nodiscard]] bool IsAlive() const;
|
||||
|
||||
void ConnectToEvents(RemovalEvent::Handler& handler);
|
||||
void ConnectToEvents(SubsystemEvent::Handler& handler);
|
||||
|
||||
// Set the instance of a subsystem associated with this scene.
|
||||
template <typename T>
|
||||
bool SetSubsystem(T* system);
|
||||
bool SetSubsystem(T&& system);
|
||||
|
||||
// Unset the instance of a subsystem associated with this scene.
|
||||
template <typename T>
|
||||
bool UnsetSubsystem();
|
||||
|
||||
// Get the instance of a subsystem associated with this scene.
|
||||
// Unset the instance of the exact system associated with this scene.
|
||||
// Use this to make sure the expected instance is removed or to make sure type deduction is done in the same way as during setting.
|
||||
template<typename T>
|
||||
bool UnsetSubsystem(const T& system);
|
||||
|
||||
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
|
||||
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
|
||||
[[nodiscard]] AZStd::any* FindSubsystem(const AZ::TypeId& typeId);
|
||||
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
|
||||
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
|
||||
[[nodiscard]] const AZStd::any* FindSubsystem(const AZ::TypeId& typeId) const;
|
||||
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
|
||||
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
|
||||
template <typename T>
|
||||
T* GetSubsystem();
|
||||
[[nodiscard]] T* FindSubsystem();
|
||||
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
|
||||
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
|
||||
template<typename T>
|
||||
[[nodiscard]] const T* FindSubsystem() const;
|
||||
|
||||
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
|
||||
// the subsystem if found, otherwise returns a nullptr.
|
||||
[[nodiscard]] AZStd::any* FindSubsystemInScene(const AZ::TypeId& typeId);
|
||||
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
|
||||
// the subsystem if found, otherwise returns a nullptr.
|
||||
[[nodiscard]] const AZStd::any* FindSubsystemInScene(const AZ::TypeId& typeId) const;
|
||||
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
|
||||
// the subsystem if found, otherwise returns a nullptr.
|
||||
template<typename T>
|
||||
[[nodiscard]] T* FindSubsystemInScene();
|
||||
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
|
||||
// the subsystem if found, otherwise returns a nullptr.
|
||||
template<typename T>
|
||||
[[nodiscard]] const T* FindSubsystemInScene() const;
|
||||
|
||||
private:
|
||||
void MarkForDestruction();
|
||||
void RemoveSubsystem(size_t index, const AZ::TypeId& subsystemType);
|
||||
|
||||
AZStd::string m_name;
|
||||
RemovalEvent m_removalEvent;
|
||||
SubsystemEvent m_subsystemEvent;
|
||||
|
||||
// Storing keys separate from data to optimize for fast key search.
|
||||
AZStd::vector<AZ::TypeId> m_systemKeys;
|
||||
AZStd::vector<void*> m_systemPointers;
|
||||
AZStd::vector<AZStd::any> m_systemObjects;
|
||||
|
||||
// Name that identifies the scene.
|
||||
AZStd::string m_name;
|
||||
// Parent to this scene. Any subsystems are inherited from the parent but can be overwritten locally.
|
||||
AZStd::shared_ptr<Scene> m_parent;
|
||||
// If false, the scene has been removed from scene system and can no longer be found. As soon as all handles to the scene are
|
||||
// released it will be destroyed.
|
||||
bool m_isAlive{ true };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool Scene::SetSubsystem(T* system)
|
||||
{
|
||||
if (GetSubsystem<T>() != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_systemKeys.push_back(T::RTTI_Type());
|
||||
m_systemPointers.push_back(system);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Scene::UnsetSubsystem()
|
||||
{
|
||||
for (size_t i = 0; i < m_systemKeys.size(); ++i)
|
||||
{
|
||||
if (m_systemKeys.at(i) == T::RTTI_Type())
|
||||
{
|
||||
m_systemKeys.at(i) = m_systemKeys.back();
|
||||
m_systemKeys.pop_back();
|
||||
m_systemPointers.at(i) = m_systemPointers.back();
|
||||
m_systemPointers.pop_back();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* Scene::GetSubsystem()
|
||||
{
|
||||
for (size_t i = 0; i < m_systemKeys.size(); ++i)
|
||||
{
|
||||
if (m_systemKeys.at(i) == T::RTTI_Type())
|
||||
{
|
||||
return reinterpret_cast<T*>(m_systemPointers.at(i));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // AzFramework
|
||||
|
||||
#include <AzFramework/Scene/Scene.inl>
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
template<typename T>
|
||||
bool Scene::SetSubsystem(T&& system)
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
for (const AZ::TypeId& key : m_systemKeys)
|
||||
{
|
||||
if (key == targetType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_systemKeys.push_back(targetType);
|
||||
m_systemObjects.emplace_back(AZStd::forward<T>(system));
|
||||
m_subsystemEvent.Signal(*this, SubsystemEventType::Added, targetType);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Scene::UnsetSubsystem()
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
const size_t m_systemKeysCount = m_systemKeys.size();
|
||||
for (size_t i = 0; i < m_systemKeysCount; ++i)
|
||||
{
|
||||
if (m_systemKeys[i] != targetType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveSubsystem(i, targetType);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Scene::UnsetSubsystem(const T& system)
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
const size_t systemKeysCount = m_systemKeys.size();
|
||||
for (size_t i = 0; i < systemKeysCount; ++i)
|
||||
{
|
||||
if (m_systemKeys[i] != targetType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
[[maybe_unused]] T* instance = AZStd::any_cast<T>(&m_systemObjects[i]);
|
||||
AZ_Assert(
|
||||
instance && *instance == system,
|
||||
"Subsystem being released matched type, but wasn't pointing to the same system that was stored.");
|
||||
RemoveSubsystem(i, targetType);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Scene::FindSubsystem()
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
AZStd::any* subSystem = FindSubsystem(targetType);
|
||||
return subSystem ? AZStd::any_cast<T>(subSystem) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* Scene::FindSubsystem() const
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
const AZStd::any* subSystem = FindSubsystem(targetType);
|
||||
return subSystem ? AZStd::any_cast<const T>(subSystem) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Scene::FindSubsystemInScene()
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
AZStd::any* subSystem = FindSubsystemInScene(targetType);
|
||||
return subSystem ? AZStd::any_cast<T>(subSystem) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* Scene::FindSubsystemInScene() const
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
const AZStd::any* subSystem = FindSubsystemInScene(targetType);
|
||||
return subSystem ? AZStd::any_cast<const T>(subSystem) : nullptr;
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* 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/EBus/EBus.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
// Forward declarations
|
||||
class Scene;
|
||||
|
||||
//! Interface used to create, get, or destroy scenes.
|
||||
class SceneSystemRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~SceneSystemRequests() = default;
|
||||
|
||||
//! Single handler policy since there should only be one instance of this system component.
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
|
||||
//! Creates a scene with a given name.
|
||||
//! - If there is already a scene with the provided name this will return AZ::Failure().
|
||||
//! - If isDefault is set to true and there is already a default scene, the default scene will be switched to this one.
|
||||
virtual AZ::Outcome<Scene*, AZStd::string> CreateScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Gets a scene with a given name
|
||||
//! - If a scene does not exist with the given name, nullptr is returned.
|
||||
virtual Scene* GetScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Gets all the scenes that currently exist.
|
||||
virtual AZStd::vector<Scene*> GetAllScenes() = 0;
|
||||
|
||||
//! Remove a scene with a given name and return if the operation was successful.
|
||||
//! - If the removed scene is the default scene, there will no longer be a default scene.
|
||||
virtual bool RemoveScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Add a mapping from the provided EntityContextId to a Scene
|
||||
//! - If a scene is already associated with this EntityContextId, nothing is changed and false is returned.
|
||||
virtual bool SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) = 0;
|
||||
|
||||
//! Remove a mapping from the provided EntityContextId to a Scene
|
||||
//! - If no scene is found from the provided EntityContextId, false is returned.
|
||||
virtual bool RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) = 0;
|
||||
|
||||
//! Get the scene associated with an EntityContextId
|
||||
//! - If no scene is found for the provided EntityContextId, nullptr is returned.
|
||||
virtual Scene* GetSceneFromEntityContextId(EntityContextId entityContextId) = 0;
|
||||
};
|
||||
|
||||
using SceneSystemRequestBus = AZ::EBus<SceneSystemRequests>;
|
||||
|
||||
//! Interface used for notifications from the scene system
|
||||
class SceneSystemNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~SceneSystemNotifications() = default;
|
||||
|
||||
//! There can be multiple listeners to changes in the scene system.
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
|
||||
//! Called when a scene has been created.
|
||||
virtual void SceneCreated(Scene& /*scene*/) {};
|
||||
|
||||
//! Called just before a scene is removed.
|
||||
virtual void SceneAboutToBeRemoved(Scene& /*scene*/) {};
|
||||
|
||||
};
|
||||
|
||||
using SceneSystemNotificationBus = AZ::EBus<SceneSystemNotifications>;
|
||||
|
||||
//! Interface used for notifications about individual scenes
|
||||
class SceneNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~SceneNotifications() = default;
|
||||
|
||||
//! There can be multiple listeners to changes in the scene system.
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
|
||||
//! Bus is listened to using the pointer of the scene
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
|
||||
//! Specifies that events are addressed by the pointer to the scene
|
||||
using BusIdType = Scene*;
|
||||
|
||||
//! Called just before a scene is removed.
|
||||
virtual void SceneAboutToBeRemoved() {};
|
||||
|
||||
//! Called when an entity context is mapped to this scene.
|
||||
virtual void EntityContextMapped(EntityContextId /*entityContextId*/) {};
|
||||
|
||||
//! Called when an entity context is unmapped from this scene.
|
||||
virtual void EntityContextUnmapped(EntityContextId /*entityContextId*/) {};
|
||||
};
|
||||
|
||||
using SceneNotificationBus = AZ::EBus<SceneNotifications>;
|
||||
|
||||
} // AzFramework
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -41,14 +41,10 @@ namespace AzFramework
|
||||
|
||||
void SceneSystemComponent::Activate()
|
||||
{
|
||||
// Connect busses
|
||||
SceneSystemRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void SceneSystemComponent::Deactivate()
|
||||
{
|
||||
// Disconnect Busses
|
||||
SceneSystemRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void SceneSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
@@ -61,140 +57,105 @@ namespace AzFramework
|
||||
incompatible.push_back(AZ_CRC("SceneSystemComponentService", 0xd8975435));
|
||||
}
|
||||
|
||||
AZ::Outcome<Scene*, AZStd::string> SceneSystemComponent::CreateScene(AZStd::string_view name)
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> SceneSystemComponent::CreateScene(AZStd::string_view name)
|
||||
{
|
||||
Scene* existingScene = GetScene(name);
|
||||
return CreateSceneWithParent(name, nullptr);
|
||||
}
|
||||
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> SceneSystemComponent::CreateSceneWithParent(
|
||||
AZStd::string_view name, AZStd::shared_ptr<Scene> parent)
|
||||
{
|
||||
const AZStd::shared_ptr<Scene>& existingScene = GetScene(name);
|
||||
if (existingScene)
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("A scene already exists with this name.");
|
||||
}
|
||||
|
||||
auto newScene = AZStd::make_unique<Scene>(name);
|
||||
Scene* scenePointer = newScene.get();
|
||||
m_scenes.push_back(AZStd::move(newScene));
|
||||
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneCreated, *scenePointer);
|
||||
return AZ::Success(scenePointer);
|
||||
auto newScene = AZStd::make_shared<Scene>(name, AZStd::move(parent));
|
||||
m_activeScenes.push_back(newScene);
|
||||
{
|
||||
AZStd::lock_guard lock(m_eventMutex);
|
||||
m_events.Signal(EventType::SceneCreated, newScene);
|
||||
}
|
||||
return AZ::Success(AZStd::move(newScene));
|
||||
}
|
||||
|
||||
Scene* SceneSystemComponent::GetScene(AZStd::string_view name)
|
||||
AZStd::shared_ptr<Scene> SceneSystemComponent::GetScene(AZStd::string_view name)
|
||||
{
|
||||
auto sceneIterator = AZStd::find_if(m_scenes.begin(), m_scenes.end(),
|
||||
auto sceneIterator = AZStd::find_if(m_activeScenes.begin(), m_activeScenes.end(),
|
||||
[name](auto& scene) -> bool
|
||||
{
|
||||
return scene->GetName() == name;
|
||||
}
|
||||
);
|
||||
|
||||
return sceneIterator == m_scenes.end() ? nullptr : sceneIterator->get();
|
||||
return sceneIterator == m_activeScenes.end() ? nullptr : *sceneIterator;
|
||||
}
|
||||
|
||||
AZStd::vector<Scene*> SceneSystemComponent::GetAllScenes()
|
||||
void SceneSystemComponent::IterateActiveScenes(const ActiveIterationCallback& callback)
|
||||
{
|
||||
AZStd::vector<Scene*> scenes;
|
||||
scenes.resize_no_construct(m_scenes.size());
|
||||
|
||||
for (size_t i = 0; i < m_scenes.size(); ++i)
|
||||
bool keepGoing = true;
|
||||
auto end = m_activeScenes.end();
|
||||
for (auto it = m_activeScenes.begin(); it != end && keepGoing; ++it)
|
||||
{
|
||||
scenes.at(i) = m_scenes.at(i).get();
|
||||
keepGoing = callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSystemComponent::IterateZombieScenes(const ZombieIterationCallback& callback)
|
||||
{
|
||||
bool keepGoing = true;
|
||||
auto end = m_zombieScenes.end();
|
||||
for (auto it = m_zombieScenes.begin(); it != end && keepGoing;)
|
||||
{
|
||||
if (!it->expired())
|
||||
{
|
||||
keepGoing = callback(*(it->lock()));
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
*it = m_zombieScenes.back();
|
||||
m_zombieScenes.pop_back();
|
||||
end = m_zombieScenes.end();
|
||||
}
|
||||
}
|
||||
return scenes;
|
||||
}
|
||||
|
||||
bool SceneSystemComponent::RemoveScene(AZStd::string_view name)
|
||||
{
|
||||
for (size_t i = 0; i < m_scenes.size(); ++i)
|
||||
for (AZStd::shared_ptr<Scene>& scene : m_activeScenes)
|
||||
{
|
||||
auto& scenePtr = m_scenes.at(i);
|
||||
if (scenePtr->GetName() == name)
|
||||
if (scene->GetName() == name)
|
||||
{
|
||||
// Remove any entityContext mappings.
|
||||
Scene* scene = scenePtr.get();
|
||||
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
|
||||
MarkSceneForDestruction(*scene);
|
||||
{
|
||||
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
|
||||
if (pair.second == scene)
|
||||
{
|
||||
// swap and pop back.
|
||||
*entityContextScenePairIt = m_entityContextToScenes.back();
|
||||
m_entityContextToScenes.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
++entityContextScenePairIt;
|
||||
}
|
||||
AZStd::lock_guard lock(m_eventMutex);
|
||||
m_events.Signal(EventType::ScenePendingRemoval, scene);
|
||||
}
|
||||
|
||||
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneAboutToBeRemoved, *scene);
|
||||
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::SceneAboutToBeRemoved);
|
||||
|
||||
m_scenes.erase(&scenePtr);
|
||||
// Zombies are weak pointers that are kept around for situations where there's a delay in deleting the scene. This can happen
|
||||
// if there are outstanding calls like in-progress async calls or resources locked by hardware. A weak_ptr of the original
|
||||
// scene is kept so the zombie scene can still be found through iteration as it may require additional calls such as Tick calls.
|
||||
m_zombieScenes.push_back(scene);
|
||||
scene = AZStd::move(m_activeScenes.back());
|
||||
m_activeScenes.pop_back();
|
||||
// The scene may not be held onto anymore, so check here to see if the previously added zombie can be released.
|
||||
if (m_zombieScenes.back().expired())
|
||||
{
|
||||
m_zombieScenes.pop_back();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Warning("SceneSystemComponent", false, "Attempting to remove scene name \"%.*s\", but that scene was not found.", static_cast<int>(name.size()), name.data());
|
||||
AZ_Warning("SceneSystemComponent", false, R"(Attempting to remove scene name "%.*s", but that scene was not found.)", AZ_STRING_ARG(name));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SceneSystemComponent::SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
|
||||
void SceneSystemComponent::ConnectToEvents(SceneEvent::Handler& handler)
|
||||
{
|
||||
Scene* existingSceneForEntityContext = GetSceneFromEntityContextId(entityContextId);
|
||||
if (existingSceneForEntityContext)
|
||||
{
|
||||
// This entity context is already mapped and must be unmapped explictely before it can be changed.
|
||||
char entityContextIdString[EntityContextId::MaxStringBuffer];
|
||||
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
|
||||
AZ_Warning("SceneSystemComponent", false, "Failed to set a scene for entity context %s, scene is already set for that entity context.", entityContextIdString);
|
||||
|
||||
return false;
|
||||
}
|
||||
m_entityContextToScenes.emplace_back(entityContextId, scene);
|
||||
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextMapped, entityContextId);
|
||||
return true;
|
||||
AZStd::lock_guard lock(m_eventMutex);
|
||||
handler.Connect(m_events);
|
||||
}
|
||||
|
||||
bool SceneSystemComponent::RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
|
||||
{
|
||||
if (!scene || entityContextId.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
|
||||
{
|
||||
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
|
||||
if (!(pair.first == entityContextId && pair.second == scene))
|
||||
{
|
||||
++entityContextScenePairIt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// swap and pop back.
|
||||
*entityContextScenePairIt = m_entityContextToScenes.back();
|
||||
m_entityContextToScenes.pop_back();
|
||||
|
||||
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextUnmapped, entityContextId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
char entityContextIdString[EntityContextId::MaxStringBuffer];
|
||||
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
|
||||
AZ_Warning("SceneSystemComponent", false, "Failed to remove scene \"%.*s\" for entity context %s, entity context is not currently mapped to that scene.", static_cast<int>(scene->GetName().size()), scene->GetName().data(), entityContextIdString);
|
||||
return false;
|
||||
}
|
||||
|
||||
Scene* SceneSystemComponent::GetSceneFromEntityContextId(EntityContextId entityContextId)
|
||||
{
|
||||
for (AZStd::pair<EntityContextId, Scene*>& pair : m_entityContextToScenes)
|
||||
{
|
||||
if (pair.first == entityContextId)
|
||||
{
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // AzFramework
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -13,18 +13,18 @@
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class SceneSystemComponent
|
||||
: public AZ::Component
|
||||
, public SceneSystemRequestBus::Handler
|
||||
, public SceneSystemInterface::Registrar
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_COMPONENT(SceneSystemComponent, "{7AC53AF0-BE1A-437C-BE3E-4D6A998DA945}", AZ::Component);
|
||||
AZ_COMPONENT(SceneSystemComponent, "{7AC53AF0-BE1A-437C-BE3E-4D6A998DA945}", AZ::Component, ISceneSystem);
|
||||
|
||||
SceneSystemComponent();
|
||||
~SceneSystemComponent() override;
|
||||
@@ -41,24 +41,26 @@ namespace AzFramework
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SceneSystemRequestsBus::Handler
|
||||
// SceneSystemInterface overrides
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AZ::Outcome<Scene*, AZStd::string> CreateScene(AZStd::string_view name) override;
|
||||
Scene* GetScene(AZStd::string_view name) override;
|
||||
AZStd::vector<Scene*> GetAllScenes() override;
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateScene(AZStd::string_view name) override;
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateSceneWithParent(
|
||||
AZStd::string_view name, AZStd::shared_ptr<Scene> parent) override;
|
||||
[[nodiscard]] AZStd::shared_ptr<Scene> GetScene(AZStd::string_view name) override;
|
||||
void IterateActiveScenes(const ActiveIterationCallback& callback) override;
|
||||
void IterateZombieScenes(const ZombieIterationCallback& callback) override;
|
||||
bool RemoveScene(AZStd::string_view name) override;
|
||||
bool SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) override;
|
||||
bool RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) override;
|
||||
Scene* GetSceneFromEntityContextId(EntityContextId entityContextId) override;
|
||||
void ConnectToEvents(SceneEvent::Handler& handler) override;
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(SceneSystemComponent);
|
||||
|
||||
AZ_DISABLE_COPY(SceneSystemComponent);
|
||||
|
||||
// Container of scene in order of creation
|
||||
AZStd::vector<AZStd::unique_ptr<Scene>> m_scenes;
|
||||
|
||||
// Map of entity context Ids to scenes. Using a vector because lookups will be common, but the size will be small.
|
||||
AZStd::vector<AZStd::pair<EntityContextId, Scene*>> m_entityContextToScenes;
|
||||
AZStd::vector<AZStd::shared_ptr<Scene>> m_activeScenes;
|
||||
AZStd::vector<AZStd::weak_ptr<Scene>> m_zombieScenes;
|
||||
// Using a mutex around the events as other threads may respond to a new/deleted scene by making
|
||||
// local updates and unregistering themselves. Since Scene is single threaded, no updates (other
|
||||
// then unregistering an event) should be done from other threads though.
|
||||
AZStd::recursive_mutex m_eventMutex;
|
||||
SceneEvent m_events;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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/EBus/EBus.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
//! Interface used to create, get, or destroy scenes.
|
||||
//! This interface is single thread and is intended to be called from a single thread, commonly the main thread. The exception
|
||||
//! is connecting events, which is thread safe.
|
||||
class ISceneSystem
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AzFramework::ISceneSystem, "{DAE482A8-88AE-4BD3-8A5B-52D19A96E15F}");
|
||||
AZ_DISABLE_COPY_MOVE(ISceneSystem);
|
||||
|
||||
enum class EventType
|
||||
{
|
||||
SceneCreated,
|
||||
ScenePendingRemoval
|
||||
};
|
||||
using SceneEvent = AZ::Event<EventType, const AZStd::shared_ptr<Scene>&>;
|
||||
|
||||
ISceneSystem() = default;
|
||||
virtual ~ISceneSystem() = default;
|
||||
|
||||
using ActiveIterationCallback = AZStd::function<bool(const AZStd::shared_ptr<Scene>& scene)>;
|
||||
using ZombieIterationCallback = AZStd::function<bool(Scene& scene)>;
|
||||
|
||||
//! Creates a scene with a given name.
|
||||
//! - If there is already a scene with the provided name this will return AZ::Failure().
|
||||
virtual AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Creates a scene with a given name and a parent.
|
||||
//! - If there is already a scene with the provided name this will return AZ::Failure().
|
||||
virtual AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateSceneWithParent(
|
||||
AZStd::string_view name, AZStd::shared_ptr<Scene> parent) = 0;
|
||||
|
||||
//! Gets a scene with a given name
|
||||
//! - If a scene does not exist with the given name, nullptr is returned.
|
||||
[[nodiscard]] virtual AZStd::shared_ptr<Scene> GetScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Iterates over all scenes that are in active use. Iteration stops if the callback returns false or all scenes have been listed.
|
||||
virtual void IterateActiveScenes(const ActiveIterationCallback& callback) = 0;
|
||||
//! Iterates over all zombie scenes. Zombie scenes are scenes that have been removed but still have references held on to. This can
|
||||
//! happen because scenes hold on to subsystems that can't immediately be deleted. These subsystems may still require being called
|
||||
//! such as a periodic tick. Iteration stops if the callback returns false or all scenes have been listed.
|
||||
virtual void IterateZombieScenes(const ZombieIterationCallback& callback) = 0;
|
||||
|
||||
//! Remove a scene with a given name and return if the operation was successful.
|
||||
virtual bool RemoveScene(AZStd::string_view name) = 0;
|
||||
|
||||
//! Connects the provided handler to the events that are called after scenes are created or before they get removed.
|
||||
virtual void ConnectToEvents(SceneEvent::Handler& handler) = 0;
|
||||
|
||||
protected:
|
||||
// Strictly a forwarding function to call private functions on the scene.
|
||||
void MarkSceneForDestruction(Scene& scene) { scene.MarkForDestruction(); }
|
||||
};
|
||||
|
||||
using SceneSystemInterface = AZ::Interface<ISceneSystem>;
|
||||
|
||||
// EBus wrapper for ScriptCanvas
|
||||
class ISceneSystemRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
};
|
||||
using ILoggerRequestBus = AZ::EBus<ISceneSystem, ISceneSystemRequests>;
|
||||
} // AzFramework
|
||||
@@ -194,10 +194,11 @@ set(FILES
|
||||
Logging/MissingAssetLogger.h
|
||||
Logging/MissingAssetNotificationBus.h
|
||||
Scene/Scene.h
|
||||
Scene/Scene.inl
|
||||
Scene/Scene.cpp
|
||||
Scene/SceneSystemBus.h
|
||||
Scene/SceneSystemComponent.h
|
||||
Scene/SceneSystemComponent.cpp
|
||||
Scene/SceneSystemInterface.h
|
||||
Script/ScriptComponent.h
|
||||
Script/ScriptComponent.cpp
|
||||
Script/ScriptDebugAgentBus.h
|
||||
|
||||
@@ -284,6 +284,10 @@ namespace AzToolsFramework
|
||||
void ToolsApplication::Start(const Descriptor& descriptor, const StartupParameters& startupParameters/* = StartupParameters()*/)
|
||||
{
|
||||
Application::Start(descriptor, startupParameters);
|
||||
if (!m_isStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_editorEntityManager.Start();
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ namespace AzToolsFramework
|
||||
/// Retrieve the Id of the editor entity context.
|
||||
virtual AzFramework::EntityContextId GetEditorEntityContextId() = 0;
|
||||
|
||||
virtual AzFramework::EntityContext* GetEditorEntityContextInstance() = 0;
|
||||
|
||||
/// Creates an entity in the editor context.
|
||||
/// \return the EntityId for the created Entity
|
||||
virtual AZ::EntityId CreateNewEditorEntity(const char* name) = 0;
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EditorEntityContextRequestBus
|
||||
AzFramework::EntityContextId GetEditorEntityContextId() override { return GetContextId(); }
|
||||
AzFramework::EntityContext* GetEditorEntityContextInstance() override { return this; }
|
||||
void ResetEditorContext() override;
|
||||
|
||||
AZ::EntityId CreateNewEditorEntity(const char* name) override;
|
||||
|
||||
+2
-2
@@ -769,12 +769,12 @@ namespace AzToolsFramework
|
||||
|
||||
template<typename Vertex>
|
||||
void EditorVertexSelectionBase<Vertex>::DisplayViewport2d(
|
||||
const AzFramework::ViewportInfo& /*viewportInfo*/,
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
m_editorBoxSelect.Display2d(debugDisplay);
|
||||
m_editorBoxSelect.Display2d(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
template<typename Vertex>
|
||||
|
||||
+33
-8
@@ -16,7 +16,7 @@
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
|
||||
#include <AzToolsFramework/Editor/EditorSettingsAPIBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextComponent.h>
|
||||
@@ -56,22 +56,47 @@ namespace AzToolsFramework
|
||||
|
||||
void AzToolsFrameworkConfigurationSystemComponent::Activate()
|
||||
{
|
||||
// Associate the EditorEntityContext with the default scene.
|
||||
// Create the editor specific child scene to the main scene and add the editor entity context to it.
|
||||
AzFramework::EntityContextId editorEntityContextId;
|
||||
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
|
||||
|
||||
AzFramework::Scene* defaultScene = nullptr;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(defaultScene, &AzFramework::SceneSystemRequests::GetScene, "default");
|
||||
|
||||
if (!editorEntityContextId.IsNull() && defaultScene)
|
||||
if (!editorEntityContextId.IsNull())
|
||||
{
|
||||
bool success = false;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequests::SetSceneForEntityContextId, editorEntityContextId, defaultScene);
|
||||
auto sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
AZ_Assert(sceneSystem, "Scene system not available to create the editor scene.");
|
||||
AZStd::shared_ptr<AzFramework::Scene> mainScene = sceneSystem->GetScene(AzFramework::Scene::MainSceneName);
|
||||
if (mainScene)
|
||||
{
|
||||
AZ::Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> editorScene =
|
||||
sceneSystem->CreateSceneWithParent(AzFramework::Scene::EditorMainSceneName, mainScene);
|
||||
if (editorScene.IsSuccess())
|
||||
{
|
||||
AzFramework::EntityContext* editorEntityContext = nullptr;
|
||||
EditorEntityContextRequestBus::BroadcastResult(
|
||||
editorEntityContext, &EditorEntityContextRequests::GetEditorEntityContextInstance);
|
||||
if (editorEntityContext != nullptr)
|
||||
{
|
||||
[[maybe_unused]] bool contextAdded =
|
||||
editorScene.GetValue()->SetSubsystem<AzFramework::EntityContext::SceneStorageType&>(editorEntityContext);
|
||||
AZ_Assert(contextAdded, "Unable to add editor entity context to scene.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Failed to create editor scene because: %s", editorScene.GetError().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "No main scene to parent the editor scene under.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AzToolsFrameworkConfigurationSystemComponent::Deactivate()
|
||||
{
|
||||
[[maybe_unused]] bool success = AzFramework::SceneSystemInterface::Get()->RemoveScene(AzFramework::Scene::EditorMainSceneName);
|
||||
AZ_Assert(success, "Unable to remove the main editor scene.");
|
||||
}
|
||||
|
||||
void AzToolsFrameworkConfigurationSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
|
||||
+11
-7
@@ -13,6 +13,7 @@
|
||||
#include "EditorBoxSelect.h"
|
||||
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace AzToolsFramework
|
||||
m_previousModifiers = mouseInteraction.m_mouseInteraction.m_keyboardModifiers;
|
||||
}
|
||||
|
||||
void EditorBoxSelect::Display2d(AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
void EditorBoxSelect::Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
@@ -82,12 +83,15 @@ namespace AzToolsFramework
|
||||
debugDisplay.SetLineWidth(s_boxSelectLineWidth);
|
||||
debugDisplay.SetColor(s_boxSelectColor);
|
||||
|
||||
debugDisplay.DrawWireBox(
|
||||
AZ::Vector3(
|
||||
static_cast<float>(m_boxSelectRegion->x()), static_cast<float>(m_boxSelectRegion->y()), 0.0f),
|
||||
AZ::Vector3(
|
||||
static_cast<float>(m_boxSelectRegion->x()) + static_cast<float>(m_boxSelectRegion->width()),
|
||||
static_cast<float>(m_boxSelectRegion->y()) + static_cast<float>(m_boxSelectRegion->height()), 0.0f));
|
||||
AZ::Vector2 viewportSize = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId).m_viewportSize;
|
||||
|
||||
debugDisplay.DrawWireQuad2d(
|
||||
AZ::Vector2(
|
||||
aznumeric_cast<float>(m_boxSelectRegion->x()), aznumeric_cast<float>(m_boxSelectRegion->y())) / viewportSize,
|
||||
AZ::Vector2(
|
||||
aznumeric_cast<float>(m_boxSelectRegion->x()) + aznumeric_cast<float>(m_boxSelectRegion->width()),
|
||||
aznumeric_cast<float>(m_boxSelectRegion->y()) + aznumeric_cast<float>(m_boxSelectRegion->height())) / viewportSize,
|
||||
0.f);
|
||||
|
||||
debugDisplay.DepthTestOn();
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ namespace AzToolsFramework
|
||||
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
|
||||
|
||||
/// Responsible for drawing the 2d box representing the selection in screen space.
|
||||
void Display2d(AzFramework::DebugDisplayRequests& debugDisplay);
|
||||
void Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay);
|
||||
|
||||
/// Custom drawing behavior to happen during a box select.
|
||||
void DisplayScene(
|
||||
|
||||
+4
-4
@@ -441,7 +441,7 @@ namespace AzToolsFramework
|
||||
clusterId);
|
||||
}
|
||||
|
||||
static void SetViewportUiClusterVisible(ViewportUi::ClusterId clusterId, bool visible)
|
||||
static void SetViewportUiClusterVisible(const ViewportUi::ClusterId clusterId, const bool visible)
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId,
|
||||
@@ -449,7 +449,7 @@ namespace AzToolsFramework
|
||||
clusterId, visible);
|
||||
}
|
||||
|
||||
static void SetViewportUiClusterActiveButton(ViewportUi::ClusterId clusterId, ViewportUi::ButtonId buttonId)
|
||||
static void SetViewportUiClusterActiveButton(const ViewportUi::ClusterId clusterId, const ViewportUi::ButtonId buttonId)
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId,
|
||||
@@ -457,7 +457,7 @@ namespace AzToolsFramework
|
||||
clusterId, buttonId);
|
||||
}
|
||||
|
||||
static ViewportUi::ButtonId RegisterClusterButton(ViewportUi::ClusterId clusterId, const char* iconName)
|
||||
static ViewportUi::ButtonId RegisterClusterButton(const ViewportUi::ClusterId clusterId, const char* iconName)
|
||||
{
|
||||
ViewportUi::ButtonId buttonId;
|
||||
ViewportUi::ViewportUiRequestBus::EventResult(
|
||||
@@ -3494,7 +3494,7 @@ namespace AzToolsFramework
|
||||
|
||||
DrawAxisGizmo(viewportInfo, debugDisplay);
|
||||
|
||||
m_boxSelect.Display2d(debugDisplay);
|
||||
m_boxSelect.Display2d(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::RefreshSelectedEntityIds()
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "AzToolsFramework_precompiled.h"
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
@@ -22,4 +21,11 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
, m_buttonId(buttonId)
|
||||
{
|
||||
}
|
||||
|
||||
Button::Button(AZStd::string icon, AZStd::string name, ButtonId buttonId)
|
||||
: m_icon(AZStd::move(icon))
|
||||
, m_name(AZStd::move(name))
|
||||
, m_buttonId(buttonId)
|
||||
{
|
||||
}
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
@@ -27,10 +26,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
Deselected
|
||||
};
|
||||
|
||||
explicit Button(AZStd::string icon, ButtonId buttonId);
|
||||
Button(AZStd::string icon, ButtonId buttonId);
|
||||
Button(AZStd::string icon, AZStd::string name, ButtonId buttonId);
|
||||
~Button() = default;
|
||||
|
||||
AZStd::string m_icon; //!< The icon for this button, string path to an image.
|
||||
AZStd::string m_name; //!< The name displayed as a label next to the button's icon.
|
||||
State m_state = State::Deselected;
|
||||
ButtonId m_buttonId;
|
||||
};
|
||||
|
||||
+18
-21
@@ -11,37 +11,27 @@
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
Cluster::Cluster()
|
||||
ButtonGroup::ButtonGroup()
|
||||
: m_buttons()
|
||||
, m_buttonTriggeredEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void Cluster::SetViewportUiElementId(const ViewportUiElementId id)
|
||||
void ButtonGroup::SetViewportUiElementId(const ViewportUiElementId id)
|
||||
{
|
||||
m_viewportUiId = id;
|
||||
}
|
||||
|
||||
ViewportUiElementId Cluster::GetViewportUiElementId() const
|
||||
ViewportUiElementId ButtonGroup::GetViewportUiElementId() const
|
||||
{
|
||||
return m_viewportUiId;
|
||||
}
|
||||
|
||||
void Cluster::SetClusterId(const ClusterId clusterId)
|
||||
{
|
||||
m_clusterId = clusterId;
|
||||
}
|
||||
|
||||
ClusterId Cluster::GetClusterId() const
|
||||
{
|
||||
return m_clusterId;
|
||||
}
|
||||
|
||||
void Cluster::SetHighlightedButton(ButtonId buttonId)
|
||||
void ButtonGroup::SetHighlightedButton(ButtonId buttonId)
|
||||
{
|
||||
if (auto buttonEntry = m_buttons.find(buttonId); buttonEntry != m_buttons.end())
|
||||
{
|
||||
@@ -53,15 +43,22 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
ButtonId Cluster::AddButton(const AZStd::string& icon)
|
||||
ButtonId ButtonGroup::AddButton(const AZStd::string& icon, const AZStd::string& name)
|
||||
{
|
||||
auto buttonId = ButtonId(m_buttons.size() + 1);
|
||||
|
||||
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, buttonId)});
|
||||
if (name.empty())
|
||||
{
|
||||
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, buttonId)});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, name, buttonId)});
|
||||
}
|
||||
return buttonId;
|
||||
}
|
||||
|
||||
Button* Cluster::GetButton(ButtonId buttonId)
|
||||
Button* ButtonGroup::GetButton(ButtonId buttonId)
|
||||
{
|
||||
if (auto buttonEntry = m_buttons.find(buttonId); buttonEntry != m_buttons.end())
|
||||
{
|
||||
@@ -70,7 +67,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZStd::vector<Button*> Cluster::GetButtons()
|
||||
AZStd::vector<Button*> ButtonGroup::GetButtons()
|
||||
{
|
||||
auto buttons = AZStd::vector<Button*>();
|
||||
for (const auto& button : m_buttons)
|
||||
@@ -80,11 +77,11 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return buttons;
|
||||
}
|
||||
|
||||
void Cluster::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler) {
|
||||
void ButtonGroup::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler) {
|
||||
handler.Connect(m_buttonTriggeredEvent);
|
||||
}
|
||||
|
||||
void Cluster::PressButton(ButtonId buttonId)
|
||||
void ButtonGroup::PressButton(ButtonId buttonId)
|
||||
{
|
||||
m_buttonTriggeredEvent.Signal(buttonId);
|
||||
}
|
||||
+6
-9
@@ -18,23 +18,21 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
class Button;
|
||||
|
||||
//! Data class for a cluster on the Viewport UI. A cluster is defined as a group of buttons with icons
|
||||
//! Data class for a button group on the Viewport UI. A button group is defined as a group of buttons with icons
|
||||
//! each of which can be clicked to trigger an event e.g. toggling between modes.
|
||||
class Cluster
|
||||
//! @note This can be used with either a Cluster or a Switcher with slightly different visuals for each.
|
||||
class ButtonGroup
|
||||
{
|
||||
public:
|
||||
Cluster();
|
||||
~Cluster() = default;
|
||||
ButtonGroup();
|
||||
~ButtonGroup() = default;
|
||||
|
||||
void SetHighlightedButton(ButtonId buttonId);
|
||||
|
||||
void SetViewportUiElementId(ViewportUiElementId id);
|
||||
ViewportUiElementId GetViewportUiElementId() const;
|
||||
|
||||
void SetClusterId(ClusterId id);
|
||||
ClusterId GetClusterId() const;
|
||||
|
||||
ButtonId AddButton(const AZStd::string& icon);
|
||||
ButtonId AddButton(const AZStd::string& icon, const AZStd::string& name = AZStd::string());
|
||||
Button* GetButton(ButtonId buttonId);
|
||||
AZStd::vector<Button*> GetButtons();
|
||||
|
||||
@@ -44,7 +42,6 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
private:
|
||||
AZ::Event<ButtonId> m_buttonTriggeredEvent;
|
||||
ViewportUiElementId m_viewportUiId;
|
||||
ClusterId m_clusterId;
|
||||
AZStd::unordered_map<ButtonId, AZStd::unique_ptr<Button>> m_buttons;
|
||||
};
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
@@ -9,21 +9,22 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzToolsFramework_precompiled.h"
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
ViewportUiCluster::ViewportUiCluster(AZStd::shared_ptr<Cluster> cluster)
|
||||
ViewportUiCluster::ViewportUiCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup)
|
||||
: QToolBar(nullptr)
|
||||
, m_cluster(cluster)
|
||||
, m_buttonGroup(buttonGroup)
|
||||
{
|
||||
setOrientation(Qt::Orientation::Vertical);
|
||||
setStyleSheet("background: black;");
|
||||
|
||||
const AZStd::vector<Button*> buttons = cluster->GetButtons();
|
||||
const AZStd::vector<Button*> buttons = buttonGroup->GetButtons();
|
||||
for (auto button : buttons)
|
||||
{
|
||||
RegisterButton(button);
|
||||
@@ -39,7 +40,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
AddClusterAction(
|
||||
action,
|
||||
[this, button]() {
|
||||
m_cluster->PressButton(button->m_buttonId);
|
||||
m_buttonGroup->PressButton(button->m_buttonId);
|
||||
},
|
||||
[button](QAction* action) {
|
||||
action->setChecked(button->m_state == Button::State::Selected);
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
|
||||
#include <QToolBar>
|
||||
|
||||
class Cluster;
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
class ButtonGroup;
|
||||
|
||||
//! Helper class to make clusters (toolbars) for display in Viewport UI.
|
||||
class ViewportUiCluster
|
||||
: public QToolBar
|
||||
@@ -29,7 +29,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ViewportUiCluster(AZStd::shared_ptr<Cluster> cluster);
|
||||
ViewportUiCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup);
|
||||
~ViewportUiCluster() = default;
|
||||
|
||||
//! Adds a new button to the cluster.
|
||||
@@ -49,7 +49,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
//! Removes an action from the Viewport UI Cluster.
|
||||
void RemoveClusterAction(QAction* action);
|
||||
|
||||
AZStd::shared_ptr<Cluster> m_cluster; //!< Data structure which the cluster will be displaying to the Viewport UI.
|
||||
AZStd::shared_ptr<ButtonGroup> m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI.
|
||||
AZStd::unordered_map<ButtonId, QPointer<QAction>> m_buttonActionMap; //!< Map for buttons to their corresponding actions.
|
||||
ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates.
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiTextField.h>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -55,16 +56,16 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
UnparentWidgets(m_viewportUiElements);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<Cluster> cluster)
|
||||
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup)
|
||||
{
|
||||
if (!cluster.get())
|
||||
if (!buttonGroup.get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto viewportUiCluster = AZStd::make_shared<ViewportUiCluster>(cluster);
|
||||
auto viewportUiCluster = AZStd::make_shared<ViewportUiCluster>(buttonGroup);
|
||||
auto id = AddViewportUiElement(viewportUiCluster);
|
||||
cluster->SetViewportUiElementId(id);
|
||||
buttonGroup->SetViewportUiElementId(id);
|
||||
PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft);
|
||||
}
|
||||
|
||||
@@ -93,6 +94,51 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup)
|
||||
{
|
||||
if (!buttonGroup.get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto viewportUiSwitcher = AZStd::make_shared<ViewportUiSwitcher>(buttonGroup);
|
||||
auto id = AddViewportUiElement(viewportUiSwitcher);
|
||||
buttonGroup->SetViewportUiElementId(id);
|
||||
PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddSwitcherButton(const ViewportUiElementId clusterId, Button* button)
|
||||
{
|
||||
if (auto viewportUiSwitcher = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
viewportUiSwitcher->AddButton(button);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::RemoveSwitcherButton(ViewportUiElementId clusterId, ButtonId buttonId)
|
||||
{
|
||||
if (auto cluster = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
cluster->RemoveButton(buttonId);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::UpdateSwitcher(ViewportUiElementId clusterId)
|
||||
{
|
||||
if (auto cluster = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
cluster->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::SetSwitcherActiveButton(ViewportUiElementId clusterId, ButtonId buttonId)
|
||||
{
|
||||
if (auto viewportUiSwitcher = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
viewportUiSwitcher->SetActiveButton(buttonId);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddTextField(AZStd::shared_ptr<TextField> textField)
|
||||
{
|
||||
if (!textField.get())
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/TextField.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
|
||||
@@ -56,11 +56,17 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
ViewportUiDisplay(QWidget* parent, QWidget* renderOverlay);
|
||||
~ViewportUiDisplay();
|
||||
|
||||
void AddCluster(AZStd::shared_ptr<Cluster> cluster);
|
||||
void AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup);
|
||||
void AddClusterButton(ViewportUiElementId clusterId, Button* button);
|
||||
void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId);
|
||||
void UpdateCluster(const ViewportUiElementId clusterId);
|
||||
|
||||
void AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup);
|
||||
void AddSwitcherButton(ViewportUiElementId switcherId, Button* button);
|
||||
void RemoveSwitcherButton(ViewportUiElementId switcherId, ButtonId buttonId);
|
||||
void UpdateSwitcher(ViewportUiElementId switcherId);
|
||||
void SetSwitcherActiveButton(ViewportUiElementId switcherId, ButtonId buttonId);
|
||||
|
||||
void AddTextField(AZStd::shared_ptr<TextField> textField);
|
||||
void UpdateTextField(ViewportUiElementId textFieldId);
|
||||
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
// create a 3x2 map of sub layouts which will stack widgets according to their mapped alignment
|
||||
m_internalLayouts = AZStd::unordered_map<Qt::Alignment, QBoxLayout*> {
|
||||
CreateSubLayout(new QHBoxLayout(), 0, 0, Qt::AlignTop | Qt::AlignLeft),
|
||||
CreateSubLayout(new QVBoxLayout(), 0, 0, Qt::AlignTop | Qt::AlignLeft),
|
||||
CreateSubLayout(new QHBoxLayout(), 1, 0, Qt::AlignBottom | Qt::AlignLeft),
|
||||
CreateSubLayout(new QVBoxLayout(), 0, 1, Qt::AlignTop),
|
||||
CreateSubLayout(new QHBoxLayout(), 1, 1, Qt::AlignBottom),
|
||||
@@ -60,7 +60,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
AZStd::pair<Qt::Alignment, QBoxLayout*> ViewportUiDisplayLayout::CreateSubLayout(
|
||||
QBoxLayout* layout, const int row, const int column, const Qt::Alignment alignment)
|
||||
{
|
||||
layout->setAlignment(alignment);
|
||||
layout->setAlignment(alignment);
|
||||
|
||||
// add an invisible spacer (stretch) to occupy empty space
|
||||
// without this, alignment and resizing within the sublayouts becomes difficult
|
||||
|
||||
+119
-39
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
|
||||
@@ -32,36 +32,64 @@ namespace AzToolsFramework::ViewportUi
|
||||
|
||||
const ClusterId ViewportUiManager::CreateCluster()
|
||||
{
|
||||
auto cluster = AZStd::make_shared<Internal::Cluster>();
|
||||
m_viewportUi->AddCluster(cluster);
|
||||
auto buttonGroup = AZStd::make_shared<Internal::ButtonGroup>();
|
||||
m_viewportUi->AddCluster(buttonGroup);
|
||||
|
||||
return RegisterNewCluster(cluster);
|
||||
return RegisterNewCluster(buttonGroup);
|
||||
}
|
||||
|
||||
const SwitcherId ViewportUiManager::CreateSwitcher()
|
||||
{
|
||||
auto buttonGroup = AZStd::make_shared<Internal::ButtonGroup>();
|
||||
m_viewportUi->AddSwitcher(buttonGroup);
|
||||
|
||||
return RegisterNewSwitcher(buttonGroup);
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetClusterActiveButton(const ClusterId clusterId, const ButtonId buttonId)
|
||||
{
|
||||
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
auto cluster = clusterEntry->second;
|
||||
auto cluster = clusterIt->second;
|
||||
cluster->SetHighlightedButton(buttonId);
|
||||
UpdateClusterUi(cluster.get());
|
||||
UpdateButtonGroupUi(cluster.get());
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetSwitcherActiveButton(const SwitcherId switcherId, const ButtonId buttonId)
|
||||
{
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
auto switcher = switcherIt->second;
|
||||
switcher->SetHighlightedButton(buttonId);
|
||||
m_viewportUi->SetSwitcherActiveButton(switcher->GetViewportUiElementId(), buttonId);
|
||||
UpdateButtonGroupUi(switcher.get());
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::RegisterClusterEventHandler(const ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler)
|
||||
{
|
||||
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
auto cluster = clusterEntry->second;
|
||||
auto cluster = clusterIt->second;
|
||||
cluster->ConnectEventHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::RegisterSwitcherEventHandler(const SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler)
|
||||
{
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
auto switcher = switcherIt->second;
|
||||
switcher->ConnectEventHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
const ButtonId ViewportUiManager::CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon)
|
||||
{
|
||||
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
auto cluster = clusterEntry->second;
|
||||
auto cluster = clusterIt->second;
|
||||
auto newId = cluster->AddButton(icon);
|
||||
m_viewportUi->AddClusterButton(cluster->GetViewportUiElementId(), cluster->GetButton(newId));
|
||||
|
||||
@@ -71,12 +99,35 @@ namespace AzToolsFramework::ViewportUi
|
||||
return ButtonId(0);
|
||||
}
|
||||
|
||||
const ButtonId ViewportUiManager::CreateSwitcherButton(const SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name)
|
||||
{
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
auto switcher = switcherIt->second;
|
||||
auto newId = switcher->AddButton(icon, name);
|
||||
m_viewportUi->AddSwitcherButton(switcher->GetViewportUiElementId(), switcher->GetButton(newId));
|
||||
|
||||
return newId;
|
||||
}
|
||||
|
||||
return ButtonId(0);
|
||||
}
|
||||
|
||||
void ViewportUiManager::RemoveCluster(const ClusterId clusterId)
|
||||
{
|
||||
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
m_clusters.erase(clusterEntry);
|
||||
m_viewportUi->RemoveViewportUiElement(clusterEntry->second->GetViewportUiElementId());
|
||||
m_clusterButtonGroups.erase(clusterIt);
|
||||
m_viewportUi->RemoveViewportUiElement(clusterIt->second->GetViewportUiElementId());
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::RemoveSwitcher(SwitcherId switcherId)
|
||||
{
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
m_switcherButtonGroups.erase(switcherIt);
|
||||
m_viewportUi->RemoveViewportUiElement(switcherIt->second->GetViewportUiElementId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +144,24 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetClusterVisible(ClusterId clusterId, bool visible)
|
||||
void ViewportUiManager::SetClusterVisible(const ClusterId clusterId, bool visible)
|
||||
{
|
||||
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
auto cluster = clusterEntry->second;
|
||||
auto cluster = clusterIt->second;
|
||||
SetViewportUiElementVisible(m_viewportUi.get(), cluster->GetViewportUiElementId(), visible);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetSwitcherVisible(const SwitcherId switcherId, bool visible)
|
||||
{
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
auto switcher = switcherIt->second;
|
||||
SetViewportUiElementVisible(m_viewportUi.get(), switcher->GetViewportUiElementId(), visible);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible)
|
||||
{
|
||||
for (auto clusterId : clusterGroup)
|
||||
@@ -123,9 +183,9 @@ namespace AzToolsFramework::ViewportUi
|
||||
|
||||
void ViewportUiManager::SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text)
|
||||
{
|
||||
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
|
||||
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
|
||||
{
|
||||
auto textField = textFieldEntry->second;
|
||||
auto textField = textFieldIt->second;
|
||||
textField->m_fieldText = text;
|
||||
UpdateTextFieldUi(textField.get());
|
||||
}
|
||||
@@ -134,27 +194,27 @@ namespace AzToolsFramework::ViewportUi
|
||||
void ViewportUiManager::RegisterTextFieldCallback(
|
||||
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler)
|
||||
{
|
||||
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
|
||||
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
|
||||
{
|
||||
auto textField = textFieldEntry->second;
|
||||
auto textField = textFieldIt->second;
|
||||
textField->ConnectEventHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::RemoveTextField(TextFieldId textFieldId)
|
||||
{
|
||||
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
|
||||
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
|
||||
{
|
||||
m_textFields.erase(textFieldEntry);
|
||||
m_viewportUi->RemoveViewportUiElement(textFieldEntry->second->m_viewportId);
|
||||
m_textFields.erase(textFieldIt);
|
||||
m_viewportUi->RemoveViewportUiElement(textFieldIt->second->m_viewportId);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::SetTextFieldVisible(TextFieldId textFieldId, bool visible)
|
||||
{
|
||||
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
|
||||
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
|
||||
{
|
||||
auto textField = textFieldEntry->second;
|
||||
auto textField = textFieldIt->second;
|
||||
SetViewportUiElementVisible(m_viewportUi.get(), textField->m_viewportId, visible);
|
||||
}
|
||||
}
|
||||
@@ -173,10 +233,19 @@ namespace AzToolsFramework::ViewportUi
|
||||
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
|
||||
{
|
||||
// Find cluster using ID and cluster map
|
||||
if (auto clusterEntry = m_clusters.find(clusterId);
|
||||
clusterEntry != m_clusters.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId);
|
||||
clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
clusterEntry->second->PressButton(buttonId);
|
||||
clusterIt->second->PressButton(buttonId);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::PressButton(SwitcherId switcherId, ButtonId buttonId)
|
||||
{
|
||||
// Find cluster using ID and cluster map
|
||||
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
|
||||
{
|
||||
switcherIt->second->PressButton(buttonId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,21 +265,32 @@ namespace AzToolsFramework::ViewportUi
|
||||
{
|
||||
m_viewportUi->Update();
|
||||
|
||||
for (auto clusterEntry : m_clusters)
|
||||
for (auto buttonGroup : m_clusterButtonGroups)
|
||||
{
|
||||
UpdateClusterUi(clusterEntry.second.get());
|
||||
UpdateButtonGroupUi(buttonGroup.second.get());
|
||||
}
|
||||
for (auto textFieldEntry : m_textFields)
|
||||
for (auto buttonGroup : m_switcherButtonGroups)
|
||||
{
|
||||
UpdateTextFieldUi(textFieldEntry.second.get());
|
||||
UpdateButtonGroupUi(buttonGroup.second.get());
|
||||
}
|
||||
for (auto textField : m_textFields)
|
||||
{
|
||||
UpdateTextFieldUi(textField.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
ClusterId ViewportUiManager::RegisterNewCluster(AZStd::shared_ptr<Internal::Cluster>& cluster)
|
||||
ClusterId ViewportUiManager::RegisterNewCluster(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup)
|
||||
{
|
||||
ClusterId newId = ClusterId(m_clusters.size() + 1);
|
||||
cluster->SetClusterId(newId);
|
||||
m_clusters.insert({ newId, cluster });
|
||||
ClusterId newId = ClusterId(m_clusterButtonGroups.size() + 1);
|
||||
m_clusterButtonGroups.insert({ newId, buttonGroup });
|
||||
|
||||
return newId;
|
||||
}
|
||||
|
||||
SwitcherId ViewportUiManager::RegisterNewSwitcher(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup)
|
||||
{
|
||||
SwitcherId newId = SwitcherId(m_switcherButtonGroups.size() + 1);
|
||||
m_switcherButtonGroups.insert({newId, buttonGroup});
|
||||
|
||||
return newId;
|
||||
}
|
||||
@@ -224,9 +304,9 @@ namespace AzToolsFramework::ViewportUi
|
||||
return newId;
|
||||
}
|
||||
|
||||
void ViewportUiManager::UpdateClusterUi(Internal::Cluster* cluster)
|
||||
void ViewportUiManager::UpdateButtonGroupUi(Internal::ButtonGroup* buttonGroup)
|
||||
{
|
||||
m_viewportUi->UpdateCluster(cluster->GetViewportUiElementId());
|
||||
m_viewportUi->UpdateCluster(buttonGroup->GetViewportUiElementId());
|
||||
}
|
||||
|
||||
void ViewportUiManager::UpdateTextFieldUi(Internal::TextField* textField)
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
* 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 <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/TextField.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
|
||||
@@ -21,6 +20,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
class ButtonGroup;
|
||||
class ViewportUiDisplay;
|
||||
}
|
||||
|
||||
@@ -29,26 +29,32 @@ namespace AzToolsFramework::ViewportUi
|
||||
public:
|
||||
ViewportUiManager() = default;
|
||||
~ViewportUiManager() = default;
|
||||
|
||||
|
||||
// ViewportUiRequestBus ...
|
||||
const ClusterId CreateCluster() override;
|
||||
const SwitcherId CreateSwitcher() override;
|
||||
void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override;
|
||||
void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override;
|
||||
const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override;
|
||||
const ButtonId CreateSwitcherButton(
|
||||
SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) override;
|
||||
void RegisterClusterEventHandler(ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler) override;
|
||||
void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) override;
|
||||
void RemoveCluster(ClusterId clusterId) override;
|
||||
void RemoveSwitcher(SwitcherId switcherId) override;
|
||||
void SetClusterVisible(ClusterId clusterId, bool visible);
|
||||
void SetSwitcherVisible(SwitcherId switcherId, bool visible);
|
||||
void SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible) override;
|
||||
const TextFieldId CreateTextField(
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText,
|
||||
TextFieldValidationType validationType) override;
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText, TextFieldValidationType validationType) override;
|
||||
void SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text) override;
|
||||
void RegisterTextFieldCallback(
|
||||
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
|
||||
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
|
||||
void RemoveTextField(TextFieldId textFieldId) override;
|
||||
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
|
||||
void CreateComponentModeBorder(const AZStd::string& borderTitle) override;
|
||||
void RemoveComponentModeBorder() override;
|
||||
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
|
||||
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
|
||||
|
||||
//! Connects to the correct viewportId bus address.
|
||||
void ConnectViewportUiBus(const int viewportId);
|
||||
@@ -60,17 +66,23 @@ namespace AzToolsFramework::ViewportUi
|
||||
void Update();
|
||||
|
||||
protected:
|
||||
AZStd::unordered_map<ClusterId, AZStd::shared_ptr<Internal::Cluster>> m_clusters; //!< A map of all registered clusters.
|
||||
AZStd::unordered_map<TextFieldId, AZStd::shared_ptr<Internal::TextField>> m_textFields; //!< A map of all registered textFields.
|
||||
AZStd::unordered_map<ClusterId, AZStd::shared_ptr<Internal::ButtonGroup>>
|
||||
m_clusterButtonGroups; //!< A map of all registered Clusters.
|
||||
AZStd::unordered_map<SwitcherId, AZStd::shared_ptr<Internal::ButtonGroup>>
|
||||
m_switcherButtonGroups; //!< A map of all registered Switchers.
|
||||
AZStd::unordered_map<TextFieldId, AZStd::shared_ptr<Internal::TextField>> m_textFields; //!< A map of all registered TextFields.
|
||||
|
||||
AZStd::unique_ptr<Internal::ViewportUiDisplay> m_viewportUi; //!< The lower level graphical API for Viewport UI.
|
||||
|
||||
private:
|
||||
//! Register a new cluster and return its id.
|
||||
ClusterId RegisterNewCluster(AZStd::shared_ptr<Internal::Cluster>& cluster);
|
||||
//! Register a new Cluster and return its id.
|
||||
ClusterId RegisterNewCluster(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup);
|
||||
//! Register a new Switcher and return its id.
|
||||
SwitcherId RegisterNewSwitcher(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup);
|
||||
//! Register a new text field and return its id.
|
||||
TextFieldId RegisterNewTextField(AZStd::shared_ptr<Internal::TextField>& textField);
|
||||
//! Update the corresponding ui element for the given cluster.
|
||||
void UpdateClusterUi(Internal::Cluster* cluster);
|
||||
//! Update the corresponding ui element for the given button group.
|
||||
void UpdateButtonGroupUi(Internal::ButtonGroup* buttonGroup);
|
||||
//! Update the corresponding ui element for the given text field.
|
||||
void UpdateTextFieldUi(Internal::TextField* textField);
|
||||
};
|
||||
|
||||
+28
-16
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
* 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
|
||||
|
||||
@@ -23,11 +23,13 @@ namespace AzToolsFramework::ViewportUi
|
||||
using ViewportUiElementId = IdType<struct ViewportUiIdType>;
|
||||
using ButtonId = IdType<struct ButtonIdType>;
|
||||
using ClusterId = IdType<struct ClusterIdType>;
|
||||
using SwitcherId = IdType<struct SwitcherIdType>;
|
||||
using TextFieldId = IdType<struct TextFieldIdType>;
|
||||
|
||||
inline const ViewportUiElementId InvalidViewportUiElementId = ViewportUiElementId(0);
|
||||
inline const ButtonId InvalidButtonId = ButtonId(0);
|
||||
inline const ClusterId InvalidClusterId = ClusterId(0);
|
||||
inline const SwitcherId InvalidSwitcherId = SwitcherId(0);
|
||||
|
||||
inline const int DefaultViewportId = 0;
|
||||
|
||||
@@ -46,27 +48,36 @@ namespace AzToolsFramework::ViewportUi
|
||||
public:
|
||||
//! Creates and registers a cluster with the Viewport UI system.
|
||||
virtual const ClusterId CreateCluster() = 0;
|
||||
//! Creates and registers a switcher with the Viewport UI system.
|
||||
virtual const SwitcherId CreateSwitcher() = 0;
|
||||
//! Sets the active button of the cluster. This is the button which will display as highlighted.
|
||||
virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0;
|
||||
//! Sets the active button of the switcher. This is the button which has a text label.
|
||||
virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0;
|
||||
//! Registers a new button onto a cluster.
|
||||
virtual const ButtonId CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon) = 0;
|
||||
//! Registers a new button onto a switcher.
|
||||
virtual const ButtonId CreateSwitcherButton(
|
||||
SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) = 0;
|
||||
//! Registers an event handler to handle events from the cluster.
|
||||
virtual void RegisterClusterEventHandler(ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler) = 0;
|
||||
//! Registers an event handler to handle events from the cluster.
|
||||
virtual void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) = 0;
|
||||
//! Removes a cluster from the Viewport UI system.
|
||||
virtual void RemoveCluster(ClusterId clusterId) = 0;
|
||||
//!
|
||||
virtual void RemoveSwitcher(SwitcherId switcherId) = 0;
|
||||
//! Sets the visibility of the cluster.
|
||||
virtual void SetClusterVisible(ClusterId clusterId, bool visible) = 0;
|
||||
//! Sets the visibility of multiple clusters.
|
||||
virtual void SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible) = 0;
|
||||
//! Creates and registers a text field with the Viewport UI system.
|
||||
virtual const TextFieldId CreateTextField(
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText,
|
||||
TextFieldValidationType validationType) = 0;
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText, TextFieldValidationType validationType) = 0;
|
||||
//! Set the text that will go inside the text field.
|
||||
virtual void SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text) = 0;
|
||||
//! Register an event handler to handle when the text field text changes.
|
||||
virtual void RegisterTextFieldCallback(
|
||||
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) = 0;
|
||||
virtual void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) = 0;
|
||||
//! Removes a text field from the Viewport UI system.
|
||||
virtual void RemoveTextField(TextFieldId textFieldId) = 0;
|
||||
//! Sets the visibility of the text field.
|
||||
@@ -77,11 +88,12 @@ namespace AzToolsFramework::ViewportUi
|
||||
virtual void RemoveComponentModeBorder() = 0;
|
||||
//! Invoke a button press in a cluster.
|
||||
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
|
||||
//!
|
||||
virtual void PressButton(SwitcherId switcherId, ButtonId buttonId) = 0;
|
||||
};
|
||||
|
||||
/// The EBusTraits for ViewportInteractionRequests.
|
||||
class ViewportUiBusTraits
|
||||
: public AZ::EBusTraits
|
||||
class ViewportUiBusTraits : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
using BusIdType = int; ///< ViewportId - used to address requests to this EBus.
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
ViewportUiSwitcher::ViewportUiSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup)
|
||||
: m_buttonGroup(buttonGroup)
|
||||
{
|
||||
setOrientation(Qt::Orientation::Horizontal);
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||
setStyleSheet(QString("QToolBar {background-color: none; border: none; spacing: 3px;}"
|
||||
"QToolButton {background-color: black; border: outset; border-color: white; border-radius: 7px; "
|
||||
"border-width: 2px; padding: 7px; color: white;}"));
|
||||
|
||||
// Add am empty active button (is set in the call to SetActiveMode)
|
||||
m_activeButton = new QToolButton();
|
||||
// No hover effect for the main button as it's not clickable
|
||||
m_activeButton->setProperty("IconHasHoverEffect", false);
|
||||
m_activeButton->setCheckable(false);
|
||||
m_activeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
addWidget(m_activeButton);
|
||||
|
||||
const AZStd::vector<Button*> buttons = buttonGroup->GetButtons();
|
||||
|
||||
for (auto button : buttons)
|
||||
{
|
||||
// Add all the buttons as actions
|
||||
if (button->m_buttonId)
|
||||
{
|
||||
AddButton(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewportUiSwitcher::~ViewportUiSwitcher()
|
||||
{
|
||||
delete m_activeButton;
|
||||
}
|
||||
|
||||
void ViewportUiSwitcher::AddButton(Button* button)
|
||||
{
|
||||
QAction* action = new QAction();
|
||||
action->setCheckable(true);
|
||||
action->setIcon(QIcon(QString(button->m_icon.c_str())));
|
||||
|
||||
if (!action)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// set hover to true by default
|
||||
action->setProperty("IconHasHoverEffect", true);
|
||||
|
||||
// add the action
|
||||
addAction(action);
|
||||
|
||||
// resize to fit new action with minimum extra space
|
||||
resize(minimumSizeHint());
|
||||
|
||||
const AZStd::function<void()>& callback = [this, button]() { m_buttonGroup->PressButton(button->m_buttonId); };
|
||||
const AZStd::function<void(QAction*)>& updateCallback = [button](QAction* action) {
|
||||
action->setChecked(button->m_state == Button::State::Selected);
|
||||
};
|
||||
|
||||
// connect the callback if provided
|
||||
if (callback)
|
||||
{
|
||||
QObject::connect(action, &QAction::triggered, action, callback);
|
||||
}
|
||||
|
||||
// register the action
|
||||
m_widgetCallbacks.AddWidget(
|
||||
action, [updateCallback](QPointer<QObject> object) { updateCallback(static_cast<QAction*>(object.data())); });
|
||||
|
||||
m_buttonActionMap.insert({button->m_buttonId, action});
|
||||
}
|
||||
|
||||
void ViewportUiSwitcher::RemoveButton(ButtonId buttonId)
|
||||
{
|
||||
if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end())
|
||||
{
|
||||
QAction* action = actionEntry->second;
|
||||
|
||||
// remove the action from the toolbar
|
||||
removeAction(action);
|
||||
|
||||
// deregister from the widget manager
|
||||
m_widgetCallbacks.RemoveWidget(action);
|
||||
|
||||
// resize to fit new area with minimum extra space
|
||||
resize(minimumSizeHint());
|
||||
|
||||
m_buttonActionMap.erase(buttonId);
|
||||
|
||||
// reset current active mode if its the button being removed
|
||||
if (buttonId == m_activeButtonId)
|
||||
{
|
||||
if (auto nextEntry = m_buttonActionMap.find(ButtonId(buttonId + 1)); nextEntry != m_buttonActionMap.end())
|
||||
{
|
||||
SetActiveButton(nextEntry->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiSwitcher::Update()
|
||||
{
|
||||
m_widgetCallbacks.Update();
|
||||
}
|
||||
|
||||
void ViewportUiSwitcher::SetActiveButton(ButtonId buttonId)
|
||||
{
|
||||
// Check if it is the first active mode to be set
|
||||
bool initialActiveMode = (m_activeButtonId == ButtonId(0));
|
||||
|
||||
// Change the toolbutton's name and icon to that button
|
||||
const AZStd::vector<Button*> buttons = m_buttonGroup->GetButtons();
|
||||
auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); };
|
||||
|
||||
if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end())
|
||||
{
|
||||
QString buttonName = ((*buttonIt)->m_name).c_str();
|
||||
QIcon buttonIcon = QIcon(QString(((*buttonIt)->m_icon).c_str()));
|
||||
m_activeButton->setIcon(buttonIcon);
|
||||
m_activeButton->setText(buttonName);
|
||||
}
|
||||
|
||||
// Look up button ID in map then remove it from its current position
|
||||
auto itr = m_buttonActionMap.find(buttonId);
|
||||
QAction* action = itr->second;
|
||||
removeAction(action);
|
||||
|
||||
if (!initialActiveMode)
|
||||
{
|
||||
// Add the last action removed
|
||||
if (m_activeButtonId != buttonId)
|
||||
{
|
||||
itr = m_buttonActionMap.find(m_activeButtonId);
|
||||
action = itr->second;
|
||||
addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
m_activeButtonId = buttonId;
|
||||
}
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
|
||||
#include <functional>
|
||||
#include <QPointer>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
class ButtonGroup;
|
||||
|
||||
//! Helper class to make switchers (toolbars) for display in Viewport UI.
|
||||
class ViewportUiSwitcher : public QToolBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ViewportUiSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup);
|
||||
~ViewportUiSwitcher();
|
||||
//! Adds a new button to the switcher.
|
||||
void AddButton(Button* button);
|
||||
//! Removes a button from the switcher.
|
||||
void RemoveButton(ButtonId buttonId);
|
||||
void Update();
|
||||
//! Changes the m_activeButton.
|
||||
void SetActiveButton(ButtonId buttonId);
|
||||
|
||||
private:
|
||||
QToolButton* m_activeButton; //!< The first button in the toolbar. Only button with a label/text.
|
||||
ButtonId m_activeButtonId = ButtonId(0); //!< ButtonId corresponding to the active button in the buttonActionMap.
|
||||
AZStd::shared_ptr<ButtonGroup> m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI.
|
||||
AZStd::unordered_map<ButtonId, QPointer<QAction>> m_buttonActionMap; //!< Map for buttons to their corresponding actions.
|
||||
ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates.
|
||||
};
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
@@ -487,8 +487,8 @@ set(FILES
|
||||
Viewport/ViewportTypes.cpp
|
||||
ViewportUi/Button.h
|
||||
ViewportUi/Button.cpp
|
||||
ViewportUi/Cluster.h
|
||||
ViewportUi/Cluster.cpp
|
||||
ViewportUi/ButtonGroup.h
|
||||
ViewportUi/ButtonGroup.cpp
|
||||
ViewportUi/TextField.h
|
||||
ViewportUi/TextField.cpp
|
||||
ViewportUi/ViewportUiDisplay.h
|
||||
@@ -500,6 +500,8 @@ set(FILES
|
||||
ViewportUi/ViewportUiTextField.cpp
|
||||
ViewportUi/ViewportUiCluster.h
|
||||
ViewportUi/ViewportUiCluster.cpp
|
||||
ViewportUi/ViewportUiSwitcher.h
|
||||
ViewportUi/ViewportUiSwitcher.cpp
|
||||
ViewportUi/ViewportUiWidgetCallbacks.h
|
||||
ViewportUi/ViewportUiWidgetCallbacks.cpp
|
||||
ViewportUi/ViewportUiDisplayLayout.h
|
||||
@@ -729,7 +731,7 @@ set(FILES
|
||||
# Prevent the following files from being grouped in UNITY builds
|
||||
set(SKIP_UNITY_BUILD_INCLUSION_FILES
|
||||
# The following files are skipped from unity to avoid duplicated symbols related to an ebus
|
||||
AzToolsFrameworkModule.cpp
|
||||
AzToolsFrameworkModule.cpp
|
||||
Application/ToolsApplication.cpp
|
||||
UI/PropertyEditor/PropertyEntityIdCtrl.cpp
|
||||
UI/PropertyEditor/PropertyManagerComponent.cpp
|
||||
|
||||
@@ -20,35 +20,35 @@
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
|
||||
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
|
||||
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
|
||||
|
||||
TEST(ClusterTest, AddButtonAddsButtonToClusterAndReturnsId)
|
||||
{
|
||||
auto cluster = AZStd::make_unique<Cluster>();
|
||||
auto buttonId = cluster->AddButton("");
|
||||
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
|
||||
auto buttonId = buttonGroup->AddButton("");
|
||||
|
||||
auto button = cluster->GetButton(buttonId);
|
||||
auto button = buttonGroup->GetButton(buttonId);
|
||||
EXPECT_TRUE(button != nullptr);
|
||||
}
|
||||
|
||||
TEST(ClusterTest, SetHighlightedButtonChangesButtonStateToSelected)
|
||||
{
|
||||
auto cluster = AZStd::make_unique<Cluster>();
|
||||
auto buttonId = cluster->AddButton("");
|
||||
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
|
||||
auto buttonId = buttonGroup->AddButton("");
|
||||
|
||||
// check button is not highlighted by default
|
||||
auto button = cluster->GetButton(buttonId);
|
||||
auto button = buttonGroup->GetButton(buttonId);
|
||||
EXPECT_FALSE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
|
||||
|
||||
cluster->SetHighlightedButton(buttonId);
|
||||
buttonGroup->SetHighlightedButton(buttonId);
|
||||
EXPECT_TRUE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
|
||||
}
|
||||
|
||||
TEST(ClusterTest, ConnectEventHandlerConnectsHandlerToButtonTriggeredEvent)
|
||||
{
|
||||
auto cluster = AZStd::make_unique<Cluster>();
|
||||
auto buttonId = cluster->AddButton("");
|
||||
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
|
||||
auto buttonId = buttonGroup->AddButton("");
|
||||
|
||||
// create a handler which will be triggered by the cluster
|
||||
bool handlerTriggered = false;
|
||||
@@ -62,8 +62,8 @@ namespace UnitTest
|
||||
}
|
||||
});
|
||||
|
||||
cluster->ConnectEventHandler(handler);
|
||||
cluster->PressButton(buttonId);
|
||||
buttonGroup->ConnectEventHandler(handler);
|
||||
buttonGroup->PressButton(buttonId);
|
||||
|
||||
EXPECT_TRUE(handlerTriggered);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzToolsFramework/ViewportUi/Cluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
@@ -23,14 +23,14 @@
|
||||
namespace UnitTest
|
||||
{
|
||||
using ViewportUiCluster = AzToolsFramework::ViewportUi::Internal::ViewportUiCluster;
|
||||
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
|
||||
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
|
||||
using Button = AzToolsFramework::ViewportUi::Internal::Button;
|
||||
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
|
||||
|
||||
TEST(ViewportUiCluster, RegisterButtonIncreasesClusterHeight)
|
||||
{
|
||||
auto clusterInfo = AZStd::make_shared<Cluster>();
|
||||
ViewportUiCluster viewportUiCluster(clusterInfo);
|
||||
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
ViewportUiCluster viewportUiCluster(buttonGroup);
|
||||
viewportUiCluster.resize(viewportUiCluster.minimumSizeHint());
|
||||
|
||||
// need to initialize cluster with a single button or size will be invalid
|
||||
@@ -48,8 +48,8 @@ namespace UnitTest
|
||||
|
||||
TEST(ViewportUiCluster, RemoveClusterButtonDecreasesClusterHeight)
|
||||
{
|
||||
auto clusterInfo = AZStd::make_shared<Cluster>();
|
||||
ViewportUiCluster viewportUiCluster(clusterInfo);
|
||||
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
ViewportUiCluster viewportUiCluster(buttonGroup);
|
||||
viewportUiCluster.resize(viewportUiCluster.minimumSizeHint());
|
||||
|
||||
// need to initialize cluster with a single button or size will be invalid
|
||||
@@ -70,8 +70,8 @@ namespace UnitTest
|
||||
|
||||
TEST(ViewportUiCluster, UpdateChangesActiveButton)
|
||||
{
|
||||
auto clusterInfo = AZStd::make_shared<Cluster>();
|
||||
ViewportUiCluster viewportUiCluster(clusterInfo);
|
||||
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
ViewportUiCluster viewportUiCluster(buttonGroup);
|
||||
|
||||
// register a button to the cluster
|
||||
auto button = AZStd::make_unique<Button>("", ButtonId(1));
|
||||
@@ -93,8 +93,8 @@ namespace UnitTest
|
||||
|
||||
TEST(ViewportUiCluster, TriggeringActionTriggersClusterEventForButton)
|
||||
{
|
||||
auto clusterInfo = AZStd::make_shared<Cluster>();
|
||||
ViewportUiCluster viewportUiCluster(clusterInfo);
|
||||
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
ViewportUiCluster viewportUiCluster(buttonGroup);
|
||||
|
||||
// create a handler which will be triggered by the button
|
||||
bool handlerTriggered = false;
|
||||
@@ -107,7 +107,7 @@ namespace UnitTest
|
||||
handlerTriggered = true;
|
||||
}
|
||||
});
|
||||
clusterInfo->ConnectEventHandler(handler);
|
||||
buttonGroup->ConnectEventHandler(handler);
|
||||
|
||||
// register the button
|
||||
auto button = AZStd::make_unique<Button>("", testButtonId);
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace UnitTest
|
||||
{
|
||||
using ViewportUiDisplay = AzToolsFramework::ViewportUi::Internal::ViewportUiDisplay;
|
||||
using ViewportUiElementId = AzToolsFramework::ViewportUi::ViewportUiElementId;
|
||||
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
|
||||
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
|
||||
|
||||
// sets up a parent widget and render overlay to attach the Viewport UI to
|
||||
// as well as a cluster with one button
|
||||
// as well as a button group with one button
|
||||
class ViewportUiDisplayTestFixture : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
@@ -34,22 +34,22 @@ namespace UnitTest
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
m_cluster = AZStd::make_shared<Cluster>();
|
||||
m_cluster->AddButton("");
|
||||
m_buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
m_buttonGroup->AddButton("");
|
||||
m_parentWidget = new QWidget();
|
||||
m_mockRenderOverlay = new QWidget();
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
{
|
||||
m_cluster.reset();
|
||||
m_buttonGroup.reset();
|
||||
delete m_parentWidget;
|
||||
delete m_mockRenderOverlay;
|
||||
}
|
||||
|
||||
QWidget* m_parentWidget = nullptr;
|
||||
QWidget* m_mockRenderOverlay = nullptr;
|
||||
AZStd::shared_ptr<Cluster> m_cluster = nullptr;
|
||||
AZStd::shared_ptr<ButtonGroup> m_buttonGroup = nullptr;
|
||||
};
|
||||
|
||||
TEST_F(ViewportUiDisplayTestFixture, ViewportUiInitializationReturnsProperlyParentedWidgets)
|
||||
@@ -72,13 +72,13 @@ namespace UnitTest
|
||||
TEST_F(ViewportUiDisplayTestFixture, RemoveViewportUiElementRemovesElementFromViewportUi)
|
||||
{
|
||||
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
|
||||
viewportUi.AddCluster(m_cluster);
|
||||
auto widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
viewportUi.AddCluster(m_buttonGroup);
|
||||
auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
|
||||
EXPECT_TRUE(widget.get() != nullptr);
|
||||
|
||||
viewportUi.RemoveViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
viewportUi.RemoveViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
|
||||
EXPECT_TRUE(widget.get() == nullptr);
|
||||
}
|
||||
@@ -89,11 +89,11 @@ namespace UnitTest
|
||||
|
||||
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
|
||||
viewportUi.InitializeUiOverlay();
|
||||
viewportUi.AddCluster(m_cluster);
|
||||
viewportUi.AddCluster(m_buttonGroup);
|
||||
viewportUi.Update();
|
||||
viewportUi.ShowViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
viewportUi.ShowViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
|
||||
EXPECT_TRUE(viewportUi.IsViewportUiElementVisible(m_cluster->GetViewportUiElementId()));
|
||||
EXPECT_TRUE(viewportUi.IsViewportUiElementVisible(m_buttonGroup->GetViewportUiElementId()));
|
||||
}
|
||||
|
||||
TEST_F(ViewportUiDisplayTestFixture, HideViewportUiElementSetsWidgetVisibilityToFalse)
|
||||
@@ -102,20 +102,20 @@ namespace UnitTest
|
||||
|
||||
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
|
||||
viewportUi.InitializeUiOverlay();
|
||||
viewportUi.AddCluster(m_cluster);
|
||||
viewportUi.HideViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
viewportUi.AddCluster(m_buttonGroup);
|
||||
viewportUi.HideViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
|
||||
EXPECT_FALSE(viewportUi.IsViewportUiElementVisible(m_cluster->GetViewportUiElementId()));
|
||||
EXPECT_FALSE(viewportUi.IsViewportUiElementVisible(m_buttonGroup->GetViewportUiElementId()));
|
||||
}
|
||||
|
||||
TEST_F(ViewportUiDisplayTestFixture, UpdateUiOverlayGeometryChangesGeometryToMatchViewportUiElements)
|
||||
{
|
||||
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
|
||||
viewportUi.InitializeUiOverlay();
|
||||
viewportUi.AddCluster(m_cluster);
|
||||
viewportUi.AddCluster(m_buttonGroup);
|
||||
|
||||
viewportUi.Update();
|
||||
auto widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
|
||||
auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
|
||||
|
||||
EXPECT_EQ(viewportUi.GetUiMainWindow()->mask(), widget->geometry());
|
||||
}
|
||||
@@ -127,14 +127,14 @@ namespace UnitTest
|
||||
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
|
||||
viewportUi.InitializeUiOverlay();
|
||||
|
||||
auto cluster = AZStd::make_shared<Cluster>();
|
||||
cluster->AddButton("");
|
||||
viewportUi.AddCluster(cluster);
|
||||
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
|
||||
buttonGroup->AddButton("");
|
||||
viewportUi.AddCluster(buttonGroup);
|
||||
viewportUi.Update();
|
||||
|
||||
EXPECT_TRUE(viewportUi.GetUiMainWindow()->isVisible());
|
||||
|
||||
viewportUi.RemoveViewportUiElement(cluster->GetViewportUiElementId());
|
||||
viewportUi.RemoveViewportUiElement(buttonGroup->GetViewportUiElementId());
|
||||
viewportUi.Update();
|
||||
EXPECT_FALSE(viewportUi.GetUiMainWindow()->isVisible());
|
||||
}
|
||||
|
||||
@@ -22,19 +22,19 @@ namespace UnitTest
|
||||
{
|
||||
using ViewportUiDisplay = AzToolsFramework::ViewportUi::Internal::ViewportUiDisplay;
|
||||
using ViewportUiElementId = AzToolsFramework::ViewportUi::ViewportUiElementId;
|
||||
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
|
||||
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
|
||||
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
|
||||
|
||||
// child class of ViewportUiManager which exposes the protected cluster and viewport display
|
||||
// child class of ViewportUiManager which exposes the protected button group and viewport display
|
||||
class ViewportUiManagerTestable : public AzToolsFramework::ViewportUi::ViewportUiManager
|
||||
{
|
||||
public:
|
||||
ViewportUiManagerTestable() = default;
|
||||
~ViewportUiManagerTestable() = default;
|
||||
|
||||
const AZStd::unordered_map<AzToolsFramework::ViewportUi::ClusterId, AZStd::shared_ptr<Cluster>>& GetClusterMap()
|
||||
const AZStd::unordered_map<AzToolsFramework::ViewportUi::ClusterId, AZStd::shared_ptr<ButtonGroup>>& GetClusterMap()
|
||||
{
|
||||
return m_clusters;
|
||||
return m_clusterButtonGroups;
|
||||
}
|
||||
|
||||
ViewportUiDisplay* GetViewportUiDisplay()
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace UnitTest
|
||||
|
||||
MOCK_METHOD3(InstantiateDynamicSlice, AzFramework::SliceInstantiationTicket(const AZ::Data::Asset<AZ::Data::AssetData>&, const AZ::Transform&, const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper&));
|
||||
MOCK_METHOD0(GetGameEntityContextId, AzFramework::EntityContextId());
|
||||
MOCK_METHOD0(GetGameEntityContextInstance, AzFramework::EntityContext*());
|
||||
MOCK_METHOD1(CreateGameEntity, AZ::Entity*(const char*));
|
||||
MOCK_METHOD1(AddGameEntity, void (AZ::Entity*));
|
||||
MOCK_METHOD1(DestroyGameEntity, void (const AZ::EntityId&));
|
||||
|
||||
+90
-118
@@ -130,6 +130,8 @@ namespace SceneUnitTest
|
||||
m_systemEntity->CreateComponent<AZ::JobManagerComponent>();
|
||||
m_systemEntity->CreateComponent<AZ::StreamerComponent>();
|
||||
m_systemEntity->Activate();
|
||||
|
||||
m_sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
@@ -146,167 +148,119 @@ namespace SceneUnitTest
|
||||
AZ::IO::FileIOBase* m_prevFileIO;
|
||||
AZ::ComponentApplication m_app;
|
||||
AZ::Entity* m_systemEntity = nullptr;
|
||||
AzFramework::ISceneSystem* m_sceneSystem = nullptr;
|
||||
|
||||
};
|
||||
|
||||
TEST_F(SceneTest, CreateScene)
|
||||
{
|
||||
Scene* scene = nullptr;
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
|
||||
{
|
||||
// A scene should be able to be created with a given name.
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
|
||||
EXPECT_TRUE(createSceneOutcome.IsSuccess()) << "Unable to create a scene.";
|
||||
|
||||
// The scene pointer returned should be valid
|
||||
scene = createSceneOutcome.GetValue();
|
||||
EXPECT_TRUE(scene != nullptr) << "Scene creation reported success, but no scene actually was actually returned.";
|
||||
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
|
||||
EXPECT_NE(scene, nullptr) << "Scene creation reported success, but no scene actually was actually returned.";
|
||||
|
||||
// Attempting to create another scene with the same name should fail.
|
||||
createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
|
||||
createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
|
||||
EXPECT_TRUE(!createSceneOutcome.IsSuccess()) << "Should not be able to create two scenes with the same name.";
|
||||
|
||||
}
|
||||
|
||||
TEST_F(SceneTest, GetScene)
|
||||
{
|
||||
Scene* createdScene = nullptr;
|
||||
Scene* retrievedScene = nullptr;
|
||||
Scene* nullScene = nullptr;
|
||||
const static AZStd::string_view s_sceneName = "TestScene";
|
||||
constexpr AZStd::string_view sceneName = "TestScene";
|
||||
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, s_sceneName);
|
||||
createdScene = createSceneOutcome.GetValue();
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
|
||||
AZStd::shared_ptr<Scene> createdScene = createSceneOutcome.TakeValue();
|
||||
|
||||
// Should be able to get a scene by name, and it should match the scene that was created.
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(retrievedScene, &AzFramework::SceneSystemRequestBus::Events::GetScene, s_sceneName);
|
||||
EXPECT_TRUE(retrievedScene != nullptr) << "Attempting to get scene by name resulted in nullptr.";
|
||||
EXPECT_TRUE(retrievedScene == createdScene) << "Retrieved scene does not match created scene.";
|
||||
AZStd::shared_ptr<Scene> retrievedScene = m_sceneSystem->GetScene(sceneName);
|
||||
EXPECT_NE(retrievedScene, nullptr) << "Attempting to get scene by name resulted in nullptr.";
|
||||
EXPECT_EQ(retrievedScene, createdScene) << "Retrieved scene does not match created scene.";
|
||||
|
||||
// An invalid name should return a null scene.
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(nullScene, &AzFramework::SceneSystemRequestBus::Events::GetScene, "non-existant scene");
|
||||
EXPECT_TRUE(nullScene == nullptr) << "Should not be able to retrieve a scene that wasn't created.";
|
||||
AZStd::shared_ptr<Scene> nullScene = m_sceneSystem->GetScene("non-existant scene");
|
||||
EXPECT_EQ(nullScene, nullptr) << "Should not be able to retrieve a scene that wasn't created.";
|
||||
}
|
||||
|
||||
TEST_F(SceneTest, RemoveScene)
|
||||
{
|
||||
Scene* createdScene = nullptr;
|
||||
const static AZStd::string_view s_sceneName = "TestScene";
|
||||
constexpr AZStd::string_view sceneName = "TestScene";
|
||||
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, s_sceneName);
|
||||
createdScene = createSceneOutcome.GetValue();
|
||||
|
||||
bool success = false;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, s_sceneName);
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
|
||||
bool success = m_sceneSystem->RemoveScene(sceneName);
|
||||
EXPECT_TRUE(success) << "Failed to remove the scene that was just created.";
|
||||
|
||||
success = true;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, "non-existant scene");
|
||||
success = m_sceneSystem->RemoveScene("non-existant scene");
|
||||
EXPECT_FALSE(success) << "Remove scene returned success for a non-existant scene.";
|
||||
}
|
||||
|
||||
TEST_F(SceneTest, GetAllScenes)
|
||||
TEST_F(SceneTest, IterateActiveScenes)
|
||||
{
|
||||
constexpr size_t NumScenes = 5;
|
||||
|
||||
Scene* scenes[NumScenes] = { nullptr };
|
||||
AZStd::shared_ptr<Scene> scenes[NumScenes] = {nullptr};
|
||||
|
||||
for (size_t i = 0; i < NumScenes; ++i)
|
||||
{
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
|
||||
AZStd::string sceneName = AZStd::string::format("scene %zu", i);
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, sceneName);
|
||||
scenes[i] = createSceneOutcome.GetValue();
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
|
||||
scenes[i] = createSceneOutcome.TakeValue();
|
||||
}
|
||||
|
||||
AZStd::vector<Scene*> retrievedScenes;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(retrievedScenes, &AzFramework::SceneSystemRequestBus::Events::GetAllScenes);
|
||||
|
||||
EXPECT_EQ(NumScenes, retrievedScenes.size()) << "GetAllScenes() returned a different number of scenes than those created.";
|
||||
|
||||
for (size_t i = 0; i < NumScenes; ++i)
|
||||
{
|
||||
EXPECT_EQ(scenes[i], retrievedScenes.at(i)) << "GetAllScenes() returned scenes in a different order than they were created.";
|
||||
}
|
||||
size_t index = 0;
|
||||
m_sceneSystem->IterateActiveScenes([&index, &scenes](const AZStd::shared_ptr<Scene>& scene)
|
||||
{
|
||||
EXPECT_EQ(scenes[index++], scene);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(SceneTest, EntityContextSceneMapping)
|
||||
TEST_F(SceneTest, IterateZombieScenes)
|
||||
{
|
||||
AZStd::unique_ptr<SliceEntityOwnershipService> m_entityOwnershipService =
|
||||
AZStd::make_unique<AzFramework::SliceEntityOwnershipService>(AZ::Uuid::CreateNull(), m_app.GetSerializeContext());
|
||||
// Create the entity context, entity, and component
|
||||
EntityContext* testEntityContext = new EntityContext(AZ::Uuid::CreateRandom(), AZStd::move(m_entityOwnershipService));
|
||||
testEntityContext->InitContext();
|
||||
EntityContextId testEntityContextId = testEntityContext->GetContextId();
|
||||
AZ::Entity* testEntity = testEntityContext->CreateEntity("TestEntity");
|
||||
TestComponent* testComponent = testEntity->CreateComponent<TestComponent>();
|
||||
constexpr size_t NumScenes = 5;
|
||||
|
||||
// Try to activate an entity and get the scene before a scene has been set. This should fail.
|
||||
TestComponentConfig failConfig;
|
||||
failConfig.m_activateFunction = [](TestComponent* component)
|
||||
AZStd::shared_ptr<Scene> scenes[NumScenes] = {nullptr};
|
||||
|
||||
// Create zombies.
|
||||
for (size_t i = 0; i < NumScenes; ++i)
|
||||
{
|
||||
(void)component;
|
||||
Scene* scene = nullptr;
|
||||
EntityContextId entityContextId = EntityContextId::CreateNull();
|
||||
AZStd::string sceneName = AZStd::string::format("scene %zu", i);
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene(sceneName);
|
||||
scenes[i] = createSceneOutcome.TakeValue();
|
||||
m_sceneSystem->RemoveScene(sceneName);
|
||||
}
|
||||
|
||||
AzFramework::EntityIdContextQueryBus::BroadcastResult(entityContextId, &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId);
|
||||
// Check to make sure there are no more active scenes.
|
||||
size_t index = 0;
|
||||
m_sceneSystem->IterateActiveScenes([&index, &scenes](const AZStd::shared_ptr<Scene>&)
|
||||
{
|
||||
index++;
|
||||
return true;
|
||||
});
|
||||
EXPECT_EQ(0, index);
|
||||
|
||||
// A null scene should be returned since a scene has not been set for this entity context.
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, entityContextId);
|
||||
EXPECT_TRUE(scene == nullptr) << "Found a scene when one shouldn't exist.";
|
||||
};
|
||||
|
||||
testComponent->SetConfiguration(failConfig);
|
||||
testComponent->Activate();
|
||||
testComponent->Deactivate();
|
||||
// Check that the scenes are still returned as zombies.
|
||||
index = 0;
|
||||
m_sceneSystem->IterateZombieScenes([&index, &scenes](Scene& scene)
|
||||
{
|
||||
EXPECT_EQ(scenes[index++].get(), &scene);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Create the scene
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
|
||||
Scene* scene = createSceneOutcome.GetValue();
|
||||
|
||||
// Map the Entity context to the scene
|
||||
bool success = false;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::SetSceneForEntityContextId, testEntityContextId, scene);
|
||||
EXPECT_TRUE(success) << "Unable to associate an entity context with a scene.";
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::SetSceneForEntityContextId, testEntityContextId, scene);
|
||||
EXPECT_FALSE(success) << "Attempting to map an entity context to a scene that's already mapped, this should not work.";
|
||||
|
||||
// Now it should be possible to get the scene from the entity context within an Entity's Activate()
|
||||
TestComponentConfig successConfig;
|
||||
successConfig.m_activateFunction = [](TestComponent* component)
|
||||
// Check that all scenes are removed when there are no more handles.
|
||||
for (size_t i = 0; i < NumScenes; ++i)
|
||||
{
|
||||
(void)component;
|
||||
Scene* scene = nullptr;
|
||||
EntityContextId entityContextId = EntityContextId::CreateNull();
|
||||
|
||||
AzFramework::EntityIdContextQueryBus::BroadcastResult(entityContextId, &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId);
|
||||
|
||||
// A scene should be returned since a scene has been set for this entity context.
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, entityContextId);
|
||||
EXPECT_TRUE(scene != nullptr) << "Could not find a scene for the entity context.";
|
||||
};
|
||||
|
||||
testComponent->SetConfiguration(successConfig);
|
||||
testComponent->Activate();
|
||||
testComponent->Deactivate();
|
||||
|
||||
// Now remove the entity context / scene association and make sure things fail again.
|
||||
success = false;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveSceneForEntityContextId, testEntityContextId, nullptr);
|
||||
EXPECT_FALSE(success) << "Should not be able to remove an entity context from a scene it's not associated with.";
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequestBus::Events::RemoveSceneForEntityContextId, testEntityContextId, scene);
|
||||
EXPECT_TRUE(success) << "Was not able to remove an entity context from a scene it's associated with.";
|
||||
|
||||
testComponent->SetConfiguration(failConfig);
|
||||
testComponent->Activate();
|
||||
testComponent->Deactivate();
|
||||
|
||||
delete testEntityContext; // This should also clean up owned entities / components.
|
||||
scenes[i].reset();
|
||||
}
|
||||
index = 0;
|
||||
m_sceneSystem->IterateZombieScenes([&index, &scenes](Scene&) {
|
||||
index++;
|
||||
return true;
|
||||
});
|
||||
EXPECT_EQ(0, index);
|
||||
}
|
||||
|
||||
// Test classes for use in the SceneSystem test. These can't be defined in the test itself due to some functions created by AZ_RTTI not having a body which breaks VS2015.
|
||||
@@ -324,30 +278,48 @@ namespace SceneUnitTest
|
||||
TEST_F(SceneTest, SceneSystem)
|
||||
{
|
||||
// Create the scene
|
||||
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("");
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequestBus::Events::CreateScene, "TestScene");
|
||||
AzFramework::Scene* scene = createSceneOutcome.GetValue();
|
||||
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome = m_sceneSystem->CreateScene("TestScene");
|
||||
EXPECT_TRUE(createSceneOutcome.IsSuccess());
|
||||
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
|
||||
|
||||
// Set a class on the Scene
|
||||
Foo1* foo1a = new Foo1();
|
||||
EXPECT_TRUE(scene->SetSubsystem(foo1a));
|
||||
|
||||
// Get that class back from the Scene
|
||||
EXPECT_EQ(foo1a, scene->GetSubsystem<Foo1>());
|
||||
EXPECT_EQ(foo1a, *scene->FindSubsystem<Foo1*>());
|
||||
|
||||
// Try to set the same class type twice, this should fail.
|
||||
Foo1* foo1b = new Foo1();
|
||||
EXPECT_FALSE(scene->SetSubsystem(foo1b));
|
||||
delete foo1b;
|
||||
|
||||
// Add a child scene
|
||||
createSceneOutcome = m_sceneSystem->CreateSceneWithParent("ChildScene", scene);
|
||||
EXPECT_TRUE(createSceneOutcome.IsSuccess());
|
||||
AZStd::shared_ptr<Scene> childScene = createSceneOutcome.TakeValue();
|
||||
|
||||
// Get class back from parent scene.
|
||||
EXPECT_EQ(foo1a, *childScene->FindSubsystem<Foo1*>());
|
||||
|
||||
// Find overloaded version of class on child scene.
|
||||
Foo1* foo1c = new Foo1();
|
||||
EXPECT_TRUE(childScene->SetSubsystem(foo1c));
|
||||
EXPECT_EQ(foo1c, *childScene->FindSubsystem<Foo1*>());
|
||||
|
||||
// Unset system on child scene, using alternative unset function.
|
||||
EXPECT_TRUE(childScene->UnsetSubsystem(foo1c));
|
||||
delete foo1c;
|
||||
|
||||
// Try to un-set a class that was never set, this should fail.
|
||||
EXPECT_FALSE(scene->UnsetSubsystem<Foo2>());
|
||||
|
||||
// Unset the class that was previously set
|
||||
EXPECT_TRUE(scene->UnsetSubsystem<Foo1>());
|
||||
delete foo1a;
|
||||
|
||||
// Make sure that the previsouly set class was really removed.
|
||||
EXPECT_EQ(nullptr, scene->GetSubsystem<Foo1>());
|
||||
// Make sure that the previously set class was really removed.
|
||||
EXPECT_EQ(nullptr, scene->FindSubsystem<Foo1*>());
|
||||
}
|
||||
} // UnitTest
|
||||
|
||||
|
||||
@@ -90,9 +90,6 @@ void ShaderPropertyEditor::onEditClicked()
|
||||
}
|
||||
void MaterialPropertyEditor::onEditClicked()
|
||||
{
|
||||
QString name = GetValue();
|
||||
IDataBaseItem *pItem = GetIEditor()->GetMaterialManager()->FindItemByName(name);
|
||||
GetIEditor()->OpenMaterialLibrary(pItem);
|
||||
}
|
||||
|
||||
void MaterialPropertyEditor::onButton2Clicked()
|
||||
|
||||
@@ -605,8 +605,6 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
|
||||
editMenu.AddSeparator();
|
||||
|
||||
// Lock Selection
|
||||
editMenu.AddAction(ID_EDIT_FREEZE);
|
||||
|
||||
// NEWMENUS: NEEDS IMPLEMENTATION
|
||||
//// Unlock Selection
|
||||
//auto unlockSelectionMenu = editMenu.Get()->addAction(tr("Unlock Selection"));
|
||||
@@ -614,11 +612,6 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
|
||||
//// Unlock Last Locked
|
||||
//auto unlockLastLockedMenu = editMenu.Get()->addAction(tr("Unlock Last Locked"));
|
||||
|
||||
// Unlock All
|
||||
editMenu.AddAction(ID_EDIT_UNFREEZEALL);
|
||||
|
||||
editMenu.AddSeparator();
|
||||
|
||||
// Editor Settings
|
||||
auto editorSettingsMenu = editMenu.AddMenu(tr("Editor Settings"));
|
||||
|
||||
|
||||
+21
-235
@@ -389,14 +389,9 @@ void CCryEditApp::RegisterActionHandlers()
|
||||
ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
|
||||
ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject)
|
||||
ON_COMMAND(ID_RENAME_OBJ, OnRenameObj)
|
||||
ON_COMMAND(ID_SET_HEIGHT, OnSetHeight)
|
||||
ON_COMMAND(ID_EDITMODE_MOVE, OnEditmodeMove)
|
||||
ON_COMMAND(ID_EDITMODE_ROTATE, OnEditmodeRotate)
|
||||
ON_COMMAND(ID_EDITMODE_SCALE, OnEditmodeScale)
|
||||
ON_COMMAND(ID_OBJECTMODIFY_SETAREA, OnObjectSetArea)
|
||||
ON_COMMAND(ID_OBJECTMODIFY_SETHEIGHT, OnObjectSetHeight)
|
||||
ON_COMMAND(ID_OBJECTMODIFY_FREEZE, OnObjectmodifyFreeze)
|
||||
ON_COMMAND(ID_OBJECTMODIFY_UNFREEZE, OnObjectmodifyUnfreeze)
|
||||
ON_COMMAND(ID_UNDO, OnUndo)
|
||||
ON_COMMAND(ID_TOOLBAR_WIDGET_REDO, OnUndo) // Can't use the same ID, because for the menu we can't have a QWidgetAction, while for the toolbar we want one
|
||||
ON_COMMAND(ID_IMPORT_ASSET, OnOpenAssetImporter)
|
||||
@@ -424,8 +419,6 @@ void CCryEditApp::RegisterActionHandlers()
|
||||
ON_COMMAND(ID_EDIT_HIDE, OnEditHide)
|
||||
ON_COMMAND(ID_EDIT_SHOW_LAST_HIDDEN, OnEditShowLastHidden)
|
||||
ON_COMMAND(ID_EDIT_UNHIDEALL, OnEditUnhideall)
|
||||
ON_COMMAND(ID_EDIT_FREEZE, OnEditFreeze)
|
||||
ON_COMMAND(ID_EDIT_UNFREEZEALL, OnEditUnfreezeall)
|
||||
|
||||
ON_COMMAND(ID_SNAP_TO_GRID, OnSnap)
|
||||
|
||||
@@ -477,7 +470,6 @@ void CCryEditApp::RegisterActionHandlers()
|
||||
ON_COMMAND(ID_ROTATESELECTION_YAXIS, OnRotateselectionYaxis)
|
||||
ON_COMMAND(ID_ROTATESELECTION_ZAXIS, OnRotateselectionZaxis)
|
||||
ON_COMMAND(ID_ROTATESELECTION_ROTATEANGLE, OnRotateselectionRotateangle)
|
||||
ON_COMMAND(ID_MODIFY_OBJECT_HEIGHT, OnObjectSetHeight)
|
||||
ON_COMMAND(ID_EDIT_RENAMEOBJECT, OnEditRenameobject)
|
||||
ON_COMMAND(ID_CHANGEMOVESPEED_INCREASE, OnChangemovespeedIncrease)
|
||||
ON_COMMAND(ID_CHANGEMOVESPEED_DECREASE, OnChangemovespeedDecrease)
|
||||
@@ -500,7 +492,6 @@ void CCryEditApp::RegisterActionHandlers()
|
||||
ON_COMMAND(ID_OPEN_ASSET_BROWSER, OnOpenAssetBrowserView)
|
||||
ON_COMMAND(ID_OPEN_AUDIO_CONTROLS_BROWSER, OnOpenAudioControlsEditor)
|
||||
|
||||
ON_COMMAND(ID_OPEN_MATERIAL_EDITOR, OnOpenMaterialEditor)
|
||||
ON_COMMAND(ID_GOTO_VIEWPORTSEARCH, OnGotoViewportSearch)
|
||||
ON_COMMAND(ID_DISPLAY_SHOWHELPERS, OnShowHelpers)
|
||||
ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
|
||||
@@ -2734,10 +2725,6 @@ void CCryEditApp::OnRenameObj()
|
||||
{
|
||||
}
|
||||
|
||||
void CCryEditApp::OnSetHeight()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnEditmodeMove()
|
||||
{
|
||||
@@ -2807,167 +2794,6 @@ void CCryEditApp::OnUpdateEditmodeScale(QAction* action)
|
||||
action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Scale);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnObjectSetArea()
|
||||
{
|
||||
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
|
||||
if (!pSelection->IsEmpty())
|
||||
{
|
||||
bool ok = false;
|
||||
int fractionalDigitCount = 2;
|
||||
float area = aznumeric_caster(QInputDialog::getDouble(AzToolsFramework::GetActiveWindow(), QObject::tr("Insert Value"), QStringLiteral(""), 0, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max(), fractionalDigitCount, &ok));
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetIEditor()->BeginUndo();
|
||||
for (int i = 0; i < pSelection->GetCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = pSelection->GetObject(i);
|
||||
obj->SetArea(area);
|
||||
}
|
||||
GetIEditor()->AcceptUndo("Set Area");
|
||||
GetIEditor()->SetModifiedFlag();
|
||||
GetIEditor()->SetModifiedModule(eModifiedBrushes);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), QString(), QObject::tr("No objects selected"));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnObjectSetHeight()
|
||||
{
|
||||
AzFramework::EntityContextId editorContextId;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
||||
editorContextId, &AzToolsFramework::EditorEntityContextRequests::GetEditorEntityContextId);
|
||||
|
||||
CSelectionGroup* sel = GetIEditor()->GetObjectManager()->GetSelection();
|
||||
|
||||
if (!sel->IsEmpty())
|
||||
{
|
||||
// Retrieve the Z origin from where height is messured from
|
||||
auto getZOrigin = [&](const Vec3& pos, [[maybe_unused]] AZ::EntityId entityId)
|
||||
{
|
||||
float z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
|
||||
if (z != pos.z)
|
||||
{
|
||||
float zdown = FLT_MAX;
|
||||
float zup = FLT_MAX;
|
||||
AzFramework::RenderGeometry::RayRequest ray;
|
||||
ray.m_startWorldPosition = LYVec3ToAZVec3(pos);
|
||||
ray.m_onlyVisible = true;
|
||||
if (entityId.IsValid()) // Don't check height against self
|
||||
{
|
||||
ray.m_entityFilter.m_ignoreEntities.insert(entityId);
|
||||
}
|
||||
// Down
|
||||
ray.m_endWorldPosition = LYVec3ToAZVec3(pos - Vec3(0, 0, 4000));
|
||||
{
|
||||
AzFramework::RenderGeometry::RayResult result;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(result, editorContextId,
|
||||
&AzFramework::RenderGeometry::IntersectorInterface::RayIntersect, ray);
|
||||
if (result)
|
||||
{
|
||||
zdown = result.m_worldPosition.GetZ();
|
||||
}
|
||||
}
|
||||
// Up
|
||||
ray.m_endWorldPosition = LYVec3ToAZVec3(pos + Vec3(0, 0, 4000));
|
||||
{
|
||||
AzFramework::RenderGeometry::RayResult result;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(result, editorContextId,
|
||||
&AzFramework::RenderGeometry::IntersectorInterface::RayIntersect, ray);
|
||||
if (result)
|
||||
{
|
||||
zup = result.m_worldPosition.GetZ();
|
||||
}
|
||||
}
|
||||
if (zdown != FLT_MAX && zup != FLT_MAX)
|
||||
{
|
||||
if (fabs(zup - z) < fabs(zdown - z))
|
||||
{
|
||||
z = zup;
|
||||
}
|
||||
else
|
||||
{
|
||||
z = zdown;
|
||||
}
|
||||
}
|
||||
else if (zup != FLT_MAX)
|
||||
{
|
||||
z = zup;
|
||||
}
|
||||
else if (zdown != FLT_MAX)
|
||||
{
|
||||
z = zdown;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
};
|
||||
|
||||
|
||||
float height = 0;
|
||||
if (sel->GetCount() == 1)
|
||||
{
|
||||
CBaseObject* obj = sel->GetObject(0);
|
||||
Vec3 pos = obj->GetWorldPos();
|
||||
AZ::EntityId entityId;
|
||||
if (obj->GetType() == OBJTYPE_AZENTITY)
|
||||
{
|
||||
entityId = static_cast<CComponentEntityObject*>(obj)->GetAssociatedEntityId();
|
||||
}
|
||||
height = pos.z - getZOrigin(pos, entityId);
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
int fractionalDigitCount = 2;
|
||||
height = aznumeric_caster(QInputDialog::getDouble(AzToolsFramework::GetActiveWindow(), QObject::tr("Enter Height"), QStringLiteral(""), height, -10000, 10000, fractionalDigitCount, &ok));
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CUndo undo("Set Height");
|
||||
for (int i = 0; i < sel->GetCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = sel->GetObject(i);
|
||||
Matrix34 wtm = obj->GetWorldTM();
|
||||
Vec3 pos = wtm.GetTranslation();
|
||||
AZ::EntityId entityId;
|
||||
if (obj->GetType() == OBJTYPE_AZENTITY)
|
||||
{
|
||||
entityId = static_cast<CComponentEntityObject*>(obj)->GetAssociatedEntityId();
|
||||
}
|
||||
float z = getZOrigin(pos, entityId);
|
||||
pos.z = z + height;
|
||||
wtm.SetTranslation(pos);
|
||||
obj->SetWorldTM(wtm, eObjectUpdateFlags_UserInput);
|
||||
}
|
||||
|
||||
GetIEditor()->SetModifiedFlag();
|
||||
GetIEditor()->SetModifiedModule(eModifiedBrushes);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), QString(), QObject::tr("No objects selected"));
|
||||
}
|
||||
}
|
||||
|
||||
void CCryEditApp::OnObjectmodifyFreeze()
|
||||
{
|
||||
// Freeze selection.
|
||||
OnEditFreeze();
|
||||
}
|
||||
|
||||
void CCryEditApp::OnObjectmodifyUnfreeze()
|
||||
{
|
||||
// Unfreeze all.
|
||||
OnEditUnfreezeall();
|
||||
}
|
||||
|
||||
void CCryEditApp::OnViewSwitchToGame()
|
||||
{
|
||||
if (IsInPreviewMode())
|
||||
@@ -3883,54 +3709,6 @@ void CCryEditApp::OnEditUnhideall()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnEditFreeze()
|
||||
{
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
// Freeze selection.
|
||||
CSelectionGroup* sel = GetIEditor()->GetSelection();
|
||||
if (!sel->IsEmpty())
|
||||
{
|
||||
AzToolsFramework::ScopedUndoBatch undo("Lock Selected Entities");
|
||||
|
||||
// We need to iterate over the list of selected objects in reverse order
|
||||
// because when the objects are locked, they are removed from the
|
||||
// selection so you would end up with the last selected object not
|
||||
// being locked
|
||||
int numSelected = sel->GetCount();
|
||||
for (int i = numSelected - 1; i >= 0; --i)
|
||||
{
|
||||
// Duplicated object names can exist in the case of prefab objects so passing a name as a script parameter and processing it couldn't be exact.
|
||||
sel->GetObject(i)->SetFrozen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnUpdateEditFreeze(QAction* action)
|
||||
{
|
||||
OnUpdateEditHide(action);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnEditUnfreezeall()
|
||||
{
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
if (QMessageBox::question(
|
||||
AzToolsFramework::GetActiveWindow(), QObject::tr("Unlock All"),
|
||||
QObject::tr("Are you sure you want to unlock all the objects?"),
|
||||
QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes)
|
||||
{
|
||||
// Unfreeze all.
|
||||
AzToolsFramework::ScopedUndoBatch undo("Unlock all Entities");
|
||||
GetIEditor()->GetObjectManager()->UnfreezeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnSnap()
|
||||
{
|
||||
@@ -4618,12 +4396,6 @@ void CCryEditApp::OnMaterialGetmaterial()
|
||||
GetIEditor()->GetMaterialManager()->Command_SelectFromObject();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnOpenMaterialEditor()
|
||||
{
|
||||
QtViewPaneManager::instance()->OpenPane(LyViewPane::MaterialEditor);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnOpenAssetBrowserView()
|
||||
{
|
||||
@@ -5045,12 +4817,28 @@ extern "C"
|
||||
#pragma comment(lib, "Shell32.lib")
|
||||
#endif
|
||||
|
||||
struct CryAllocatorsRAII
|
||||
{
|
||||
CryAllocatorsRAII()
|
||||
{
|
||||
AZ_Assert(!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
|
||||
AZ_Assert(!AZ::AllocatorInstance<CryStringAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
|
||||
|
||||
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
|
||||
AZ::AllocatorInstance<CryStringAllocator>::Create();
|
||||
}
|
||||
|
||||
~CryAllocatorsRAII()
|
||||
{
|
||||
AZ::AllocatorInstance<CryStringAllocator>::Destroy();
|
||||
AZ::AllocatorInstance<AZ::LegacyAllocator>::Destroy();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
|
||||
{
|
||||
AZ_Assert(!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
|
||||
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
|
||||
AZ_Assert(!AZ::AllocatorInstance<CryStringAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
|
||||
AZ::AllocatorInstance<CryStringAllocator>::Create();
|
||||
CryAllocatorsRAII cryAllocatorsRAII;
|
||||
|
||||
// ensure the EditorEventsBus context gets created inside EditorLib
|
||||
[[maybe_unused]] const auto& editorEventsContext = AzToolsFramework::EditorEvents::Bus::GetOrCreateContext();
|
||||
@@ -5058,7 +4846,7 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
|
||||
// connect relevant buses to global settings
|
||||
gSettings.Connect();
|
||||
|
||||
CCryEditApp* theApp = new CCryEditApp();
|
||||
auto theApp = AZStd::make_unique<CCryEditApp>();
|
||||
// this does some magic to set the current directory...
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
@@ -5145,8 +4933,6 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
|
||||
|
||||
}
|
||||
|
||||
delete theApp;
|
||||
|
||||
gSettings.Disconnect();
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -220,17 +220,12 @@ public:
|
||||
void DeleteSelectedEntities(bool includeDescendants);
|
||||
void OnMoveObject();
|
||||
void OnRenameObj();
|
||||
void OnSetHeight();
|
||||
void OnEditmodeMove();
|
||||
void OnEditmodeRotate();
|
||||
void OnEditmodeScale();
|
||||
void OnObjectSetArea();
|
||||
void OnObjectSetHeight();
|
||||
void OnUpdateEditmodeMove(QAction* action);
|
||||
void OnUpdateEditmodeRotate(QAction* action);
|
||||
void OnUpdateEditmodeScale(QAction* action);
|
||||
void OnObjectmodifyFreeze();
|
||||
void OnObjectmodifyUnfreeze();
|
||||
void OnUndo();
|
||||
void OnOpenAssetImporter();
|
||||
void OnUpdateSelected(QAction* action);
|
||||
@@ -388,9 +383,6 @@ private:
|
||||
void OnUpdateEditHide(QAction* action);
|
||||
void OnEditShowLastHidden();
|
||||
void OnEditUnhideall();
|
||||
void OnEditFreeze();
|
||||
void OnUpdateEditFreeze(QAction* action);
|
||||
void OnEditUnfreezeall();
|
||||
void OnSnap();
|
||||
void OnWireframe();
|
||||
void OnUpdateWireframe(QAction* action);
|
||||
@@ -459,7 +451,6 @@ private:
|
||||
void OnUpdateSwitchToSelectedCamera(QAction* action);
|
||||
void OnSwitchcameraNext();
|
||||
void OnOpenProceduralMaterialEditor();
|
||||
void OnOpenMaterialEditor();
|
||||
void OnOpenAssetBrowserView();
|
||||
void OnOpenTrackView();
|
||||
void OnOpenAudioControlsEditor();
|
||||
|
||||
@@ -2814,14 +2814,16 @@ void EditorViewportWidget::RestoreViewportAfterGameMode()
|
||||
|
||||
void EditorViewportWidget::UpdateScene()
|
||||
{
|
||||
AZStd::vector<AzFramework::Scene*> scenes;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scenes, &AzFramework::SceneSystemRequests::GetAllScenes);
|
||||
if (scenes.size() > 0)
|
||||
auto sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
if (sceneSystem)
|
||||
{
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusDisconnect();
|
||||
auto scene = scenes[0];
|
||||
m_renderViewport->SetScene(scene);
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusConnect(m_renderViewport->GetViewportContext()->GetRenderScene()->GetId());
|
||||
AZStd::shared_ptr<AzFramework::Scene> mainScene = sceneSystem->GetScene(AzFramework::Scene::MainSceneName);
|
||||
if (mainScene)
|
||||
{
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusDisconnect();
|
||||
m_renderViewport->SetScene(mainScene);
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusConnect(m_renderViewport->GetViewportContext()->GetRenderScene()->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzFramework/Input/Buses/Requests/InputSystemCursorRequestBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
|
||||
@@ -519,11 +519,6 @@ void CErrorReportDialog::OnReportItemDblClick(const QModelIndex& index)
|
||||
}
|
||||
bDone = true;
|
||||
}
|
||||
if (pError && pError->pItem != NULL)
|
||||
{
|
||||
GetIEditor()->OpenMaterialLibrary(pError->pItem);
|
||||
bDone = true;
|
||||
}
|
||||
|
||||
if (!bDone && pError && GetIEditor()->GetActiveView())
|
||||
{
|
||||
@@ -581,11 +576,6 @@ void CErrorReportDialog::OnReportHyperlink(const QModelIndex& index)
|
||||
GetIEditor()->SelectObject(pError->pObject);
|
||||
bDone = true;
|
||||
}
|
||||
if (pError && pError->pItem != NULL)
|
||||
{
|
||||
GetIEditor()->OpenMaterialLibrary(pError->pItem);
|
||||
bDone = true;
|
||||
}
|
||||
|
||||
if (!bDone && pError && GetIEditor()->GetActiveView())
|
||||
{
|
||||
|
||||
@@ -632,9 +632,6 @@ struct IEditor
|
||||
virtual RefCoordSys GetReferenceCoordSys() = 0;
|
||||
virtual XmlNodeRef FindTemplate(const QString& templateName) = 0;
|
||||
virtual void AddTemplate(const QString& templateName, XmlNodeRef& tmpl) = 0;
|
||||
//! Open material library and select specified item.
|
||||
//! If parameter is NULL current selection in material library does not change.
|
||||
virtual void OpenMaterialLibrary(IDataBaseItem* pItem = NULL) = 0;
|
||||
|
||||
virtual const QtViewPane* OpenView(QString sViewClassName, bool reuseOpen = true) = 0;
|
||||
virtual QWidget* FindView(QString viewClassName) = 0;
|
||||
|
||||
@@ -1013,29 +1013,6 @@ IDataBaseManager* CEditorImpl::GetDBItemManager(EDataBaseItemType itemType)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEditorImpl::OpenMaterialLibrary(IDataBaseItem* item)
|
||||
{
|
||||
EDataBaseItemType type = item ? item->GetType() : EDB_TYPE_MATERIAL;
|
||||
AZ_Assert(type == EDB_TYPE_MATERIAL, "Call to OpenMaterialLibrary with non-material data base item");
|
||||
|
||||
if (type == EDB_TYPE_MATERIAL)
|
||||
{
|
||||
QtViewPaneManager::instance()->OpenPane(LyViewPane::MaterialEditor);
|
||||
|
||||
// This is a workaround for a timing issue where the material editor
|
||||
// gets in a bad state while it is being polished for the first time
|
||||
// while loading a material at the same time, so delay the setting
|
||||
// of the material until the next event queue check
|
||||
QTimer::singleShot(0, [this, item] {
|
||||
IDataBaseManager* pManager = GetDBItemManager(EDB_TYPE_MATERIAL);
|
||||
if (pManager)
|
||||
{
|
||||
pManager->SetSelectedItem(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool CEditorImpl::SelectColor(QColor& color, QWidget* parent)
|
||||
{
|
||||
const AZ::Color c = AzQtComponents::fromQColor(color);
|
||||
|
||||
@@ -237,7 +237,6 @@ public:
|
||||
RefCoordSys GetReferenceCoordSys();
|
||||
XmlNodeRef FindTemplate(const QString& templateName);
|
||||
void AddTemplate(const QString& templateName, XmlNodeRef& tmpl);
|
||||
void OpenMaterialLibrary(IDataBaseItem* pItem = NULL);
|
||||
|
||||
const QtViewPane* OpenView(QString sViewClassName, bool reuseOpened = true) override;
|
||||
|
||||
|
||||
@@ -135,7 +135,6 @@ public:
|
||||
MOCK_METHOD0(GetReferenceCoordSys, RefCoordSys());
|
||||
MOCK_METHOD1(FindTemplate, XmlNodeRef(const QString& ));
|
||||
MOCK_METHOD2(AddTemplate, void(const QString& , XmlNodeRef& ));
|
||||
MOCK_METHOD1(OpenMaterialLibrary, void (IDataBaseItem*));
|
||||
MOCK_METHOD2(OpenView, const QtViewPane* (QString , bool ));
|
||||
MOCK_METHOD1(FindView, QWidget* (QString ));
|
||||
MOCK_METHOD1(CloseView, bool(const char* ));
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace LyViewPane
|
||||
static const char* const TerrainEditor = "Terrain Editor";
|
||||
static const char* const TerrainTool = "Terrain Tool";
|
||||
static const char* const TerrainTextureLayers = "Terrain Texture Layers";
|
||||
static const char* const MaterialEditor = "Material Editor";
|
||||
static const char* const ParticleEditor = "Particle Editor";
|
||||
static const char* const LensFlareEditor = "Lens Flare Editor";
|
||||
static const char* const TimeOfDayEditor = "Time Of Day";
|
||||
|
||||
@@ -435,13 +435,6 @@ MainWindow::MainWindow(QWidget* parent)
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (auto aed = QAbstractEventDispatcher::instance())
|
||||
{
|
||||
aed->installNativeEventFilter(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
// special handling for escape key (outside ActionManager)
|
||||
auto* escapeAction = new QAction(this);
|
||||
escapeAction->setShortcut(QKeySequence(Qt::Key_Escape));
|
||||
@@ -508,13 +501,6 @@ void MainWindow::SetActiveView(CLayoutViewPane* v)
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
if (auto aed = QAbstractEventDispatcher::instance())
|
||||
{
|
||||
aed->removeNativeEventFilter(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
AzToolsFramework::SourceControlNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
delete m_toolbarManager;
|
||||
@@ -938,22 +924,6 @@ void MainWindow::InitActions()
|
||||
am->AddAction(ID_MODIFY_UNLINK, tr("Un-Parent"));
|
||||
}
|
||||
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
// implemented by EditorTransformComponentSelection when the new Viewport Interaction Model is enabled
|
||||
am->AddAction(ID_EDIT_FREEZE, tr("Lock selection"))
|
||||
.SetShortcut(tr("L"))
|
||||
.SetToolTip(tr("Lock selection (L)"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateEditFreeze)
|
||||
.SetIcon(Style::icon("Locked"))
|
||||
.SetApplyHoverEffect();
|
||||
am->AddAction(ID_EDIT_UNFREEZEALL, tr("Unlock all"))
|
||||
.SetShortcut(tr("Ctrl+L"))
|
||||
.SetToolTip(tr("Unlock All (Ctrl+L)"))
|
||||
.SetIcon(Style::icon("Unlocked"))
|
||||
.SetApplyHoverEffect();
|
||||
}
|
||||
|
||||
am->AddAction(ID_EDIT_HOLD, tr("&Hold"))
|
||||
.SetShortcut(tr("Ctrl+Alt+H"))
|
||||
.SetToolTip(tr("&Hold (Ctrl+Alt+H)"))
|
||||
@@ -987,7 +957,6 @@ void MainWindow::InitActions()
|
||||
}
|
||||
|
||||
// Modify actions
|
||||
am->AddAction(ID_MODIFY_OBJECT_HEIGHT, tr("Set Object(s) Height..."));
|
||||
am->AddAction(ID_EDIT_RENAMEOBJECT, tr("Rename Object(s)..."))
|
||||
.SetStatusTip(tr("Rename Object"));
|
||||
|
||||
@@ -1202,10 +1171,6 @@ void MainWindow::InitActions()
|
||||
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
am->AddAction(ID_GENERATORS_LIGHTING, tr("&Sun Trajectory Tool"))
|
||||
.SetIcon(Style::icon("Lighting"))
|
||||
.SetApplyHoverEffect()
|
||||
.SetStatusTip(tr("Bring up the terrain lighting dialog"));
|
||||
am->AddAction(ID_TERRAIN_TIMEOFDAY, tr("Time Of Day"))
|
||||
.SetStatusTip(tr("Open Time of Day Editor"));
|
||||
}
|
||||
@@ -1300,14 +1265,6 @@ void MainWindow::InitActions()
|
||||
.SetToolTip(tr("Open Asset Browser"))
|
||||
.SetApplyHoverEffect();
|
||||
|
||||
if (!AZ::Interface<AzFramework::AtomActiveInterface>::Get())
|
||||
{
|
||||
am->AddAction(ID_OPEN_MATERIAL_EDITOR, tr(LyViewPane::MaterialEditor))
|
||||
.SetToolTip(tr("Open Material Editor"))
|
||||
.SetIcon(Style::icon("Material"))
|
||||
.SetApplyHoverEffect();
|
||||
}
|
||||
|
||||
AZ::EBusReduceResult<bool, AZStd::logical_or<bool>> emfxEnabled(false);
|
||||
using AnimationRequestBus = AzToolsFramework::EditorAnimationSystemRequestsBus;
|
||||
using AnimationSystemType = AzToolsFramework::EditorAnimationSystemRequests::AnimationSystem;
|
||||
@@ -1360,14 +1317,6 @@ void MainWindow::InitActions()
|
||||
.SetApplyHoverEffect()
|
||||
.Connect(&QAction::triggered, this, &MainWindow::OnGotoSelected);
|
||||
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
am->AddAction(ID_OBJECTMODIFY_SETHEIGHT, tr("Set object(s) height"))
|
||||
.SetIcon(QIcon(":/MainWindow/toolbars/object_toolbar-03.svg"))
|
||||
.SetApplyHoverEffect()
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSelected);
|
||||
}
|
||||
|
||||
// Misc Toolbar Actions
|
||||
am->AddAction(ID_OPEN_SUBSTANCE_EDITOR, tr("Open Substance Editor"))
|
||||
.SetApplyHoverEffect();
|
||||
@@ -2215,35 +2164,6 @@ void MainWindow::RegisterOpenWndCommands()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::MatEditSend(int param)
|
||||
{
|
||||
if (param == eMSM_Init || GetIEditor()->IsInMatEditMode())
|
||||
{
|
||||
// In MatEditMode this message is handled by CMatEditMainDlg, which doesn't have
|
||||
// any view panes and opens MaterialDialog directly.
|
||||
return;
|
||||
}
|
||||
|
||||
if (QtViewPaneManager::instance()->OpenPane(LyViewPane::MaterialEditor))
|
||||
{
|
||||
GetIEditor()->GetMaterialManager()->SyncMaterialEditor();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
bool MainWindow::nativeEventFilter([[maybe_unused]] const QByteArray &eventType, void *message, long *)
|
||||
{
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (msg->message == WM_MATEDITSEND) // For supporting 3ds Max Exporter, Windows Only
|
||||
{
|
||||
MatEditSend(msg->wParam);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MainWindow::event(QEvent* event)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
#include <QPointer>
|
||||
#include <QToolButton>
|
||||
#include <QTimer>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
#include "Include/SandboxAPI.h"
|
||||
#include <AzQtComponents/Components/ToolButtonComboBox.h>
|
||||
#include <AzQtComponents/Components/Widgets/ToolBar.h>
|
||||
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
#include "IEditor.h"
|
||||
#endif
|
||||
@@ -93,9 +91,6 @@ class SANDBOX_API MainWindow
|
||||
: public QMainWindow
|
||||
, public IEditorNotifyListener
|
||||
, private AzToolsFramework::SourceControlNotificationBus::Handler
|
||||
#ifdef Q_OS_WIN
|
||||
, public QAbstractNativeEventFilter
|
||||
#endif
|
||||
{
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
@@ -160,13 +155,9 @@ public:
|
||||
void UpdateToolsMenu();
|
||||
|
||||
int ViewPaneVersion() const;
|
||||
void MatEditSend(int param);
|
||||
|
||||
LevelEditorMenuHandler* GetLevelEditorMenuHandler() { return m_levelEditorMenuHandler; }
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override;
|
||||
#endif
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
void OnGotoSliceRoot();
|
||||
|
||||
@@ -1668,25 +1668,13 @@ void CMaterialManager::InitMatSender()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMaterialManager::GotoMaterial(CMaterial* pMaterial)
|
||||
void CMaterialManager::GotoMaterial([[maybe_unused]] CMaterial* pMaterial)
|
||||
{
|
||||
if (pMaterial)
|
||||
{
|
||||
GetIEditor()->OpenMaterialLibrary(pMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMaterialManager::GotoMaterial(_smart_ptr<IMaterial> pMtl)
|
||||
void CMaterialManager::GotoMaterial([[maybe_unused]] _smart_ptr<IMaterial> pMtl)
|
||||
{
|
||||
if (pMtl)
|
||||
{
|
||||
CMaterial* pEdMaterial = FromIMaterial(pMtl);
|
||||
if (pEdMaterial)
|
||||
{
|
||||
GetIEditor()->OpenMaterialLibrary(pEdMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -75,13 +75,10 @@
|
||||
#define IDC_PLATFORM_SALEM 2759
|
||||
#define IDC_GROUPBOX_GLOBALTAGS 2916
|
||||
#define IDC_GROUPBOX_FRAGMENTTAGS 2917
|
||||
#define ID_PARTICLE_EDITOR 2922
|
||||
#define ID_RESOURCES_GENERATECGFTHUMBNAILS 32894
|
||||
#define ID_RESOURCES_REDUCEWORKINGSET 32896
|
||||
#define ID_EDIT_HIDE 32898
|
||||
#define ID_EDIT_UNHIDEALL 32899
|
||||
#define ID_EDIT_FREEZE 32900
|
||||
#define ID_EDIT_UNFREEZEALL 32901
|
||||
#define ID_RELOAD_TERRAIN 32902
|
||||
#define ID_VIEW_GRIDSETTINGS 32904
|
||||
#define ID_VIEW_CONFIGURELAYOUT 32906
|
||||
@@ -125,7 +122,6 @@
|
||||
#define ID_EDIT_SELECTNONE 33377
|
||||
#define ID_WIREFRAME 33410
|
||||
#define ID_FILE_GENERATETERRAINTEXTURE 33445
|
||||
#define ID_GENERATORS_LIGHTING 33446
|
||||
#define ID_GENERATORS_STATICOBJECTS 33447
|
||||
#define ID_GENERATORS_TEXTURE 33448
|
||||
#define ID_FILE_IMPORT 33457
|
||||
@@ -136,17 +132,12 @@
|
||||
#define ID_EDIT_DELETE 33480
|
||||
#define ID_MOVE_OBJECT 33481
|
||||
#define ID_RENAME_OBJ 33483
|
||||
#define ID_SET_HEIGHT 33484
|
||||
#define ID_FETCH 33496
|
||||
#define ID_EDITMODE_ROTATE 33506
|
||||
#define ID_EDITMODE_SCALE 33507
|
||||
#define ID_EDITMODE_MOVE 33508
|
||||
#define ID_SELECTION_DELETE 33512
|
||||
#define ID_EDIT_ESCAPE 33513
|
||||
#define ID_OBJECTMODIFY_SETAREA 33514
|
||||
#define ID_OBJECTMODIFY_SETHEIGHT 33515
|
||||
#define ID_OBJECTMODIFY_FREEZE 33517
|
||||
#define ID_OBJECTMODIFY_UNFREEZE 33518
|
||||
#define ID_UNDO 33524
|
||||
#define ID_EDIT_CLONE 33525
|
||||
#define ID_GOTO_SELECTED 33535
|
||||
@@ -230,7 +221,6 @@
|
||||
#define ID_VIEW_OPENVIEWPANE 33709
|
||||
#define ID_VIEW_OPENPANE_FIRST 33712
|
||||
#define ID_VIEW_OPENPANE_LAST 33811
|
||||
#define ID_OPEN_MATERIAL_EDITOR 33822
|
||||
#define ID_OPEN_EMOTIONFX_EDITOR 39742
|
||||
#define ID_BRUSH_CSGSUBSTRUCT 33837
|
||||
#define ID_MATERIAL_PICKTOOL 33842
|
||||
@@ -320,7 +310,6 @@
|
||||
#define ID_SNAP_TO_ANGLE_RANGE_END 34330
|
||||
#define ID_MODIFY_LINK 34355
|
||||
#define ID_MODIFY_UNLINK 34356
|
||||
#define ID_MODIFY_OBJECT_HEIGHT 34357
|
||||
#define ID_MODIFY_GOTO_SELECTION 34358
|
||||
#define ID_VIEW_LAYOUT_FIRST 34363
|
||||
#define ID_VIEW_LAYOUT_LAST 34377
|
||||
|
||||
@@ -609,14 +609,6 @@ AmazonToolbar ToolbarManager::GetObjectToolbar() const
|
||||
AmazonToolbar t = AmazonToolbar("Object", QObject::tr("Object Toolbar"));
|
||||
t.SetMainToolbar(true);
|
||||
t.AddAction(ID_GOTO_SELECTED, ORIGINAL_TOOLBAR_VERSION);
|
||||
t.AddAction(ID_OBJECTMODIFY_SETHEIGHT, ORIGINAL_TOOLBAR_VERSION);
|
||||
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION);
|
||||
t.AddAction(ID_EDIT_FREEZE, ORIGINAL_TOOLBAR_VERSION);
|
||||
t.AddAction(ID_EDIT_UNFREEZEALL, ORIGINAL_TOOLBAR_VERSION);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
@@ -636,19 +628,9 @@ AmazonToolbar ToolbarManager::GetPlayConsoleToolbar() const
|
||||
AmazonToolbar ToolbarManager::GetEditorsToolbar() const
|
||||
{
|
||||
AmazonToolbar t = AmazonToolbar("Editors", QObject::tr("Editors Toolbar"));
|
||||
if( !AZ::Interface<AzFramework::AtomActiveInterface>::Get() && !GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
t.AddAction(ID_OPEN_MATERIAL_EDITOR, ORIGINAL_TOOLBAR_VERSION);
|
||||
}
|
||||
|
||||
t.AddAction(ID_OPEN_AUDIO_CONTROLS_BROWSER, ORIGINAL_TOOLBAR_VERSION);
|
||||
|
||||
if (!AZ::Interface<AzFramework::AtomActiveInterface>::Get())
|
||||
{
|
||||
t.AddAction(ID_PARTICLE_EDITOR, ORIGINAL_TOOLBAR_VERSION);
|
||||
t.AddAction(ID_GENERATORS_LIGHTING, ORIGINAL_TOOLBAR_VERSION);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
|
||||
namespace TrackView
|
||||
{
|
||||
|
||||
@@ -30,17 +30,14 @@ int main(int argc, char* argv[])
|
||||
[[maybe_unused]] const bool loaded = handle->Load(true);
|
||||
AZ_Assert(loaded, "EditorLib could not be loaded");
|
||||
|
||||
int ret = 1;
|
||||
if (auto fn = handle->GetFunction<CryEditMain>(CryEditMainName); fn != nullptr)
|
||||
{
|
||||
const int ret = AZStd::invoke(fn, argc, argv);
|
||||
|
||||
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
|
||||
AZ::Environment::Detach();
|
||||
|
||||
return ret;
|
||||
ret = AZStd::invoke(fn, argc, argv);
|
||||
}
|
||||
|
||||
handle = {};
|
||||
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
|
||||
AZ::Environment::Detach();
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -713,7 +713,7 @@ namespace AssetUtilities
|
||||
}
|
||||
|
||||
// Update Settings Registry with new token
|
||||
AZStd::string azNewAllowedList{ newAllowedList.join(', ').toUtf8().constData() };
|
||||
AZStd::string azNewAllowedList{ newAllowedList.join(',').toUtf8().constData() };
|
||||
settingsRegistry->Set(allowedListKey, azNewAllowedList);
|
||||
|
||||
return AssetUtilsInternal::DumpAssetProcessorUserSettingsToFile(*settingsRegistry, assetProcessorUserSetregPath);
|
||||
|
||||
@@ -579,6 +579,8 @@ int rcmain(int argc, char** argv, [[maybe_unused]] char** envp)
|
||||
// on the command line
|
||||
AZ::CommandLine commandLine;
|
||||
commandLine.Parse(argc, argv);
|
||||
AZ::SettingsRegistryMergeUtils::ParseCommandLine(commandLine);
|
||||
|
||||
AZ::SettingsRegistryImpl settingsRegistry;
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
namespace AZ
|
||||
{
|
||||
@@ -43,15 +43,15 @@ namespace AZ
|
||||
EBusConnectionPolicy<Bus>::Connect(busPtr, context, handler, connectLock, id);
|
||||
|
||||
// Check if bootstrap scene already exists and fire notifications if it does
|
||||
AZStd::vector<AzFramework::Scene*> scenes;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scenes, &AzFramework::SceneSystemRequests::GetAllScenes);
|
||||
AZ_Assert(scenes.size() > 0, "AzFramework didn't set up any scenes.");
|
||||
auto sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
AZ_Assert(sceneSystem, "Notification bus called before the scene system has been initialized.");
|
||||
AZStd::shared_ptr<AzFramework::Scene> mainScene = sceneSystem->GetScene(AzFramework::Scene::MainSceneName);
|
||||
AZ_Assert(mainScene, "AzFramework didn't set up any scenes.");
|
||||
|
||||
// Assume first scene is the default scene
|
||||
AZ::RPI::Scene* defaultScene = scenes.at(0)->GetSubsystem<AZ::RPI::Scene>();
|
||||
if (defaultScene && defaultScene->GetDefaultRenderPipeline())
|
||||
AZ::RPI::ScenePtr* defaultScene = mainScene->FindSubsystem<AZ::RPI::ScenePtr>();
|
||||
if (defaultScene && *defaultScene && (*defaultScene)->GetDefaultRenderPipeline())
|
||||
{
|
||||
handler->OnBootstrapSceneReady(defaultScene);
|
||||
handler->OnBootstrapSceneReady(defaultScene->get());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
namespace AZ::Render::Bootstrap
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace AZ
|
||||
|
||||
// Register scene to RPI system so it will be processed/rendered per tick
|
||||
RPI::RPISystemInterface::Get()->RegisterScene(atomScene);
|
||||
scene->SetSubsystem(atomScene.get());
|
||||
scene->SetSubsystem(atomScene);
|
||||
|
||||
atomSceneHandle = atomScene;
|
||||
|
||||
@@ -279,11 +279,19 @@ namespace AZ
|
||||
void BootstrapSystemComponent::CreateDefaultScene()
|
||||
{
|
||||
// Bind atomScene to the GameEntityContext's AzFramework::Scene
|
||||
AZStd::vector<AzFramework::Scene*> scenes;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scenes, &AzFramework::SceneSystemRequests::GetAllScenes);
|
||||
AZ_Assert(scenes.size() > 0, "Error: Scenes missing during system component initialization"); // This should never happen unless scene creation has changed.
|
||||
m_defaultFrameworkScene = scenes[0];
|
||||
m_defaultScene = GetOrCreateAtomSceneFromAzScene(m_defaultFrameworkScene);
|
||||
m_defaultFrameworkScene = AzFramework::SceneSystemInterface::Get()->GetScene(AzFramework::Scene::MainSceneName);
|
||||
// This should never happen unless scene creation has changed.
|
||||
AZ_Assert(m_defaultFrameworkScene, "Error: Scenes missing during system component initialization");
|
||||
m_sceneRemovalHandler = AzFramework::Scene::RemovalEvent::Handler(
|
||||
[this](AzFramework::Scene&, AzFramework::Scene::RemovalEventType eventType)
|
||||
{
|
||||
if (eventType == AzFramework::Scene::RemovalEventType::Zombified)
|
||||
{
|
||||
m_defaultFrameworkScene.reset();
|
||||
}
|
||||
});
|
||||
m_defaultFrameworkScene->ConnectToEvents(m_sceneRemovalHandler);
|
||||
m_defaultScene = GetOrCreateAtomSceneFromAzScene(m_defaultFrameworkScene.get());
|
||||
}
|
||||
|
||||
bool BootstrapSystemComponent::EnsureDefaultRenderPipelineInstalledForScene(AZ::RPI::ScenePtr scene, AZ::RPI::ViewportContextPtr viewportContext)
|
||||
@@ -405,15 +413,6 @@ namespace AZ
|
||||
AzFramework::WindowNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void BootstrapSystemComponent::SceneAboutToBeRemoved(AzFramework::Scene& scene)
|
||||
{
|
||||
if (&scene == m_defaultFrameworkScene)
|
||||
{
|
||||
// Set to nullptr so we don't try to unbind the RPI::Scene from it later.
|
||||
m_defaultFrameworkScene = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AzFramework::NativeWindowHandle BootstrapSystemComponent::GetDefaultWindowHandle()
|
||||
{
|
||||
return m_windowHandle;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <AzFramework/Windowing/NativeWindow.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace AZ
|
||||
, public TickBus::Handler
|
||||
, public AzFramework::WindowNotificationBus::Handler
|
||||
, public AzFramework::AssetCatalogEventBus::Handler
|
||||
, private AzFramework::SceneSystemNotificationBus::Handler
|
||||
, public AzFramework::WindowSystemNotificationBus::Handler
|
||||
, public AzFramework::WindowSystemRequestBus::Handler
|
||||
, public Render::Bootstrap::DefaultWindowBus::Handler
|
||||
@@ -90,9 +89,6 @@ namespace AZ
|
||||
// AzFramework::AssetCatalogEventBus::Handler overrides ...
|
||||
void OnCatalogLoaded(const char* catalogFile) override;
|
||||
|
||||
// AzFramework::SceneSystemNotificationBus::Handler overrides ...
|
||||
void SceneAboutToBeRemoved(AzFramework::Scene& scene) override;
|
||||
|
||||
// AzFramework::WindowSystemNotificationBus::Handler overrides ...
|
||||
void OnWindowCreated(AzFramework::NativeWindowHandle windowHandle) override;
|
||||
|
||||
@@ -104,12 +100,14 @@ namespace AZ
|
||||
|
||||
void CreateWindowContext();
|
||||
|
||||
AzFramework::Scene::RemovalEvent::Handler m_sceneRemovalHandler;
|
||||
|
||||
AZStd::unique_ptr<AzFramework::NativeWindow> m_nativeWindow;
|
||||
AzFramework::NativeWindowHandle m_windowHandle = nullptr;
|
||||
RPI::ViewportContextPtr m_viewportContext;
|
||||
|
||||
RPI::ScenePtr m_defaultScene = nullptr;
|
||||
AzFramework::Scene* m_defaultFrameworkScene = nullptr;
|
||||
AZStd::shared_ptr<AzFramework::Scene> m_defaultFrameworkScene = nullptr;
|
||||
|
||||
float m_simulateTime = 0;
|
||||
float m_deltaTime = 0.016f;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"type": "Compute"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"DisabledRHIBackends": ["metal"]
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@
|
||||
"type": "Compute"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"DisabledRHIBackends": ["metal"]
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -731,11 +731,12 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove unnecessary camera views in shadow properties
|
||||
for (uint16_t lightIndex = 0; lightIndex < aznumeric_cast<uint16_t>(m_shadowProperties.GetDataCount()); ++lightIndex)
|
||||
auto& shadowPropertiesVector = m_shadowProperties.GetDataVector();
|
||||
for (ShadowProperty& shadowProperty : shadowPropertiesVector)
|
||||
{
|
||||
AZStd::unordered_map<const RPI::View*, AZStd::fixed_vector<CascadeSegment, Shadow::MaxNumberOfCascades>>& cascades = m_shadowProperties.GetData(lightIndex).m_segments;
|
||||
auto& cascades = shadowProperty.m_segments;
|
||||
for (auto it = cascades.begin(); it != cascades.end();)
|
||||
{
|
||||
if (AZStd::find(cameraViews.begin(), cameraViews.end(), it->first) != cameraViews.end())
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace AZ
|
||||
RHI::ImageInitRequest request;
|
||||
request.m_image = m_classificationImage[m_currentImageIndex].get();
|
||||
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
|
||||
RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
|
||||
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -294,7 +294,7 @@ namespace AZ
|
||||
|
||||
// probe classification
|
||||
{
|
||||
RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetClassificationImageAttachmentId(), diffuseProbeGrid->GetClassificationImage());
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetClassificationImageAttachmentId(), diffuseProbeGrid->GetClassificationImage());
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeClassificationImage");
|
||||
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzCore/Preprocessor/EnumReflectUtils.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
|
||||
#if defined(OPEN_IMAGE_IO_ENABLED)
|
||||
#include <OpenImageIO/imageio.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -38,6 +43,41 @@ namespace AZ
|
||||
{
|
||||
AZ_ENUM_DEFINE_REFLECT_UTILITIES(FrameCaptureResult);
|
||||
|
||||
#if defined(OPEN_IMAGE_IO_ENABLED)
|
||||
AZ_CVAR(unsigned int,
|
||||
r_pngCompressionLevel,
|
||||
3, // A compression level of 3 seems like the best default in terms of file size and saving speeds
|
||||
nullptr,
|
||||
ConsoleFunctorFlags::Null,
|
||||
"Sets the compression level for saving png screenshots. Valid values are from 0 to 8"
|
||||
);
|
||||
|
||||
FrameCaptureOutputResult PngFrameCaptureOutput(
|
||||
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
|
||||
{
|
||||
using namespace OIIO;
|
||||
AZStd::unique_ptr<ImageOutput> out = ImageOutput::create(outputFilePath.c_str());
|
||||
if (out)
|
||||
{
|
||||
ImageSpec spec(
|
||||
readbackResult.m_imageDescriptor.m_size.m_width,
|
||||
readbackResult.m_imageDescriptor.m_size.m_height,
|
||||
AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format)
|
||||
);
|
||||
spec.attribute("png:compressionLevel", r_pngCompressionLevel);
|
||||
|
||||
if (out->open(outputFilePath.c_str(), spec))
|
||||
{
|
||||
out->write_image(TypeDesc::UINT8, readbackResult.m_dataBuffer->data());
|
||||
out->close();
|
||||
return FrameCaptureOutputResult{FrameCaptureResult::Success, AZStd::nullopt};
|
||||
}
|
||||
}
|
||||
|
||||
return FrameCaptureOutputResult{FrameCaptureResult::InternalError, "Unable to save frame capture output to " + outputFilePath};
|
||||
}
|
||||
#endif
|
||||
|
||||
FrameCaptureOutputResult DdsFrameCaptureOutput(
|
||||
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
|
||||
{
|
||||
@@ -377,7 +417,6 @@ namespace AZ
|
||||
if (readbackResult.m_attachmentType == AZ::RHI::AttachmentType::Buffer)
|
||||
{
|
||||
// write buffer data to the data file
|
||||
|
||||
AZ::IO::FileIOStream fileStream(m_outputFilePath.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeCreatePath);
|
||||
if (fileStream.IsOpen())
|
||||
{
|
||||
@@ -418,6 +457,18 @@ namespace AZ
|
||||
m_result = ddsFrameCapture.m_result;
|
||||
m_latestCaptureInfo = ddsFrameCapture.m_errorMessage.value_or("");
|
||||
}
|
||||
#if defined(OPEN_IMAGE_IO_ENABLED)
|
||||
else if (extension == "png")
|
||||
{
|
||||
AZStd::string folderPath;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(m_outputFilePath.c_str(), folderPath);
|
||||
AZ::IO::SystemFile::CreateDir(folderPath.c_str());
|
||||
|
||||
const auto frameCaptureResult = PngFrameCaptureOutput(m_outputFilePath, readbackResult);
|
||||
m_result = frameCaptureResult.m_result;
|
||||
m_latestCaptureInfo = frameCaptureResult.m_errorMessage.value_or("");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
m_latestCaptureInfo = AZStd::string::format("Only supports saving image to ppm or dds files");
|
||||
|
||||
@@ -9,3 +9,14 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(LY_BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::OpenImageIO
|
||||
3rdParty::ilmbase
|
||||
)
|
||||
|
||||
# [GFX-TODO] Add macro defintion in OpenImageIO 3rd party find cmake file
|
||||
set(LY_COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
OPEN_IMAGE_IO_ENABLED
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <AzCore/Script/ScriptTimePoint.h>
|
||||
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
#include <AzCore/Jobs/JobEmpty.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
@@ -71,12 +73,15 @@ namespace AZ
|
||||
Scene* Scene::GetSceneForEntityContextId(AzFramework::EntityContextId entityContextId)
|
||||
{
|
||||
// Find the scene for this entity context.
|
||||
AzFramework::Scene* scene = nullptr;
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, entityContextId);
|
||||
AZStd::shared_ptr<AzFramework::Scene> scene = AzFramework::EntityContext::FindContainingScene(entityContextId);
|
||||
if (scene)
|
||||
{
|
||||
// Get the RPI::Scene subsystem from the AZFramework Scene.
|
||||
return scene->GetSubsystem<RPI::Scene>();
|
||||
RPI::ScenePtr* scenePtr = scene->FindSubsystem<RPI::ScenePtr>();
|
||||
if (scenePtr)
|
||||
{
|
||||
return scenePtr->get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ namespace AtomToolsFramework
|
||||
AZ::RPI::ConstViewportContextPtr GetViewportContext() const;
|
||||
//! Creates an AZ::RPI::ScenePtr for the given scene and assigns it to the current ViewportContext.
|
||||
//! If useDefaultRenderPipeline is specified, this will initialize the scene with a rendering pipeline.
|
||||
void SetScene(AzFramework::Scene* scene, bool useDefaultRenderPipeline = true);
|
||||
void SetScene(const AZStd::shared_ptr<AzFramework::Scene>& scene, bool useDefaultRenderPipeline = true);
|
||||
//! Gets the default camera that's been automatically registered to our ViewportContext.
|
||||
AZ::RPI::ViewPtr GetDefaultCamera();
|
||||
AZ::RPI::ConstViewPtr GetDefaultCamera() const;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user