Provisional implemenation and testing of central state tracker to track viewport editing modes. (#4112)

* Provisional impl and testing of central state tracker.

Signed-off-by: John <jonawals@amazon.com>

* Add missing namespace comment.

Signed-off-by: John <jonawals@amazon.com>

* ViewportEditorModeState -> ViewportEditorModes

Signed-off-by: John <jonawals@amazon.com>

* ViewportEditorModesTracker -> ViewportEditorModeTracker

Signed-off-by: John <jonawals@amazon.com>

* GetEditorModeState ->GetViewportEditorModes

Signed-off-by: John <jonawals@amazon.com>

* GetNumTrackedViewports -> GetTrackedViewportCount

Signed-off-by: John <jonawals@amazon.com>

* IsViewportStateBeingTracked -> IsViewportModeTracked

Signed-off-by: John <jonawals@amazon.com>

* Fix API comments.

Signed-off-by: John <jonawals@amazon.com>

* Delete hangover file.

Signed-off-by: John <jonawals@amazon.com>

* Delete more hangover files.

Signed-off-by: John <jonawals@amazon.com>

* Minor member name refactor.

Signed-off-by: John <jonawals@amazon.com>

* Refactor nonclemanture.

Signed-off-by: John <jonawals@amazon.com>

* Rename Enter/ExitMode to Register/UnregisterMode.

Signed-off-by: John <jonawals@amazon.com>

* Error and warning msgs now return AZ::Outcomes.

Signed-off-by: John <jonawals@amazon.com>

* Change all nomenclature to Activate/Deactivate for consistency.

Signed-off-by: John <jonawals@amazon.com>

* Change tense of notification bus methods.

Signed-off-by: John <jonawals@amazon.com>

* Fix malformed string format.

Signed-off-by: John <jonawals@amazon.com>

* Fix malformed string format (again).

Signed-off-by: John <jonawals@amazon.com>

* Fix Linux warning.

Signed-off-by: John <jonawals@amazon.com>
This commit is contained in:
jonawals
2021-09-20 17:37:09 +01:00
committed by GitHub
parent 1f542838bb
commit 4aff76343f
7 changed files with 822 additions and 0 deletions
@@ -0,0 +1,43 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Interface/Interface.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
namespace AzToolsFramework
{
//! The AZ::Interface of the central editor mode tracker for all viewports.
class ViewportEditorModeTrackerInterface
{
public:
AZ_RTTI(ViewportEditorModeTrackerInterface, "{7D72A4F7-2147-4ED9-A315-E456A3BE3CF6}");
virtual ~ViewportEditorModeTrackerInterface() = default;
//! Activates the specified editor mode for the specified viewport.
virtual AZ::Outcome<void, AZStd::string> ActivateMode(
const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) = 0;
//! Deactivates the specified editor mode for the specified viewport.
virtual AZ::Outcome<void, AZStd::string> DeactivateMode(
const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) = 0;
//! Attempts to retrieve the editor mode state for the specified viewport, otherwise returns nullptr.
virtual const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const = 0;
//! Returns the number of viewports currently being tracked.
virtual size_t GetTrackedViewportCount() const = 0;
//! Returns true if the specified viewport is being tracked, otherwise false.
virtual bool IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const = 0;
};
} // namespace AzToolsFramework
@@ -0,0 +1,66 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/Event.h>
#include <AzFramework/Viewport/ViewportId.h>
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
namespace AzToolsFramework
{
//! Enumeration of each viewport editor mode.
enum class ViewportEditorMode : AZ::u8
{
Default,
Component,
Focus,
Pick
};
//! Viewport identifier and other relevant viewport data.
struct ViewportEditorModeInfo
{
using IdType = AzFramework::ViewportId;
IdType m_id = ViewportUi::DefaultViewportId; //!< The unique identifier for a given viewport.
};
//! Interface for the editor modes of a given viewport.
class ViewportEditorModesInterface
{
public:
virtual ~ViewportEditorModesInterface() = default;
//! Returns true if the specified editor mode is active, otherwise false.
virtual bool IsModeActive(ViewportEditorMode mode) const = 0;
};
//! Provides a bus to notify when the different editor modes are entered/exit.
class ViewportEditorModeNotifications
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = ViewportEditorModeInfo::IdType;
//////////////////////////////////////////////////////////////////////////
//! Notifies subscribers of the a given viewport to the activation of the specified editor mode.
virtual void OnEditorModeActivated([[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
{
}
//! Notifies subscribers of the a given viewport to the deactivation of the specified editor mode.
virtual void OnEditorModeDeactivated([[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
{
}
};
using ViewportEditorModeNotificationsBus = AZ::EBus<ViewportEditorModeNotifications>;
} // namespace AzToolsFramework
@@ -0,0 +1,149 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h>
namespace AzToolsFramework
{
AZ::Outcome<void, AZStd::string> ViewportEditorModes::ActivateMode(ViewportEditorMode mode)
{
if (const AZ::u32 modeIndex = static_cast<AZ::u32>(mode);
modeIndex < NumEditorModes)
{
m_editorModes[modeIndex] = true;
return AZ::Success();
}
else
{
return AZ::Failure(
AZStd::string::format("Cannot activate mode %u, mode is not recognized", modeIndex));
}
}
AZ::Outcome<void, AZStd::string> ViewportEditorModes::DeactivateMode(ViewportEditorMode mode)
{
if (const AZ::u32 modeIndex = static_cast<AZ::u32>(mode); modeIndex < NumEditorModes)
{
m_editorModes[modeIndex] = false;
return AZ::Success();
}
else
{
return AZ::Failure(
AZStd::string::format("Cannot deactivate mode %u, mode is not recognized", modeIndex));
}
}
bool ViewportEditorModes::IsModeActive(ViewportEditorMode mode) const
{
return m_editorModes[static_cast<AZ::u32>(mode)];
}
void ViewportEditorModeTracker::RegisterInterface()
{
if (AZ::Interface<ViewportEditorModeTrackerInterface>::Get() == nullptr)
{
AZ::Interface<ViewportEditorModeTrackerInterface>::Register(this);
}
}
void ViewportEditorModeTracker::UnregisterInterface()
{
if (AZ::Interface<ViewportEditorModeTrackerInterface>::Get() != nullptr)
{
AZ::Interface<ViewportEditorModeTrackerInterface>::Unregister(this);
}
}
AZ::Outcome<void, AZStd::string> ViewportEditorModeTracker::ActivateMode(
const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode)
{
auto& editorModes = m_viewportEditorModesMap[viewportEditorModeInfo.m_id];
if (editorModes.IsModeActive(mode))
{
return AZ::Failure(AZStd::string::format(
"Duplicate call to ActivateMode for mode '%u' on id '%i'", static_cast<AZ::u32>(mode), viewportEditorModeInfo.m_id));
}
if (const auto result = editorModes.ActivateMode(mode);
!result.IsSuccess())
{
return result;
}
ViewportEditorModeNotificationsBus::Event(
viewportEditorModeInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeActivated, editorModes, mode);
return AZ::Success();
}
AZ::Outcome<void, AZStd::string> ViewportEditorModeTracker::DeactivateMode(
const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode)
{
ViewportEditorModes* editorModes = nullptr;
bool modeWasActive = true;
if (m_viewportEditorModesMap.count(viewportEditorModeInfo.m_id))
{
editorModes = &m_viewportEditorModesMap.at(viewportEditorModeInfo.m_id);
if (!editorModes->IsModeActive(mode))
{
return AZ::Failure(AZStd::string::format(
"Duplicate call to DeactivateMode for mode '%u' on id '%i'", static_cast<AZ::u32>(mode), viewportEditorModeInfo.m_id));
}
}
else
{
modeWasActive = false;
editorModes = &m_viewportEditorModesMap[viewportEditorModeInfo.m_id];
}
if(const auto result = editorModes->DeactivateMode(mode);
!result.IsSuccess())
{
return result;
}
ViewportEditorModeNotificationsBus::Event(
viewportEditorModeInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeDeactivated, *editorModes, mode);
if (modeWasActive)
{
return AZ::Success();
}
else
{
return AZ::Failure(AZStd::string::format(
"Call to DeactivateMode for mode '%u' on id '%i' without precursor call to ActivateMode", static_cast<AZ::u32>(mode),
viewportEditorModeInfo.m_id));
}
}
const ViewportEditorModesInterface* ViewportEditorModeTracker::GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const
{
if (auto editorModes = m_viewportEditorModesMap.find(viewportEditorModeInfo.m_id);
editorModes != m_viewportEditorModesMap.end())
{
return &editorModes->second;
}
else
{
return nullptr;
}
}
size_t ViewportEditorModeTracker::GetTrackedViewportCount() const
{
return m_viewportEditorModesMap.size();
}
bool ViewportEditorModeTracker::IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const
{
return m_viewportEditorModesMap.count(viewportEditorModeInfo.m_id) > 0;
}
} // namespace AzToolsFramework
@@ -0,0 +1,61 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
namespace AzToolsFramework
{
//! The encapsulation of the editor modes for a given viewport.
class ViewportEditorModes
: public ViewportEditorModesInterface
{
public:
//! The number of currently supported viewport editor modes.
static constexpr AZ::u8 NumEditorModes = 4;
//! Sets the specified mode as active.
AZ::Outcome<void, AZStd::string> ActivateMode(ViewportEditorMode mode);
// Sets the specified mode as inactive.
AZ::Outcome<void, AZStd::string> DeactivateMode(ViewportEditorMode mode);
// ViewportEditorModesInterface ...
bool IsModeActive(ViewportEditorMode mode) const override;
private:
AZStd::array<bool, NumEditorModes> m_editorModes{}; //!< State flags to track active/inactive status of viewport editor modes.
};
//! The implementation of the central editor mode state tracker for all viewports.
class ViewportEditorModeTracker
: public ViewportEditorModeTrackerInterface
{
public:
//! Registers this object with the AZ::Interface.
void RegisterInterface();
//! Unregisters this object with the AZ::Interface.
void UnregisterInterface();
// ViewportEditorModeTrackerInterface overrides ...
AZ::Outcome<void, AZStd::string> ActivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;
AZ::Outcome<void, AZStd::string> DeactivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;
const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const override;
size_t GetTrackedViewportCount() const override;
bool IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const override;
private:
using ViewportEditorModesMap = AZStd::unordered_map<typename ViewportEditorModeInfo::IdType, ViewportEditorModes>;
ViewportEditorModesMap m_viewportEditorModesMap; //!< Editor mode state per viewport.
};
} // namespace AzToolsFramework
@@ -34,6 +34,7 @@ set(FILES
API/EditorAnimationSystemRequestBus.h
API/EditorEntityAPI.h
API/EditorLevelNotificationBus.h
API/ViewportEditorModeTrackerNotificationBus.h
API/EditorVegetationRequestsBus.h
API/EditorPythonConsoleBus.h
API/EditorPythonRunnerRequestsBus.h
@@ -44,6 +45,7 @@ set(FILES
API/EntityCompositionNotificationBus.h
API/EditorViewportIconDisplayInterface.h
API/ViewPaneOptions.h
API/ViewportEditorModeTrackerInterface.h
Application/Ticker.h
Application/Ticker.cpp
Application/EditorEntityManager.cpp
@@ -538,6 +540,8 @@ set(FILES
ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp
ViewportSelection/EditorVisibleEntityDataCache.h
ViewportSelection/EditorVisibleEntityDataCache.cpp
ViewportSelection/ViewportEditorModeTracker.cpp
ViewportSelection/ViewportEditorModeTracker.h
ToolsFileUtils/ToolsFileUtils.h
AssetBrowser/AssetBrowserBus.h
AssetBrowser/AssetBrowserSourceDropBus.h