@@ -74,6 +74,7 @@ def update_manifest(scene):
|
||||
source_filename_only = os.path.basename(clean_filename)
|
||||
|
||||
created_entities = []
|
||||
previous_entity_id = azlmbr.entity.InvalidEntityId
|
||||
|
||||
# Loop every mesh node in the scene
|
||||
for activeMeshIndex in range(len(mesh_name_list)):
|
||||
@@ -102,14 +103,33 @@ def update_manifest(scene):
|
||||
# The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
|
||||
# The assetHint will be converted to an AssetId later during prefab loading
|
||||
json_update = json.dumps({
|
||||
"Controller": { "Configuration": { "ModelAsset": {
|
||||
"assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
|
||||
});
|
||||
"Controller": { "Configuration": { "ModelAsset": {
|
||||
"assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
|
||||
});
|
||||
# Apply the JSON above to the component we created
|
||||
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)
|
||||
|
||||
if not result:
|
||||
raise RuntimeError("UpdateComponentForEntity failed")
|
||||
raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
|
||||
|
||||
# Get the transform component
|
||||
transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0")
|
||||
|
||||
# Set this entity to be a child of the last entity we created
|
||||
# This is just an example of how to do parenting and isn't necessarily useful to parent everything like this
|
||||
if previous_entity_id is not None:
|
||||
transform_json = json.dumps({
|
||||
"Parent Entity" : previous_entity_id.to_json()
|
||||
});
|
||||
|
||||
# Apply the JSON update
|
||||
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, transform_component, transform_json)
|
||||
|
||||
if not result:
|
||||
raise RuntimeError("UpdateComponentForEntity failed for Transform component")
|
||||
|
||||
# Update the last entity id for next time
|
||||
previous_entity_id = entity_id
|
||||
|
||||
# Keep track of the entity we set up, we'll add them all to the prefab we're creating later
|
||||
created_entities.append(entity_id)
|
||||
@@ -147,6 +167,8 @@ def on_update_manifest(args):
|
||||
except RuntimeError as err:
|
||||
print (f'ERROR - {err}')
|
||||
log_exception_traceback()
|
||||
except:
|
||||
log_exception_traceback()
|
||||
|
||||
global sceneJobHandler
|
||||
sceneJobHandler = None
|
||||
|
||||
@@ -71,5 +71,9 @@ class TestAutomation(EditorTestSuite):
|
||||
class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C36525664")
|
||||
class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module
|
||||
|
||||
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
|
||||
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
postfx_gradient_weight_creation = (
|
||||
"PostFX Gradient Weight Modifier Entity successfully created",
|
||||
"PostFX Gradient Weight Modifier Entity failed to be created")
|
||||
postfx_gradient_weight_component = (
|
||||
"Entity has a PostFX Gradient Weight Modifier component",
|
||||
"Entity failed to find PostFX Gradient Weight Modifier component")
|
||||
postfx_gradient_weight_disabled = (
|
||||
"PostFX Gradient Weight Modifier component disabled",
|
||||
"PostFX Gradient Weight Modifier component was not disabled.")
|
||||
postfx_layer_component = (
|
||||
"Entity has a PostFX Layer component",
|
||||
"Entity did not have an PostFX Layer component")
|
||||
postfx_gradient_weight_enabled = (
|
||||
"PostFX Gradient Weight Modifier component enabled",
|
||||
"PostFX Gradient Weight Modifier component was not enabled.")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
|
||||
|
||||
def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
|
||||
"""
|
||||
Summary:
|
||||
Tests the PostFX Gradient Weight Modifier component can be added to an entity and has the expected functionality.
|
||||
|
||||
Test setup:
|
||||
- Wait for Editor idle loop.
|
||||
- Open the "Base" level.
|
||||
|
||||
Expected Behavior:
|
||||
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
|
||||
Creation and deletion undo/redo should also work.
|
||||
|
||||
Test Steps:
|
||||
1) Create a PostFX Gradient Weight Modifier entity with no components.
|
||||
2) Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Verify PostFX Gradient Weight Modifier component not enabled.
|
||||
6) Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
|
||||
7) Verify PostFX Gradient Weight Modifier component is enabled.
|
||||
8) Enter/Exit game mode.
|
||||
9) Test IsHidden.
|
||||
10) Test IsVisible.
|
||||
11) Delete PostFX Gradient Weight Modifier entity.
|
||||
12) UNDO deletion.
|
||||
13) REDO deletion.
|
||||
14) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("", "Base")
|
||||
|
||||
# Test steps begin.
|
||||
# 1. Create a PostFX Gradient Weight Modifier entity with no components.
|
||||
postfx_gradient_weight_name = "PostFX Gradient Weight Modifier"
|
||||
postfx_gradient_weight_entity = EditorEntity.create_editor_entity(postfx_gradient_weight_name)
|
||||
Report.critical_result(Tests.postfx_gradient_weight_creation, postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 2. Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
|
||||
postfx_gradient_weight_component = postfx_gradient_weight_entity.add_component(postfx_gradient_weight_name)
|
||||
Report.critical_result(
|
||||
Tests.postfx_gradient_weight_component,
|
||||
postfx_gradient_weight_entity.has_component(postfx_gradient_weight_name))
|
||||
|
||||
# 3. UNDO the entity creation and component addition.
|
||||
# -> UNDO component addition.
|
||||
general.undo()
|
||||
# -> UNDO naming entity.
|
||||
general.undo()
|
||||
# -> UNDO selecting entity.
|
||||
general.undo()
|
||||
# -> UNDO entity creation.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_undo, not postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 4. REDO the entity creation and component addition.
|
||||
# -> REDO entity creation.
|
||||
general.redo()
|
||||
# -> REDO selecting entity.
|
||||
general.redo()
|
||||
# -> REDO naming entity.
|
||||
general.redo()
|
||||
# -> REDO component addition.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 5. Verify PostFX Gradient Weight Modifier component not enabled.
|
||||
Report.result(Tests.postfx_gradient_weight_disabled, not postfx_gradient_weight_component.is_enabled())
|
||||
|
||||
# 6. Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
|
||||
postfx_layer_name = "PostFX Layer"
|
||||
postfx_gradient_weight_entity.add_component(postfx_layer_name)
|
||||
Report.result(Tests.postfx_layer_component, postfx_gradient_weight_entity.has_component(postfx_layer_name))
|
||||
|
||||
# 7. Verify PostFX Gradient Weight Modifier component is enabled.
|
||||
Report.result(Tests.postfx_gradient_weight_enabled, postfx_gradient_weight_component.is_enabled())
|
||||
|
||||
# 8. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 9. Test IsHidden.
|
||||
postfx_gradient_weight_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, postfx_gradient_weight_entity.is_hidden() is True)
|
||||
|
||||
# 10. Test IsVisible.
|
||||
postfx_gradient_weight_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, postfx_gradient_weight_entity.is_visible() is True)
|
||||
|
||||
# 11. Delete PostFX Gradient Weight Modifier entity.
|
||||
postfx_gradient_weight_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 12. UNDO deletion.
|
||||
general.undo()
|
||||
Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 13. REDO deletion.
|
||||
general.redo()
|
||||
Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists())
|
||||
|
||||
# 14. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity)
|
||||
@@ -19,10 +19,16 @@ namespace Editor
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
#ifdef PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
AzFramework::XcbEventHandlerBus::Broadcast(&AzFramework::XcbEventHandler::HandleXcbEvent, static_cast<xcb_generic_event_t*>(message));
|
||||
// We need to handle RAW Input events in a separate loop. This is a workaround to enable XInput2 RAW Inputs using Editor mode.
|
||||
// TODO To have this call here might be not be perfect.
|
||||
AzFramework::XcbEventHandlerBus::Broadcast(&AzFramework::XcbEventHandler::PollSpecialEvents);
|
||||
|
||||
// Now handle the rest of the events.
|
||||
AzFramework::XcbEventHandlerBus::Broadcast(
|
||||
&AzFramework::XcbEventHandler::HandleXcbEvent, static_cast<xcb_generic_event_t*>(message));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace Editor
|
||||
|
||||
@@ -264,6 +264,9 @@ void EditorPreferencesDialog::SetFilter(const QString& filter)
|
||||
else if (m_currentPageItem)
|
||||
{
|
||||
m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
|
||||
|
||||
// Refresh the Stylesheet - when using search functionality.
|
||||
AzQtComponents::StyleManager::repolishStyleSheet(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,15 +108,11 @@ CObjectManager::CObjectManager()
|
||||
|
||||
m_objectsByName.reserve(1024);
|
||||
LoadRegistry();
|
||||
|
||||
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CObjectManager::~CObjectManager()
|
||||
{
|
||||
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
|
||||
|
||||
m_bExiting = true;
|
||||
SaveRegistry();
|
||||
DeleteAllObjects();
|
||||
@@ -2307,37 +2303,6 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::OnEditorModeActivated(
|
||||
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
|
||||
{
|
||||
if (mode == AzToolsFramework::ViewportEditorMode::Component)
|
||||
{
|
||||
// hide current gizmo for entity (translate/rotate/scale)
|
||||
IGizmoManager* gizmoManager = GetGizmoManager();
|
||||
const size_t gizmoCount = static_cast<size_t>(gizmoManager->GetGizmoCount());
|
||||
for (size_t i = 0; i < gizmoCount; ++i)
|
||||
{
|
||||
gizmoManager->RemoveGizmo(gizmoManager->GetGizmoByIndex(static_cast<int>(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::OnEditorModeDeactivated(
|
||||
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
|
||||
{
|
||||
if (mode == AzToolsFramework::ViewportEditorMode::Component)
|
||||
{
|
||||
// show translate/rotate/scale gizmo again
|
||||
if (IGizmoManager* gizmoManager = GetGizmoManager())
|
||||
{
|
||||
if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
|
||||
{
|
||||
gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "ObjectManagerEventBus.h"
|
||||
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <Include/SandboxAPI.h>
|
||||
@@ -59,7 +58,6 @@ public:
|
||||
*/
|
||||
class CObjectManager
|
||||
: public IObjectManager
|
||||
, private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
|
||||
{
|
||||
public:
|
||||
//! Selection functor callback.
|
||||
@@ -330,12 +328,6 @@ private:
|
||||
|
||||
void FindDisplayableObjects(DisplayContext& dc, bool bDisplay);
|
||||
|
||||
// ViewportEditorModeNotificationsBus overrides ...
|
||||
void OnEditorModeActivated(
|
||||
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
|
||||
void OnEditorModeDeactivated(
|
||||
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
|
||||
|
||||
private:
|
||||
typedef std::map<GUID, CBaseObjectPtr, guid_less_predicate> Objects;
|
||||
Objects m_objects;
|
||||
|
||||
@@ -225,8 +225,16 @@ namespace AZ
|
||||
|
||||
ConsoleCommandContainer commandSubset;
|
||||
|
||||
for (ConsoleFunctorBase* curr = m_head; curr != nullptr; curr = curr->m_next)
|
||||
for (const auto& functor : m_commands)
|
||||
{
|
||||
if (functor.second.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter functors registered with the same name
|
||||
const ConsoleFunctorBase* curr = functor.second.front();
|
||||
|
||||
if ((curr->GetFlags() & ConsoleFunctorFlags::IsInvisible) == ConsoleFunctorFlags::IsInvisible)
|
||||
{
|
||||
// Filter functors marked as invisible
|
||||
@@ -236,7 +244,12 @@ namespace AZ
|
||||
if (StringFunc::StartsWith(curr->m_name, command, false))
|
||||
{
|
||||
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
|
||||
commandSubset.push_back(curr->m_name);
|
||||
|
||||
if (commandSubset.size() < MaxConsoleCommandPlusArgsLength)
|
||||
{
|
||||
commandSubset.push_back(curr->m_name);
|
||||
}
|
||||
|
||||
if (matches)
|
||||
{
|
||||
matches->push_back(curr->m_name);
|
||||
@@ -271,7 +284,10 @@ namespace AZ
|
||||
{
|
||||
for (auto& curr : m_commands)
|
||||
{
|
||||
visitor(curr.second.front());
|
||||
if (!curr.second.empty())
|
||||
{
|
||||
visitor(curr.second.front());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +352,11 @@ namespace AZ
|
||||
{
|
||||
iter->second.erase(iter2);
|
||||
}
|
||||
|
||||
if (iter->second.empty())
|
||||
{
|
||||
m_commands.erase(iter);
|
||||
}
|
||||
}
|
||||
functor->Unlink(m_head);
|
||||
functor->m_console = nullptr;
|
||||
|
||||
@@ -40,6 +40,12 @@ namespace AZ
|
||||
static unsigned int Record(StackFrame* frames, unsigned int maxNumOfFrames, unsigned int suppressCount = 0, void* nativeThread = 0);
|
||||
};
|
||||
|
||||
class StackConverter
|
||||
{
|
||||
public:
|
||||
static unsigned int FromNative(StackFrame* frames, unsigned int maxNumOfFrames, void* nativeContext);
|
||||
};
|
||||
|
||||
class SymbolStorage
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
struct StackFrame;
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
@@ -551,17 +553,19 @@ namespace AZ
|
||||
{
|
||||
StackFrame frames[25];
|
||||
|
||||
// Without StackFrame explicit alignment frames array is aligned to 4 bytes
|
||||
// which causes the stack tracing to fail.
|
||||
//size_t bla = AZStd::alignment_of<StackFrame>::value;
|
||||
//printf("Alignment value %d address 0x%08x : 0x%08x\n",bla,frames);
|
||||
SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
|
||||
unsigned int numFrames = 0;
|
||||
|
||||
if (!nativeContext)
|
||||
{
|
||||
suppressCount += 1; /// If we don't provide a context we will capture in the RecordFunction, so skip us (Trace::PrinCallstack).
|
||||
suppressCount += 1; /// If we don't provide a context we will capture in the RecordFunction, so skip us (Trace::PrintCallstack).
|
||||
numFrames = StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), suppressCount);
|
||||
}
|
||||
unsigned int numFrames = StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), suppressCount, nativeContext);
|
||||
else
|
||||
{
|
||||
numFrames = StackConverter::FromNative(frames, AZ_ARRAY_SIZE(frames), nativeContext);
|
||||
}
|
||||
|
||||
if (numFrames)
|
||||
{
|
||||
SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
|
||||
+5
@@ -17,6 +17,11 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int StackConverter::FromNative(StackFrame*, unsigned int, void*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SymbolStorage::LoadModuleData(const void*, unsigned int)
|
||||
{}
|
||||
|
||||
|
||||
@@ -78,6 +78,12 @@ StackRecorder::Record(StackFrame* frames, unsigned int maxNumOfFrames, unsigned
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned int StackConverter::FromNative([[maybe_unused]] StackFrame* frames, [[maybe_unused]] unsigned int maxNumOfFrames, [[maybe_unused]] void* nativeContext)
|
||||
{
|
||||
AZ_Assert(false, "StackConverter::FromNative() is not supported for UnixLike platform yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SymbolStorage::DecodeFrames(const StackFrame* frames, unsigned int numFrames, StackLine* textLines)
|
||||
{
|
||||
|
||||
@@ -1048,9 +1048,9 @@ cleanup:
|
||||
unsigned int
|
||||
StackRecorder::Record(StackFrame* frames, unsigned int maxNumOfFrames, unsigned int suppressCount, void* nativeThread)
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
unsigned int numFrames = 0;
|
||||
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
if (nativeThread == NULL)
|
||||
{
|
||||
++suppressCount; // Skip current call
|
||||
@@ -1079,9 +1079,8 @@ cleanup:
|
||||
|
||||
STACKFRAME64 sf;
|
||||
memset(&sf, 0, sizeof(STACKFRAME64));
|
||||
DWORD imageType;
|
||||
DWORD imageType = IMAGE_FILE_MACHINE_AMD64;
|
||||
|
||||
imageType = IMAGE_FILE_MACHINE_AMD64;
|
||||
sf.AddrPC.Offset = context.Rip;
|
||||
sf.AddrPC.Mode = AddrModeFlat;
|
||||
sf.AddrFrame.Offset = context.Rsp;
|
||||
@@ -1090,8 +1089,7 @@ cleanup:
|
||||
sf.AddrStack.Mode = AddrModeFlat;
|
||||
|
||||
EnterCriticalSection(&g_csDbgHelpDll);
|
||||
s32 frame = -(s32)suppressCount;
|
||||
for (; frame < (s32)maxNumOfFrames; ++frame)
|
||||
for (s32 frame = -static_cast<s32>(suppressCount); frame < static_cast<s32>(maxNumOfFrames); ++frame)
|
||||
{
|
||||
if (!g_StackWalk64(imageType, g_currentProcess, hThread, &sf, &context, 0, g_SymFunctionTableAccess64, g_SymGetModuleBase64, 0))
|
||||
{
|
||||
@@ -1111,15 +1109,68 @@ cleanup:
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_csDbgHelpDll);
|
||||
}
|
||||
return numFrames;
|
||||
}
|
||||
#else
|
||||
(void)frames;
|
||||
(void)maxNumOfFrames;
|
||||
(void)suppressCount;
|
||||
(void)nativeThread;
|
||||
return 0;
|
||||
AZ_UNUSED(frames);
|
||||
AZ_UNUSED(maxNumOfFrames);
|
||||
AZ_UNUSED(suppressCount);
|
||||
AZ_UNUSED(nativeThread);
|
||||
#endif // AZ_ENABLE_DEBUG_TOOLS
|
||||
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
unsigned int StackConverter::FromNative(StackFrame* frames, unsigned int maxNumOfFrames, void* nativeContext)
|
||||
{
|
||||
unsigned int numFrames = 0;
|
||||
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
if (!g_dbgHelpLoaded)
|
||||
{
|
||||
LoadDbgHelp();
|
||||
}
|
||||
|
||||
HANDLE hThread;
|
||||
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hThread, 0, false, DUPLICATE_SAME_ACCESS);
|
||||
|
||||
PCONTEXT nativeContextType = reinterpret_cast<PCONTEXT>(nativeContext);
|
||||
STACKFRAME64 sf;
|
||||
memset(&sf, 0, sizeof(STACKFRAME64));
|
||||
|
||||
DWORD imageType = IMAGE_FILE_MACHINE_AMD64;
|
||||
|
||||
sf.AddrPC.Offset = nativeContextType->Rip;
|
||||
sf.AddrPC.Mode = AddrModeFlat;
|
||||
sf.AddrFrame.Offset = nativeContextType->Rsp;
|
||||
sf.AddrFrame.Mode = AddrModeFlat;
|
||||
sf.AddrStack.Offset = nativeContextType->Rsp;
|
||||
sf.AddrStack.Mode = AddrModeFlat;
|
||||
|
||||
EnterCriticalSection(&g_csDbgHelpDll);
|
||||
for (unsigned int frame = 0; frame < maxNumOfFrames; ++frame)
|
||||
{
|
||||
if (!g_StackWalk64(imageType, g_currentProcess, hThread, &sf, nativeContext, 0, g_SymFunctionTableAccess64, g_SymGetModuleBase64, 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (sf.AddrPC.Offset == sf.AddrReturn.Offset)
|
||||
{
|
||||
// "StackWalk64-Endless-Callstack!"
|
||||
break;
|
||||
}
|
||||
|
||||
frames[numFrames++].m_programCounter = sf.AddrPC.Offset;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_csDbgHelpDll);
|
||||
#else
|
||||
AZ_UNUSED(frames);
|
||||
AZ_UNUSED(maxNumOfFrames);
|
||||
AZ_UNUSED(nativeContext);
|
||||
#endif
|
||||
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1413,7 +1413,7 @@ namespace UnitTest
|
||||
>;
|
||||
TYPED_TEST_CASE(HashedSetDifferentAllocatorFixture, SetTemplateConfigs);
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TYPED_TEST(HashedSetDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
|
||||
{
|
||||
using ContainerType = typename TypeParam::ContainerType;
|
||||
@@ -1435,7 +1435,7 @@ namespace UnitTest
|
||||
}
|
||||
}, ".*");
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
template<typename ContainerType>
|
||||
class HashedMapContainers
|
||||
@@ -1811,7 +1811,7 @@ namespace UnitTest
|
||||
>;
|
||||
TYPED_TEST_CASE(HashedMapDifferentAllocatorFixture, MapTemplateConfigs);
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TYPED_TEST(HashedMapDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
|
||||
{
|
||||
using ContainerType = typename TypeParam::ContainerType;
|
||||
@@ -1833,7 +1833,7 @@ namespace UnitTest
|
||||
}
|
||||
} , ".*");
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace HashedContainerTransparentTestInternal
|
||||
{
|
||||
|
||||
@@ -1095,7 +1095,7 @@ namespace UnitTest
|
||||
>;
|
||||
TYPED_TEST_CASE(TreeSetDifferentAllocatorFixture, SetTemplateConfigs);
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TYPED_TEST(TreeSetDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
|
||||
{
|
||||
using ContainerType = typename TypeParam::ContainerType;
|
||||
@@ -1117,7 +1117,7 @@ namespace UnitTest
|
||||
}
|
||||
}, ".*");
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TYPED_TEST(TreeSetDifferentAllocatorFixture, SwapMovesElementsWhenAllocatorsDiffer)
|
||||
{
|
||||
@@ -1516,7 +1516,7 @@ namespace UnitTest
|
||||
>;
|
||||
TYPED_TEST_CASE(TreeMapDifferentAllocatorFixture, MapTemplateConfigs);
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TYPED_TEST(TreeMapDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
|
||||
{
|
||||
using ContainerType = typename TypeParam::ContainerType;
|
||||
@@ -1538,7 +1538,7 @@ namespace UnitTest
|
||||
}
|
||||
}, ".*");
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TYPED_TEST(TreeMapDifferentAllocatorFixture, SwapMovesElementsWhenAllocatorsDiffer)
|
||||
{
|
||||
|
||||
@@ -1595,7 +1595,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST_F(ThreadEventsDeathTest, UsingClientBus_AvoidsDeadlock)
|
||||
{
|
||||
EXPECT_EXIT(
|
||||
@@ -1608,5 +1608,5 @@ namespace UnitTest
|
||||
, ::testing::ExitedWithCode(0),".*");
|
||||
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
}
|
||||
|
||||
@@ -736,7 +736,10 @@ namespace UnitTest
|
||||
auto& assetManager = AssetManager::Instance();
|
||||
|
||||
AssetBusCallbacks callbacks{};
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
callbacks.SetOnAssetReadyCallback([&, AssetNoRefB](const Asset<AssetData>&, AssetBusCallbacks&)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
// This callback should run inside the "main thread" dispatch events loop
|
||||
auto loadAsset = assetManager.GetAsset<AssetWithSerializedData>(AZ::Uuid(AssetNoRefB), AssetLoadBehavior::Default);
|
||||
|
||||
@@ -288,6 +288,21 @@ namespace AZ
|
||||
AZStd::string completeCommand = console->AutoCompleteCommand("testVec3");
|
||||
AZ_TEST_ASSERT(completeCommand == "testVec3");
|
||||
}
|
||||
|
||||
// Duplicate names
|
||||
{
|
||||
// Register two cvars with the same name
|
||||
auto id = AZ::TypeId();
|
||||
auto flag = AZ::ConsoleFunctorFlags::Null;
|
||||
auto signature = AZ::ConsoleFunctor<void, false>::FunctorSignature();
|
||||
AZ::ConsoleFunctor<void, false> cvarOne(*console, "testAutoCompleteDuplication", "", flag, id, signature);
|
||||
AZ::ConsoleFunctor<void, false> cvarTwo(*console, "testAutoCompleteDuplication", "", flag, id, signature);
|
||||
|
||||
// Autocomplete given name expecting one match (not two)
|
||||
AZStd::vector<AZStd::string> matches;
|
||||
AZStd::string completeCommand = console->AutoCompleteCommand("testAutoCompleteD", &matches);
|
||||
AZ_TEST_ASSERT(matches.size() == 1 && completeCommand == "testAutoCompleteDuplication");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ConsoleTests, ConsoleFunctor_FreeFunctorExecutionTest)
|
||||
|
||||
@@ -109,7 +109,10 @@ namespace AZ::Debug
|
||||
AZStd::thread threads[totalThreads];
|
||||
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
threads[threadIndex] = AZStd::thread([&startLogging, &messages]()
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
while (!startLogging)
|
||||
{
|
||||
@@ -226,7 +229,10 @@ namespace AZ::Debug
|
||||
AZStd::thread threads[totalThreads];
|
||||
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
threads[threadIndex] = AZStd::thread([&startLogging, &message, &totalRecordsWritten]()
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
AZ_UNUSED(message);
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class UnhandledExceptions
|
||||
: public ScopedAllocatorSetupFixture
|
||||
{
|
||||
|
||||
public:
|
||||
void causeAccessViolation()
|
||||
{
|
||||
int* someVariable = reinterpret_cast<int*>(0);
|
||||
*someVariable = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST_F(UnhandledExceptions, Handle)
|
||||
{
|
||||
EXPECT_DEATH(causeAccessViolation(), "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -144,14 +144,13 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
// SPEC-2669: Disabled since it is causing hangs on Linux
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST_F(AllocatorsTestFixtureLeakDetectionDeathTest_SKIPCODECOVERAGE, AllocatorLeak)
|
||||
{
|
||||
// testing that the TraceBusHook will fail on cause the test to die
|
||||
EXPECT_DEATH(TestAllocatorLeak(), "");
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Testing ScopedAllocatorSetupFixture. Testing that detects leaks
|
||||
|
||||
+18
@@ -597,7 +597,10 @@ namespace AZ::IO
|
||||
path.InitFromAbsolutePath(m_dummyFilepath);
|
||||
|
||||
request->CreateRead(nullptr, buffer.get(), fileSize, path, 0, fileSize);
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [&fileSize, this](const FileRequest& request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
@@ -639,7 +642,10 @@ namespace AZ::IO
|
||||
path.InitFromAbsolutePath(m_dummyFilepath);
|
||||
|
||||
request->CreateRead(nullptr, buffer, unalignedSize + 4, path, unalignedOffset, unalignedSize);
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [unalignedOffset, unalignedSize, this](const FileRequest& request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
@@ -784,7 +790,10 @@ namespace AZ::IO
|
||||
requests[i] = m_context->GetNewInternalRequest();
|
||||
|
||||
requests[i]->CreateRead(nullptr, buffers[i].get(), chunkSize, path, i * chunkSize, chunkSize);
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [chunkSize, i](const FileRequest& request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
@@ -970,7 +979,10 @@ namespace AZ::IO
|
||||
i * chunkSize
|
||||
));
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [numChunks, &numCallbacks, &waitForReads](FileRequestHandle request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
IStreamer* streamer = Interface<IStreamer>::Get();
|
||||
if (streamer)
|
||||
@@ -1038,7 +1050,10 @@ namespace AZ::IO
|
||||
i * chunkSize
|
||||
));
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [numChunks, &waitForReads, &waitForSingleRead, &numReadCallbacks]([[maybe_unused]] FileRequestHandle request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
numReadCallbacks++;
|
||||
if (numReadCallbacks == 1)
|
||||
@@ -1059,7 +1074,10 @@ namespace AZ::IO
|
||||
for (size_t i = 0; i < numChunks; ++i)
|
||||
{
|
||||
cancels.push_back(m_streamer->Cancel(requests[numChunks - i - 1]));
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback = [&numCancelCallbacks, &waitForCancels, numChunks](FileRequestHandle request)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
auto result = Interface<IStreamer>::Get()->GetRequestStatus(request);
|
||||
EXPECT_EQ(result, IStreamerTypes::RequestStatus::Completed);
|
||||
|
||||
@@ -327,7 +327,7 @@ namespace JsonSerializationTests
|
||||
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
#if GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
using JsonSerializationDeathTests = JsonRegistrationContextTests;
|
||||
TEST_F(JsonSerializationDeathTests, DoubleUnregisterSerializer_Asserts)
|
||||
{
|
||||
@@ -338,5 +338,6 @@ namespace JsonSerializationTests
|
||||
}, ".*"
|
||||
);
|
||||
}
|
||||
#endif // GTEST_OS_SUPPORTS_DEATH_TEST
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} //namespace JsonSerializationTests
|
||||
|
||||
@@ -363,7 +363,10 @@ namespace AZ
|
||||
{
|
||||
constexpr AZStd::array visitTokens = { "Hello", "World", "", "More", "", "", "Tokens" };
|
||||
size_t visitIndex{};
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto visitor = [&visitIndex, &visitTokens](AZStd::string_view token)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
if (visitIndex > visitTokens.size())
|
||||
{
|
||||
@@ -389,7 +392,10 @@ namespace AZ
|
||||
{
|
||||
constexpr AZStd::array visitTokens = { "Hello", "World", "", "More", "", "", "Tokens" };
|
||||
size_t visitIndex = visitTokens.size() - 1;
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto visitor = [&visitIndex, &visitTokens](AZStd::string_view token)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
if (visitIndex > visitTokens.size())
|
||||
{
|
||||
|
||||
@@ -72,6 +72,7 @@ set(FILES
|
||||
Debug/AssetTracking.cpp
|
||||
Debug/LocalFileEventLoggerTests.cpp
|
||||
Debug/Trace.cpp
|
||||
Debug/UnhandledExceptions.cpp
|
||||
Name/NameJsonSerializerTests.cpp
|
||||
Name/NameTests.cpp
|
||||
RTTI/TypeSafeIntegralTests.cpp
|
||||
|
||||
@@ -23,10 +23,12 @@ namespace AzFramework
|
||||
virtual ~XcbEventHandler() = default;
|
||||
|
||||
virtual void HandleXcbEvent(xcb_generic_event_t* event) = 0;
|
||||
|
||||
// ATTN This is used as a workaround for RAW Input events when using the Editor.
|
||||
virtual void PollSpecialEvents(){};
|
||||
};
|
||||
|
||||
class XcbEventHandlerBusTraits
|
||||
: public AZ::EBusTraits
|
||||
class XcbEventHandlerBusTraits : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/std/typetraits/integral_constant.h>
|
||||
#include <AzFramework/API/ApplicationAPI_Linux.h>
|
||||
#include <AzFramework/XcbConnectionManager.h>
|
||||
#include <AzFramework/XcbInputDeviceMouse.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
xcb_window_t GetSystemCursorFocusWindow()
|
||||
{
|
||||
void* systemCursorFocusWindow = nullptr;
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::BroadcastResult(
|
||||
systemCursorFocusWindow, &AzFramework::InputSystemCursorConstraintRequests::GetSystemCursorConstraintWindow);
|
||||
|
||||
if (!systemCursorFocusWindow)
|
||||
{
|
||||
return XCB_NONE;
|
||||
}
|
||||
|
||||
// TODO Clang compile error because cast .... loses information. On GNU/Linux HWND is void* and on 64-bit
|
||||
// machines its obviously 64 bit but we receive the window id from m_renderOverlay.winId() which is xcb_window_t 32-bit.
|
||||
|
||||
return static_cast<xcb_window_t>(reinterpret_cast<uint64_t>(systemCursorFocusWindow));
|
||||
}
|
||||
|
||||
xcb_connection_t* XcbInputDeviceMouse::s_xcbConnection = nullptr;
|
||||
xcb_screen_t* XcbInputDeviceMouse::s_xcbScreen = nullptr;
|
||||
bool XcbInputDeviceMouse::m_xfixesInitialized = false;
|
||||
bool XcbInputDeviceMouse::m_xInputInitialized = false;
|
||||
|
||||
XcbInputDeviceMouse::XcbInputDeviceMouse(InputDeviceMouse& inputDevice)
|
||||
: InputDeviceMouse::Implementation(inputDevice)
|
||||
, m_systemCursorState(SystemCursorState::Unknown)
|
||||
, m_systemCursorPositionNormalized(0.5f, 0.5f)
|
||||
, m_prevConstraintWindow(XCB_NONE)
|
||||
, m_focusWindow(XCB_NONE)
|
||||
, m_cursorShown(true)
|
||||
{
|
||||
XcbEventHandlerBus::Handler::BusConnect();
|
||||
|
||||
SetSystemCursorState(SystemCursorState::Unknown);
|
||||
}
|
||||
|
||||
XcbInputDeviceMouse::~XcbInputDeviceMouse()
|
||||
{
|
||||
XcbEventHandlerBus::Handler::BusDisconnect();
|
||||
|
||||
SetSystemCursorState(SystemCursorState::Unknown);
|
||||
}
|
||||
|
||||
InputDeviceMouse::Implementation* XcbInputDeviceMouse::Create(InputDeviceMouse& inputDevice)
|
||||
{
|
||||
auto* interface = AzFramework::XcbConnectionManagerInterface::Get();
|
||||
if (!interface)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XCB interface not available");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
s_xcbConnection = AzFramework::XcbConnectionManagerInterface::Get()->GetXcbConnection();
|
||||
if (!s_xcbConnection)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XCB connection not available");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const xcb_setup_t* xcbSetup = xcb_get_setup(s_xcbConnection);
|
||||
s_xcbScreen = xcb_setup_roots_iterator(xcbSetup).data;
|
||||
if (!s_xcbScreen)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XCB screen not available");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Initialize XFixes extension which we use to create pointer barriers.
|
||||
if (!InitializeXFixes())
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XCB XFixes initialization failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Initialize XInput extension which is used to get RAW Input events.
|
||||
if (!InitializeXInput())
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XCB XInput initialization failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return aznew XcbInputDeviceMouse(inputDevice);
|
||||
}
|
||||
|
||||
bool XcbInputDeviceMouse::IsConnected() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::CreateBarriers(xcb_window_t window, bool create)
|
||||
{
|
||||
// Don't create any barriers if we are debugging. This will cause artifacts but better then
|
||||
// a confined cursor during debugging.
|
||||
if (AZ::Debug::Trace::IsDebuggerPresent())
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "Debugger running. Barriers will not be created.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (create)
|
||||
{
|
||||
// Destroy barriers if they are active already.
|
||||
if (!m_activeBarriers.empty())
|
||||
{
|
||||
for (const auto& barrier : m_activeBarriers)
|
||||
{
|
||||
xcb_xfixes_delete_pointer_barrier_checked(s_xcbConnection, barrier.id);
|
||||
}
|
||||
|
||||
m_activeBarriers.clear();
|
||||
}
|
||||
|
||||
// Get window information.
|
||||
const XcbStdFreePtr<xcb_get_geometry_reply_t> xcbGeometryReply{ xcb_get_geometry_reply(
|
||||
s_xcbConnection, xcb_get_geometry(s_xcbConnection, window), NULL) };
|
||||
|
||||
if (!xcbGeometryReply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const xcb_translate_coordinates_cookie_t translate_coord =
|
||||
xcb_translate_coordinates(s_xcbConnection, window, s_xcbScreen->root, 0, 0);
|
||||
|
||||
const XcbStdFreePtr<xcb_translate_coordinates_reply_t> xkbTranslateCoordReply{ xcb_translate_coordinates_reply(
|
||||
s_xcbConnection, translate_coord, NULL) };
|
||||
|
||||
if (!xkbTranslateCoordReply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int16_t x0 = xkbTranslateCoordReply->dst_x < 0 ? 0 : xkbTranslateCoordReply->dst_x;
|
||||
const int16_t y0 = xkbTranslateCoordReply->dst_y < 0 ? 0 : xkbTranslateCoordReply->dst_y;
|
||||
const int16_t x1 = xkbTranslateCoordReply->dst_x + xcbGeometryReply->width;
|
||||
const int16_t y1 = xkbTranslateCoordReply->dst_y + xcbGeometryReply->height;
|
||||
|
||||
// ATTN For whatever reason, when making an exact rectangle the pointer will escape the top right corner in some cases. Adding
|
||||
// an offset to the lines so that they cross each other prevents that.
|
||||
const int16_t offset = 30;
|
||||
|
||||
// Create the left barrier info.
|
||||
m_activeBarriers.push_back({ xcb_generate_id(s_xcbConnection), XCB_XFIXES_BARRIER_DIRECTIONS_POSITIVE_X, x0, Clamp(y0 - offset),
|
||||
x0, Clamp(y1 + offset) });
|
||||
|
||||
// Create the right barrier info.
|
||||
m_activeBarriers.push_back({ xcb_generate_id(s_xcbConnection), XCB_XFIXES_BARRIER_DIRECTIONS_NEGATIVE_X, x1, Clamp(y0 - offset),
|
||||
x1, Clamp(y1 + offset) });
|
||||
|
||||
// Create the top barrier info.
|
||||
m_activeBarriers.push_back({ xcb_generate_id(s_xcbConnection), XCB_XFIXES_BARRIER_DIRECTIONS_POSITIVE_Y, Clamp(x0 - offset), y0,
|
||||
Clamp(x1 + offset), y0 });
|
||||
|
||||
// Create the bottom barrier info.
|
||||
m_activeBarriers.push_back({ xcb_generate_id(s_xcbConnection), XCB_XFIXES_BARRIER_DIRECTIONS_NEGATIVE_Y, Clamp(x0 - offset), y1,
|
||||
Clamp(x1 + offset), y1 });
|
||||
|
||||
// Create the xfixes barriers.
|
||||
for (const auto& barrier : m_activeBarriers)
|
||||
{
|
||||
xcb_void_cookie_t cookie = xcb_xfixes_create_pointer_barrier_checked(
|
||||
s_xcbConnection, barrier.id, window, barrier.x0, barrier.y0, barrier.x1, barrier.y1, barrier.direction, 0, NULL);
|
||||
const XcbStdFreePtr<xcb_generic_error_t> xkbError{ xcb_request_check(s_xcbConnection, cookie) };
|
||||
|
||||
AZ_Warning(
|
||||
"XcbInput", !xkbError, "XFixes, failed to create barrier %d at (%d %d %d %d)", barrier.id, barrier.x0, barrier.y0,
|
||||
barrier.x1, barrier.y1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& barrier : m_activeBarriers)
|
||||
{
|
||||
xcb_xfixes_delete_pointer_barrier_checked(s_xcbConnection, barrier.id);
|
||||
}
|
||||
|
||||
m_activeBarriers.clear();
|
||||
}
|
||||
|
||||
xcb_flush(s_xcbConnection);
|
||||
}
|
||||
|
||||
bool XcbInputDeviceMouse::InitializeXFixes()
|
||||
{
|
||||
m_xfixesInitialized = false;
|
||||
|
||||
// We don't have to free query_extension_reply according to xcb documentation.
|
||||
const xcb_query_extension_reply_t* query_extension_reply = xcb_get_extension_data(s_xcbConnection, &xcb_xfixes_id);
|
||||
if (!query_extension_reply || !query_extension_reply->present)
|
||||
{
|
||||
return m_xfixesInitialized;
|
||||
}
|
||||
|
||||
const xcb_xfixes_query_version_cookie_t query_cookie = xcb_xfixes_query_version(s_xcbConnection, 5, 0);
|
||||
|
||||
xcb_generic_error_t* error = NULL;
|
||||
const XcbStdFreePtr<xcb_xfixes_query_version_reply_t> xkbQueryRequestReply{ xcb_xfixes_query_version_reply(
|
||||
s_xcbConnection, query_cookie, &error) };
|
||||
|
||||
if (!xkbQueryRequestReply || error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "Retrieving XFixes version failed : Error code %d", error->error_code);
|
||||
free(error);
|
||||
}
|
||||
return m_xfixesInitialized;
|
||||
}
|
||||
else if (xkbQueryRequestReply->major_version < 5)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XFixes version fails the minimum version check (%d<5)", xkbQueryRequestReply->major_version);
|
||||
return m_xfixesInitialized;
|
||||
}
|
||||
|
||||
m_xfixesInitialized = true;
|
||||
|
||||
return m_xfixesInitialized;
|
||||
}
|
||||
|
||||
bool XcbInputDeviceMouse::InitializeXInput()
|
||||
{
|
||||
m_xInputInitialized = false;
|
||||
|
||||
// We don't have to free query_extension_reply according to xcb documentation.
|
||||
const xcb_query_extension_reply_t* query_extension_reply = xcb_get_extension_data(s_xcbConnection, &xcb_input_id);
|
||||
if (!query_extension_reply || !query_extension_reply->present)
|
||||
{
|
||||
return m_xInputInitialized;
|
||||
}
|
||||
|
||||
const xcb_input_xi_query_version_cookie_t query_version_cookie = xcb_input_xi_query_version(s_xcbConnection, 2, 2);
|
||||
|
||||
xcb_generic_error_t* error = NULL;
|
||||
const XcbStdFreePtr<xcb_input_xi_query_version_reply_t> xkbQueryRequestReply{ xcb_input_xi_query_version_reply(
|
||||
s_xcbConnection, query_version_cookie, &error) };
|
||||
|
||||
if (!xkbQueryRequestReply || error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "Retrieving XInput version failed : Error code %d", error->error_code);
|
||||
free(error);
|
||||
}
|
||||
return m_xInputInitialized;
|
||||
}
|
||||
else if (xkbQueryRequestReply->major_version < 2)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "XInput version fails the minimum version check (%d<5)", xkbQueryRequestReply->major_version);
|
||||
return m_xInputInitialized;
|
||||
}
|
||||
|
||||
m_xInputInitialized = true;
|
||||
|
||||
return m_xInputInitialized;
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::SetEnableXInput(bool enable)
|
||||
{
|
||||
struct
|
||||
{
|
||||
xcb_input_event_mask_t head;
|
||||
int mask;
|
||||
} mask;
|
||||
|
||||
mask.head.deviceid = XCB_INPUT_DEVICE_ALL;
|
||||
mask.head.mask_len = 1;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
mask.mask = XCB_INPUT_XI_EVENT_MASK_RAW_MOTION | XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS |
|
||||
XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE | XCB_INPUT_XI_EVENT_MASK_MOTION | XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS |
|
||||
XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask.mask = XCB_NONE;
|
||||
}
|
||||
|
||||
xcb_input_xi_select_events(s_xcbConnection, s_xcbScreen->root, 1, &mask.head);
|
||||
|
||||
xcb_flush(s_xcbConnection);
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::SetSystemCursorState(SystemCursorState systemCursorState)
|
||||
{
|
||||
if (systemCursorState != m_systemCursorState)
|
||||
{
|
||||
m_systemCursorState = systemCursorState;
|
||||
|
||||
m_focusWindow = GetSystemCursorFocusWindow();
|
||||
|
||||
HandleCursorState(m_focusWindow, systemCursorState);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::HandleCursorState(xcb_window_t window, SystemCursorState systemCursorState)
|
||||
{
|
||||
bool confined = false, cursorShown = true;
|
||||
switch (systemCursorState)
|
||||
{
|
||||
case SystemCursorState::ConstrainedAndHidden:
|
||||
{
|
||||
//!< Constrained to the application's main window and hidden
|
||||
confined = true;
|
||||
cursorShown = false;
|
||||
}
|
||||
break;
|
||||
case SystemCursorState::ConstrainedAndVisible:
|
||||
{
|
||||
//!< Constrained to the application's main window and visible
|
||||
confined = true;
|
||||
}
|
||||
break;
|
||||
case SystemCursorState::UnconstrainedAndHidden:
|
||||
{
|
||||
//!< Free to move outside the main window but hidden while inside
|
||||
cursorShown = false;
|
||||
}
|
||||
break;
|
||||
case SystemCursorState::UnconstrainedAndVisible:
|
||||
{
|
||||
//!< Free to move outside the application's main window and visible
|
||||
}
|
||||
case SystemCursorState::Unknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// ATTN GetSystemCursorFocusWindow when getting out of the play in editor will return XCB_NONE
|
||||
// We need however the window id to reset the cursor.
|
||||
if (XCB_NONE == window && (confined || cursorShown))
|
||||
{
|
||||
// Reuse the previous window to reset states.
|
||||
window = m_prevConstraintWindow;
|
||||
m_prevConstraintWindow = XCB_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remember the window we used to modify cursor and barrier states.
|
||||
m_prevConstraintWindow = window;
|
||||
}
|
||||
|
||||
SetEnableXInput(!cursorShown);
|
||||
|
||||
CreateBarriers(window, confined);
|
||||
ShowCursor(window, cursorShown);
|
||||
}
|
||||
|
||||
SystemCursorState XcbInputDeviceMouse::GetSystemCursorState() const
|
||||
{
|
||||
return m_systemCursorState;
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::SetSystemCursorPositionNormalizedInternal(xcb_window_t window, AZ::Vector2 positionNormalized)
|
||||
{
|
||||
// TODO Basically not done at all. Added only the basic functions needed.
|
||||
const XcbStdFreePtr<xcb_get_geometry_reply_t> xkbGeometryReply{ xcb_get_geometry_reply(
|
||||
s_xcbConnection, xcb_get_geometry(s_xcbConnection, window), NULL) };
|
||||
|
||||
if (!xkbGeometryReply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int16_t x = static_cast<int16_t>(positionNormalized.GetX() * xkbGeometryReply->width);
|
||||
const int16_t y = static_cast<int16_t>(positionNormalized.GetY() * xkbGeometryReply->height);
|
||||
|
||||
xcb_warp_pointer(s_xcbConnection, XCB_NONE, window, 0, 0, 0, 0, x, y);
|
||||
|
||||
xcb_flush(s_xcbConnection);
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::SetSystemCursorPositionNormalized(AZ::Vector2 positionNormalized)
|
||||
{
|
||||
const xcb_window_t window = GetSystemCursorFocusWindow();
|
||||
if (XCB_NONE == window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetSystemCursorPositionNormalizedInternal(window, positionNormalized);
|
||||
}
|
||||
|
||||
AZ::Vector2 XcbInputDeviceMouse::GetSystemCursorPositionNormalizedInternal(xcb_window_t window) const
|
||||
{
|
||||
AZ::Vector2 position = AZ::Vector2::CreateZero();
|
||||
|
||||
const xcb_query_pointer_cookie_t pointer = xcb_query_pointer(s_xcbConnection, window);
|
||||
|
||||
const XcbStdFreePtr<xcb_query_pointer_reply_t> xkbQueryPointerReply{ xcb_query_pointer_reply(s_xcbConnection, pointer, NULL) };
|
||||
|
||||
if (!xkbQueryPointerReply)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
const XcbStdFreePtr<xcb_get_geometry_reply_t> xkbGeometryReply{ xcb_get_geometry_reply(
|
||||
s_xcbConnection, xcb_get_geometry(s_xcbConnection, window), NULL) };
|
||||
|
||||
if (!xkbGeometryReply)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
AZ_Assert(xkbGeometryReply->width != 0, "xkbGeometry response width must be non-zero. (%d)", xkbGeometryReply->width);
|
||||
const float normalizedCursorPostionX = static_cast<float>(xkbQueryPointerReply->win_x) / xkbGeometryReply->width;
|
||||
|
||||
AZ_Assert(xkbGeometryReply->height != 0, "xkbGeometry response height must be non-zero. (%d)", xkbGeometryReply->height);
|
||||
const float normalizedCursorPostionY = static_cast<float>(xkbQueryPointerReply->win_y) / xkbGeometryReply->height;
|
||||
|
||||
position = AZ::Vector2(normalizedCursorPostionX, normalizedCursorPostionY);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
AZ::Vector2 XcbInputDeviceMouse::GetSystemCursorPositionNormalized() const
|
||||
{
|
||||
const xcb_window_t window = GetSystemCursorFocusWindow();
|
||||
if (XCB_NONE == window)
|
||||
{
|
||||
return AZ::Vector2::CreateZero();
|
||||
}
|
||||
|
||||
return GetSystemCursorPositionNormalizedInternal(window);
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::TickInputDevice()
|
||||
{
|
||||
ProcessRawEventQueues();
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::ShowCursor(xcb_window_t window, bool show)
|
||||
{
|
||||
xcb_void_cookie_t cookie;
|
||||
if (show)
|
||||
{
|
||||
cookie = xcb_xfixes_show_cursor_checked(s_xcbConnection, window);
|
||||
}
|
||||
else
|
||||
{
|
||||
cookie = xcb_xfixes_hide_cursor_checked(s_xcbConnection, window);
|
||||
}
|
||||
|
||||
const XcbStdFreePtr<xcb_generic_error_t> xkbError{ xcb_request_check(s_xcbConnection, cookie) };
|
||||
|
||||
if (xkbError)
|
||||
{
|
||||
AZ_Warning("XcbInput", false, "ShowCursor failed: %d", xkbError->error_code);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ATTN In the following part we will when cursor gets hidden store the position of the cursor in screen space
|
||||
// not window space. We use that to re-position when showing the cursor again. Is this the correct
|
||||
// behavior?
|
||||
|
||||
const bool cursorWasHidden = !m_cursorShown;
|
||||
m_cursorShown = show;
|
||||
if (!m_cursorShown)
|
||||
{
|
||||
m_cursorHiddenPosition = GetSystemCursorPositionNormalizedInternal(s_xcbScreen->root);
|
||||
|
||||
SetSystemCursorPositionNormalized(AZ::Vector2(0.5f, 0.5f));
|
||||
}
|
||||
else if (cursorWasHidden)
|
||||
{
|
||||
SetSystemCursorPositionNormalizedInternal(s_xcbScreen->root, m_cursorHiddenPosition);
|
||||
}
|
||||
|
||||
xcb_flush(s_xcbConnection);
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::HandleButtonPressEvents(uint32_t detail, bool pressed)
|
||||
{
|
||||
bool isWheel;
|
||||
float wheelDirection;
|
||||
const auto* button = InputChannelFromMouseEvent(detail, isWheel, wheelDirection);
|
||||
if (button)
|
||||
{
|
||||
QueueRawButtonEvent(*button, pressed);
|
||||
}
|
||||
if (isWheel)
|
||||
{
|
||||
float axisValue = MAX_XI_WHEEL_SENSITIVITY * wheelDirection;
|
||||
QueueRawMovementEvent(InputDeviceMouse::Movement::Z, axisValue);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::HandlePointerMotionEvents(const xcb_generic_event_t* event)
|
||||
{
|
||||
const xcb_input_motion_event_t* mouseMotionEvent = reinterpret_cast<const xcb_input_motion_event_t*>(event);
|
||||
|
||||
m_systemCursorPosition[0] = mouseMotionEvent->event_x;
|
||||
m_systemCursorPosition[1] = mouseMotionEvent->event_y;
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::HandleRawInputEvents(const xcb_ge_generic_event_t* event)
|
||||
{
|
||||
const xcb_ge_generic_event_t* genericEvent = reinterpret_cast<const xcb_ge_generic_event_t*>(event);
|
||||
switch (genericEvent->event_type)
|
||||
{
|
||||
case XCB_INPUT_RAW_BUTTON_PRESS:
|
||||
{
|
||||
const xcb_input_raw_button_press_event_t* mouseButtonEvent =
|
||||
reinterpret_cast<const xcb_input_raw_button_press_event_t*>(event);
|
||||
HandleButtonPressEvents(mouseButtonEvent->detail, true);
|
||||
}
|
||||
break;
|
||||
case XCB_INPUT_RAW_BUTTON_RELEASE:
|
||||
{
|
||||
const xcb_input_raw_button_release_event_t* mouseButtonEvent =
|
||||
reinterpret_cast<const xcb_input_raw_button_release_event_t*>(event);
|
||||
HandleButtonPressEvents(mouseButtonEvent->detail, false);
|
||||
}
|
||||
break;
|
||||
case XCB_INPUT_RAW_MOTION:
|
||||
{
|
||||
const xcb_input_raw_motion_event_t* mouseMotionEvent = reinterpret_cast<const xcb_input_raw_motion_event_t*>(event);
|
||||
|
||||
int axisLen = xcb_input_raw_button_press_axisvalues_length(mouseMotionEvent);
|
||||
const xcb_input_fp3232_t* axisvalues = xcb_input_raw_button_press_axisvalues_raw(mouseMotionEvent);
|
||||
for (int i = 0; i < axisLen; ++i)
|
||||
{
|
||||
const float axisValue = fp3232ToFloat(axisvalues[i]);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
QueueRawMovementEvent(InputDeviceMouse::Movement::X, axisValue);
|
||||
break;
|
||||
case 1:
|
||||
QueueRawMovementEvent(InputDeviceMouse::Movement::Y, axisValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::PollSpecialEvents()
|
||||
{
|
||||
while (xcb_generic_event_t* genericEvent = xcb_poll_for_queued_event(s_xcbConnection))
|
||||
{
|
||||
// TODO Is the following correct? If we are showing the cursor, don't poll RAW Input events.
|
||||
switch (genericEvent->response_type & ~0x80)
|
||||
{
|
||||
case XCB_GE_GENERIC:
|
||||
{
|
||||
const xcb_ge_generic_event_t* geGenericEvent = reinterpret_cast<const xcb_ge_generic_event_t*>(genericEvent);
|
||||
|
||||
// Only handle raw inputs if we have focus.
|
||||
// Handle Raw Input events first.
|
||||
if ((geGenericEvent->event_type == XCB_INPUT_RAW_BUTTON_PRESS) ||
|
||||
(geGenericEvent->event_type == XCB_INPUT_RAW_BUTTON_RELEASE) ||
|
||||
(geGenericEvent->event_type == XCB_INPUT_RAW_MOTION))
|
||||
{
|
||||
HandleRawInputEvents(geGenericEvent);
|
||||
|
||||
free(genericEvent);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInputDeviceMouse::HandleXcbEvent(xcb_generic_event_t* event)
|
||||
{
|
||||
switch (event->response_type & ~0x80)
|
||||
{
|
||||
// QT5 is using by default XInput which means we do need to check for XCB_GE_GENERIC event to parse all mouse related events.
|
||||
case XCB_GE_GENERIC:
|
||||
{
|
||||
const xcb_ge_generic_event_t* genericEvent = reinterpret_cast<const xcb_ge_generic_event_t*>(event);
|
||||
|
||||
// Handling RAW Inputs here works in GameMode but not in Editor mode because QT is
|
||||
// not handling RAW input events and passing to.
|
||||
if (!m_cursorShown)
|
||||
{
|
||||
// Handle Raw Input events first.
|
||||
if ((genericEvent->event_type == XCB_INPUT_RAW_BUTTON_PRESS) ||
|
||||
(genericEvent->event_type == XCB_INPUT_RAW_BUTTON_RELEASE) || (genericEvent->event_type == XCB_INPUT_RAW_MOTION))
|
||||
{
|
||||
HandleRawInputEvents(genericEvent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (genericEvent->event_type)
|
||||
{
|
||||
case XCB_INPUT_BUTTON_PRESS:
|
||||
{
|
||||
const xcb_input_button_press_event_t* mouseButtonEvent =
|
||||
reinterpret_cast<const xcb_input_button_press_event_t*>(genericEvent);
|
||||
HandleButtonPressEvents(mouseButtonEvent->detail, true);
|
||||
}
|
||||
break;
|
||||
case XCB_INPUT_BUTTON_RELEASE:
|
||||
{
|
||||
const xcb_input_button_release_event_t* mouseButtonEvent =
|
||||
reinterpret_cast<const xcb_input_button_release_event_t*>(genericEvent);
|
||||
HandleButtonPressEvents(mouseButtonEvent->detail, false);
|
||||
}
|
||||
break;
|
||||
case XCB_INPUT_MOTION:
|
||||
{
|
||||
HandlePointerMotionEvents(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XCB_FOCUS_IN:
|
||||
{
|
||||
const xcb_focus_in_event_t* focusInEvent = reinterpret_cast<const xcb_focus_in_event_t*>(event);
|
||||
if (m_focusWindow != focusInEvent->event)
|
||||
{
|
||||
m_focusWindow = focusInEvent->event;
|
||||
HandleCursorState(m_focusWindow, m_systemCursorState);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XCB_FOCUS_OUT:
|
||||
{
|
||||
const xcb_focus_out_event_t* focusOutEvent = reinterpret_cast<const xcb_focus_out_event_t*>(event);
|
||||
HandleCursorState(focusOutEvent->event, SystemCursorState::UnconstrainedAndVisible);
|
||||
|
||||
ProcessRawEventQueues();
|
||||
ResetInputChannelStates();
|
||||
|
||||
m_focusWindow = XCB_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/XcbConnectionManager.h>
|
||||
#include <AzFramework/XcbEventHandler.h>
|
||||
#include <AzFramework/XcbInterface.h>
|
||||
|
||||
#include <xcb/xfixes.h>
|
||||
#include <xcb/xinput.h>
|
||||
|
||||
// The maximum number of raw input axis this mouse device supports.
|
||||
constexpr uint32_t MAX_XI_RAW_AXIS = 2;
|
||||
|
||||
// The sensitivity of the wheel.
|
||||
constexpr float MAX_XI_WHEEL_SENSITIVITY = 140.0f;
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class XcbInputDeviceMouse
|
||||
: public InputDeviceMouse::Implementation
|
||||
, public XcbEventHandlerBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(XcbInputDeviceMouse, AZ::SystemAllocator, 0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Constructor
|
||||
//! \param[in] inputDevice Reference to the input device being implemented
|
||||
XcbInputDeviceMouse(InputDeviceMouse& inputDevice);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! Destructor
|
||||
virtual ~XcbInputDeviceMouse();
|
||||
|
||||
static XcbInputDeviceMouse::Implementation* Create(InputDeviceMouse& inputDevice);
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::IsConnected
|
||||
bool IsConnected() const override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::SetSystemCursorState
|
||||
void SetSystemCursorState(SystemCursorState systemCursorState) override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::GetSystemCursorState
|
||||
SystemCursorState GetSystemCursorState() const override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::SetSystemCursorPositionNormalized
|
||||
void SetSystemCursorPositionNormalized(AZ::Vector2 positionNormalized) override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::GetSystemCursorPositionNormalized
|
||||
AZ::Vector2 GetSystemCursorPositionNormalized() const override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//! \ref AzFramework::InputDeviceMouse::Implementation::TickInputDevice
|
||||
void TickInputDevice() override;
|
||||
|
||||
//! This method is called by the Editor to accommodate some events with the Editor. Never called in Game mode.
|
||||
void PollSpecialEvents() override;
|
||||
|
||||
//! Handle X11 events.
|
||||
void HandleXcbEvent(xcb_generic_event_t* event) override;
|
||||
|
||||
//! Initialize XFixes extension. Used for barriers.
|
||||
static bool InitializeXFixes();
|
||||
|
||||
//! Initialize XInput extension. Used for raw input during confinement and showing/hiding the cursor.
|
||||
static bool InitializeXInput();
|
||||
|
||||
//! Enables/Disables XInput Raw Input events.
|
||||
void SetEnableXInput(bool enable);
|
||||
|
||||
//! Create barriers.
|
||||
void CreateBarriers(xcb_window_t window, bool create);
|
||||
|
||||
//! Helper function.
|
||||
void SystemCursorStateToLogic(SystemCursorState systemCursorState, bool& confined, bool& cursorShown);
|
||||
|
||||
//! Shows/Hides the cursor.
|
||||
void ShowCursor(xcb_window_t window, bool show);
|
||||
|
||||
//! Get the normalized cursor position. The coordinates returned are relative to the specified window.
|
||||
AZ::Vector2 GetSystemCursorPositionNormalizedInternal(xcb_window_t window) const;
|
||||
|
||||
//! Set the normalized cursor position. The normalized position will be relative to the specified window.
|
||||
void SetSystemCursorPositionNormalizedInternal(xcb_window_t window, AZ::Vector2 positionNormalized);
|
||||
|
||||
//! Handle button press/release events.
|
||||
void HandleButtonPressEvents(uint32_t detail, bool pressed);
|
||||
|
||||
//! Handle motion notify events.
|
||||
void HandlePointerMotionEvents(const xcb_generic_event_t* event);
|
||||
|
||||
//! Will set cursor states and confinement modes.
|
||||
void HandleCursorState(xcb_window_t window, SystemCursorState systemCursorState);
|
||||
|
||||
//! Will handle all raw input events.
|
||||
void HandleRawInputEvents(const xcb_ge_generic_event_t* event);
|
||||
|
||||
//! Convert XInput fp1616 to float.
|
||||
inline float fp1616ToFloat(xcb_input_fp1616_t value) const
|
||||
{
|
||||
return static_cast<float>((value >> 16) + (value & 0xffff) / 0xffff);
|
||||
}
|
||||
|
||||
//! Convert XInput fp3232 to float.
|
||||
inline float fp3232ToFloat(xcb_input_fp3232_t value) const
|
||||
{
|
||||
return static_cast<float>(value.integral) + static_cast<float>(value.frac / (float)(1ull << 32));
|
||||
}
|
||||
|
||||
const InputChannelId* InputChannelFromMouseEvent(xcb_button_t button, bool& isWheel, float& direction) const
|
||||
{
|
||||
isWheel = false;
|
||||
direction = 1.0f;
|
||||
switch (button)
|
||||
{
|
||||
case XCB_BUTTON_INDEX_1:
|
||||
return &InputDeviceMouse::Button::Left;
|
||||
case XCB_BUTTON_INDEX_2:
|
||||
return &InputDeviceMouse::Button::Right;
|
||||
case XCB_BUTTON_INDEX_3:
|
||||
return &InputDeviceMouse::Button::Middle;
|
||||
case XCB_BUTTON_INDEX_4:
|
||||
isWheel = true;
|
||||
direction = 1.0f;
|
||||
break;
|
||||
case XCB_BUTTON_INDEX_5:
|
||||
isWheel = true;
|
||||
direction = -1.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Barriers work only with positive values. We clamp here to zero.
|
||||
inline int16_t Clamp(int16_t value) const
|
||||
{
|
||||
return value < 0 ? 0 : value;
|
||||
}
|
||||
|
||||
private:
|
||||
//! The current system cursor state
|
||||
SystemCursorState m_systemCursorState;
|
||||
|
||||
//! The cursor position before it got hidden.
|
||||
AZ::Vector2 m_cursorHiddenPosition;
|
||||
|
||||
AZ::Vector2 m_systemCursorPositionNormalized;
|
||||
uint32_t m_systemCursorPosition[MAX_XI_RAW_AXIS];
|
||||
|
||||
static xcb_connection_t* s_xcbConnection;
|
||||
static xcb_screen_t* s_xcbScreen;
|
||||
|
||||
//! Will be true if the xfixes extension could be initialized.
|
||||
static bool m_xfixesInitialized;
|
||||
|
||||
//! Will be true if the xinput2 extension could be initialized.
|
||||
static bool m_xInputInitialized;
|
||||
|
||||
//! The window that had focus
|
||||
xcb_window_t m_prevConstraintWindow;
|
||||
|
||||
//! The current window that has focus
|
||||
xcb_window_t m_focusWindow;
|
||||
|
||||
//! Will be true if the cursor is shown else false.
|
||||
bool m_cursorShown;
|
||||
|
||||
struct XFixesBarrierProperty
|
||||
{
|
||||
xcb_xfixes_barrier_t id;
|
||||
uint32_t direction;
|
||||
int16_t x0, y0, x1, y1;
|
||||
};
|
||||
|
||||
//! Array that holds barrier information used to confine the cursor.
|
||||
std::vector<XFixesBarrierProperty> m_activeBarriers;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -8,25 +8,31 @@
|
||||
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzFramework/Windowing/NativeWindow.h>
|
||||
#include <AzFramework/XcbNativeWindow.h>
|
||||
#include <AzFramework/XcbConnectionManager.h>
|
||||
#include <AzFramework/XcbInterface.h>
|
||||
#include <AzFramework/XcbNativeWindow.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
[[maybe_unused]] const char XcbErrorWindow[] = "XcbNativeWindow";
|
||||
static constexpr uint8_t s_XcbFormatDataSize = 32; // Format indicator for xcb for client messages
|
||||
static constexpr uint16_t s_DefaultXcbWindowBorderWidth = 4; // The default border with in pixels if a border was specified
|
||||
static constexpr uint8_t s_XcbResponseTypeMask = 0x7f; // Mask to extract the specific event type from an xcb event
|
||||
static constexpr uint8_t s_XcbFormatDataSize = 32; // Format indicator for xcb for client messages
|
||||
static constexpr uint16_t s_DefaultXcbWindowBorderWidth = 4; // The default border with in pixels if a border was specified
|
||||
static constexpr uint8_t s_XcbResponseTypeMask = 0x7f; // Mask to extract the specific event type from an xcb event
|
||||
|
||||
#define _NET_WM_STATE_REMOVE 0l
|
||||
#define _NET_WM_STATE_ADD 1l
|
||||
#define _NET_WM_STATE_TOGGLE 2l
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
XcbNativeWindow::XcbNativeWindow()
|
||||
XcbNativeWindow::XcbNativeWindow()
|
||||
: NativeWindow::Implementation()
|
||||
, m_xcbConnection(nullptr)
|
||||
, m_xcbRootScreen(nullptr)
|
||||
, m_xcbWindow(XCB_NONE)
|
||||
{
|
||||
if (auto xcbConnectionManager = AzFramework::XcbConnectionManagerInterface::Get();
|
||||
xcbConnectionManager != nullptr)
|
||||
if (auto xcbConnectionManager = AzFramework::XcbConnectionManagerInterface::Get(); xcbConnectionManager != nullptr)
|
||||
{
|
||||
m_xcbConnection = xcbConnectionManager->GetXcbConnection();
|
||||
}
|
||||
@@ -34,89 +40,184 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
XcbNativeWindow::~XcbNativeWindow() = default;
|
||||
XcbNativeWindow::~XcbNativeWindow()
|
||||
{
|
||||
if (XCB_NONE != m_xcbWindow)
|
||||
{
|
||||
xcb_destroy_window(m_xcbConnection, m_xcbWindow);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void XcbNativeWindow::InitWindow(const AZStd::string& title,
|
||||
const WindowGeometry& geometry,
|
||||
const WindowStyleMasks& styleMasks)
|
||||
void XcbNativeWindow::InitWindow(const AZStd::string& title, const WindowGeometry& geometry, const WindowStyleMasks& styleMasks)
|
||||
{
|
||||
// Get the parent window
|
||||
// Get the parent window
|
||||
const xcb_setup_t* xcbSetup = xcb_get_setup(m_xcbConnection);
|
||||
xcb_screen_t* xcbRootScreen = xcb_setup_roots_iterator(xcbSetup).data;
|
||||
xcb_window_t xcbParentWindow = xcbRootScreen->root;
|
||||
m_xcbRootScreen = xcb_setup_roots_iterator(xcbSetup).data;
|
||||
xcb_window_t xcbParentWindow = m_xcbRootScreen->root;
|
||||
|
||||
// Create an XCB window from the connection
|
||||
m_xcbWindow = xcb_generate_id(m_xcbConnection);
|
||||
|
||||
uint16_t borderWidth = 0;
|
||||
const uint32_t mask = styleMasks.m_platformAgnosticStyleMask;
|
||||
if ((mask & WindowStyleMasks::WINDOW_STYLE_BORDERED) ||
|
||||
(mask & WindowStyleMasks::WINDOW_STYLE_RESIZEABLE))
|
||||
if ((mask & WindowStyleMasks::WINDOW_STYLE_BORDERED) || (mask & WindowStyleMasks::WINDOW_STYLE_RESIZEABLE))
|
||||
{
|
||||
borderWidth = s_DefaultXcbWindowBorderWidth;
|
||||
}
|
||||
|
||||
uint32_t eventMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
||||
|
||||
const uint32_t interestedEvents =
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||
| XCB_EVENT_MASK_BUTTON_PRESS
|
||||
| XCB_EVENT_MASK_BUTTON_RELEASE
|
||||
| XCB_EVENT_MASK_KEY_PRESS
|
||||
| XCB_EVENT_MASK_KEY_RELEASE
|
||||
| XCB_EVENT_MASK_POINTER_MOTION
|
||||
;
|
||||
uint32_t valueList[] = { xcbRootScreen->black_pixel,
|
||||
interestedEvents };
|
||||
|
||||
const uint32_t interestedEvents = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
||||
XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||
uint32_t valueList[] = { m_xcbRootScreen->black_pixel, interestedEvents };
|
||||
|
||||
xcb_void_cookie_t xcbCheckResult;
|
||||
|
||||
xcbCheckResult = xcb_create_window_checked(m_xcbConnection,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
m_xcbWindow,
|
||||
xcbParentWindow,
|
||||
aznumeric_cast<int16_t>(geometry.m_posX),
|
||||
aznumeric_cast<int16_t>(geometry.m_posY),
|
||||
aznumeric_cast<int16_t>(geometry.m_width),
|
||||
aznumeric_cast<int16_t>(geometry.m_height),
|
||||
borderWidth,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
xcbRootScreen->root_visual,
|
||||
eventMask,
|
||||
valueList);
|
||||
xcbCheckResult = xcb_create_window_checked(
|
||||
m_xcbConnection, XCB_COPY_FROM_PARENT, m_xcbWindow, xcbParentWindow, aznumeric_cast<int16_t>(geometry.m_posX),
|
||||
aznumeric_cast<int16_t>(geometry.m_posY), aznumeric_cast<int16_t>(geometry.m_width), aznumeric_cast<int16_t>(geometry.m_height),
|
||||
borderWidth, XCB_WINDOW_CLASS_INPUT_OUTPUT, m_xcbRootScreen->root_visual, eventMask, valueList);
|
||||
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to create xcb window.");
|
||||
|
||||
SetWindowTitle(title);
|
||||
|
||||
// Setup the window close event
|
||||
const static char* wmProtocolString = "WM_PROTOCOLS";
|
||||
|
||||
xcb_intern_atom_cookie_t cookieProtocol = xcb_intern_atom(m_xcbConnection, 1, strlen(wmProtocolString), wmProtocolString);
|
||||
xcb_intern_atom_reply_t* replyProtocol = xcb_intern_atom_reply(m_xcbConnection, cookieProtocol, nullptr);
|
||||
AZ_Error(XcbErrorWindow, replyProtocol != nullptr, "Unable to query xcb '%s' atom", wmProtocolString);
|
||||
m_xcbAtomProtocols = replyProtocol->atom;
|
||||
|
||||
const static char* wmDeleteWindowString = "WM_DELETE_WINDOW";
|
||||
xcb_intern_atom_cookie_t cookieDeleteWindow = xcb_intern_atom(m_xcbConnection, 0, strlen(wmDeleteWindowString), wmDeleteWindowString);
|
||||
xcb_intern_atom_reply_t* replyDeleteWindow = xcb_intern_atom_reply(m_xcbConnection, cookieDeleteWindow, nullptr);
|
||||
AZ_Error(XcbErrorWindow, replyDeleteWindow != nullptr, "Unable to query xcb '%s' atom", wmDeleteWindowString);
|
||||
m_xcbAtomDeleteWindow = replyDeleteWindow->atom;
|
||||
|
||||
xcbCheckResult = xcb_change_property_checked(m_xcbConnection,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
m_xcbWindow,
|
||||
m_xcbAtomProtocols,
|
||||
XCB_ATOM_ATOM,
|
||||
s_XcbFormatDataSize,
|
||||
1,
|
||||
&m_xcbAtomDeleteWindow);
|
||||
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to change the xcb atom property for WM_CLOSE event");
|
||||
|
||||
m_posX = geometry.m_posX;
|
||||
m_posY = geometry.m_posY;
|
||||
m_width = geometry.m_width;
|
||||
m_height = geometry.m_height;
|
||||
|
||||
InitializeAtoms();
|
||||
|
||||
xcb_client_message_event_t event;
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.type = _NET_REQUEST_FRAME_EXTENTS;
|
||||
event.window = m_xcbWindow;
|
||||
event.format = 32;
|
||||
event.sequence = 0;
|
||||
event.data.data32[0] = 0l;
|
||||
event.data.data32[1] = 0l;
|
||||
event.data.data32[2] = 0l;
|
||||
event.data.data32[3] = 0l;
|
||||
event.data.data32[4] = 0l;
|
||||
xcbCheckResult = xcb_send_event(
|
||||
m_xcbConnection, 1, m_xcbRootScreen->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
||||
(const char*)&event);
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set _NET_REQUEST_FRAME_EXTENTS");
|
||||
|
||||
// The WM will be able to kill the application if it gets unresponsive.
|
||||
int32_t pid = getpid();
|
||||
xcb_change_property(m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
|
||||
|
||||
xcb_flush(m_xcbConnection);
|
||||
}
|
||||
|
||||
xcb_atom_t XcbNativeWindow::GetAtom(const char* atomName)
|
||||
{
|
||||
xcb_intern_atom_cookie_t intern_atom_cookie = xcb_intern_atom(m_xcbConnection, 0, strlen(atomName), atomName);
|
||||
XcbStdFreePtr<xcb_intern_atom_reply_t> xkbinternAtom{ xcb_intern_atom_reply(m_xcbConnection, intern_atom_cookie, NULL) };
|
||||
|
||||
if (!xkbinternAtom)
|
||||
{
|
||||
AZ_Error(XcbErrorWindow, xkbinternAtom != nullptr, "Unable to query xcb '%s' atom", atomName);
|
||||
return XCB_NONE;
|
||||
}
|
||||
|
||||
return xkbinternAtom->atom;
|
||||
}
|
||||
|
||||
int XcbNativeWindow::SetAtom(xcb_window_t window, xcb_atom_t atom, xcb_atom_t type, size_t len, void* data)
|
||||
{
|
||||
xcb_void_cookie_t cookie = xcb_change_property_checked(m_xcbConnection, XCB_PROP_MODE_REPLACE, window, atom, type, 32, len, data);
|
||||
XcbStdFreePtr<xcb_generic_error_t> xkbError{ xcb_request_check(m_xcbConnection, cookie) };
|
||||
|
||||
if (!xkbError)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return xkbError->error_code;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void XcbNativeWindow::InitializeAtoms()
|
||||
{
|
||||
AZStd::vector<xcb_atom_t> Atoms;
|
||||
|
||||
_NET_ACTIVE_WINDOW = GetAtom("_NET_ACTIVE_WINDOW");
|
||||
_NET_WM_BYPASS_COMPOSITOR = GetAtom("_NET_WM_BYPASS_COMPOSITOR");
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Handle all WM Protocols atoms.
|
||||
//
|
||||
|
||||
WM_PROTOCOLS = GetAtom("WM_PROTOCOLS");
|
||||
|
||||
// This atom is used to close a window. Emitted when user clicks the close button.
|
||||
WM_DELETE_WINDOW = GetAtom("WM_DELETE_WINDOW");
|
||||
|
||||
Atoms.push_back(WM_DELETE_WINDOW);
|
||||
|
||||
xcb_change_property(
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, WM_PROTOCOLS, XCB_ATOM_ATOM, 32, Atoms.size(), Atoms.data());
|
||||
|
||||
xcb_flush(m_xcbConnection);
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Handle all WM State atoms.
|
||||
//
|
||||
|
||||
_NET_WM_STATE = GetAtom("_NET_WM_STATE");
|
||||
_NET_WM_STATE_FULLSCREEN = GetAtom("_NET_WM_STATE_FULLSCREEN");
|
||||
_NET_WM_STATE_MAXIMIZED_VERT = GetAtom("_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
_NET_WM_STATE_MAXIMIZED_HORZ = GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
_NET_MOVERESIZE_WINDOW = GetAtom("_NET_MOVERESIZE_WINDOW");
|
||||
_NET_REQUEST_FRAME_EXTENTS = GetAtom("_NET_REQUEST_FRAME_EXTENTS");
|
||||
_NET_FRAME_EXTENTS = GetAtom("_NET_FRAME_EXTENTS");
|
||||
_NET_WM_PID = GetAtom("_NET_WM_PID");
|
||||
}
|
||||
|
||||
void XcbNativeWindow::GetWMStates()
|
||||
{
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(m_xcbConnection, 0, m_xcbWindow, _NET_WM_STATE, XCB_ATOM_ATOM, 0, 1024);
|
||||
|
||||
xcb_generic_error_t* error = nullptr;
|
||||
XcbStdFreePtr<xcb_get_property_reply_t> xkbGetPropertyReply{ xcb_get_property_reply(m_xcbConnection, cookie, &error) };
|
||||
|
||||
if (!xkbGetPropertyReply || error || !((xkbGetPropertyReply->format == 32) && (xkbGetPropertyReply->type == XCB_ATOM_ATOM)))
|
||||
{
|
||||
AZ_Warning("ApplicationLinux", false, "Acquiring _NET_WM_STATE information from the WM failed.");
|
||||
|
||||
if (error)
|
||||
{
|
||||
AZ_TracePrintf("Error", "Error code %d", error->error_code);
|
||||
free(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_fullscreenState = false;
|
||||
m_horizontalyMaximized = false;
|
||||
m_verticallyMaximized = false;
|
||||
|
||||
const xcb_atom_t* states = static_cast<const xcb_atom_t*>(xcb_get_property_value(xkbGetPropertyReply.get()));
|
||||
for (int i = 0; i < xkbGetPropertyReply->length; i++)
|
||||
{
|
||||
if (states[i] == _NET_WM_STATE_FULLSCREEN)
|
||||
{
|
||||
m_fullscreenState = true;
|
||||
}
|
||||
else if (states[i] == _NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
m_horizontalyMaximized = true;
|
||||
}
|
||||
else if (states[i] == _NET_WM_STATE_MAXIMIZED_VERT)
|
||||
{
|
||||
m_verticallyMaximized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -146,7 +247,7 @@ namespace AzFramework
|
||||
xcb_flush(m_xcbConnection);
|
||||
}
|
||||
XcbEventHandlerBus::Handler::BusDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
NativeWindowHandle XcbNativeWindow::GetWindowHandle() const
|
||||
@@ -158,14 +259,9 @@ namespace AzFramework
|
||||
void XcbNativeWindow::SetWindowTitle(const AZStd::string& title)
|
||||
{
|
||||
xcb_void_cookie_t xcbCheckResult;
|
||||
xcbCheckResult = xcb_change_property(m_xcbConnection,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
m_xcbWindow,
|
||||
XCB_ATOM_WM_NAME,
|
||||
XCB_ATOM_STRING,
|
||||
8,
|
||||
static_cast<uint32_t>(title.size()),
|
||||
title.c_str());
|
||||
xcbCheckResult = xcb_change_property(
|
||||
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, static_cast<uint32_t>(title.size()),
|
||||
title.c_str());
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set window title.");
|
||||
}
|
||||
|
||||
@@ -175,7 +271,7 @@ namespace AzFramework
|
||||
const uint32_t values[] = { clientAreaSize.m_width, clientAreaSize.m_height };
|
||||
|
||||
xcb_configure_window(m_xcbConnection, m_xcbWindow, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
|
||||
|
||||
|
||||
m_width = clientAreaSize.m_width;
|
||||
m_height = clientAreaSize.m_height;
|
||||
}
|
||||
@@ -185,16 +281,77 @@ namespace AzFramework
|
||||
{
|
||||
// [GFX TODO][GHI - 2678]
|
||||
// Using 60 for now until proper support is added
|
||||
|
||||
return 60;
|
||||
}
|
||||
|
||||
bool XcbNativeWindow::GetFullScreenState() const
|
||||
{
|
||||
return m_fullscreenState;
|
||||
}
|
||||
|
||||
void XcbNativeWindow::SetFullScreenState(bool fullScreenState)
|
||||
{
|
||||
// TODO This is a pretty basic full-screen implementation using WM's _NET_WM_STATE_FULLSCREEN state.
|
||||
// Do we have to provide also the old way?
|
||||
|
||||
GetWMStates();
|
||||
|
||||
xcb_client_message_event_t event;
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.type = _NET_WM_STATE;
|
||||
event.window = m_xcbWindow;
|
||||
event.format = 32;
|
||||
event.sequence = 0;
|
||||
event.data.data32[0] = fullScreenState ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||
event.data.data32[1] = _NET_WM_STATE_FULLSCREEN;
|
||||
event.data.data32[2] = 0;
|
||||
event.data.data32[3] = 1;
|
||||
event.data.data32[4] = 0;
|
||||
xcb_void_cookie_t xcbCheckResult = xcb_send_event(
|
||||
m_xcbConnection, 1, m_xcbRootScreen->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
||||
(const char*)&event);
|
||||
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set _NET_WM_STATE_FULLSCREEN");
|
||||
|
||||
// Also try to disable/enable the compositor if possible. Might help in some cases.
|
||||
const long _NET_WM_BYPASS_COMPOSITOR_HINT_ON = m_fullscreenState ? 1 : 0;
|
||||
SetAtom(m_xcbWindow, _NET_WM_BYPASS_COMPOSITOR, XCB_ATOM_CARDINAL, 32, (char*)&_NET_WM_BYPASS_COMPOSITOR_HINT_ON);
|
||||
|
||||
if (!fullScreenState)
|
||||
{
|
||||
if (m_horizontalyMaximized || m_verticallyMaximized)
|
||||
{
|
||||
printf("Remove maximized state.\n");
|
||||
xcb_client_message_event_t event;
|
||||
event.response_type = XCB_CLIENT_MESSAGE;
|
||||
event.type = _NET_WM_STATE;
|
||||
event.window = m_xcbWindow;
|
||||
event.format = 32;
|
||||
event.sequence = 0;
|
||||
event.data.data32[0] = _NET_WM_STATE_MAXIMIZED_VERT;
|
||||
event.data.data32[1] = _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
event.data.data32[2] = 0;
|
||||
event.data.data32[3] = 0;
|
||||
event.data.data32[4] = 0;
|
||||
xcb_void_cookie_t xcbCheckResult = xcb_send_event(
|
||||
m_xcbConnection, 1, m_xcbRootScreen->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
||||
(const char*)&event);
|
||||
AZ_Assert(
|
||||
ValidateXcbResult(xcbCheckResult), "Failed to remove _NET_WM_STATE_MAXIMIZED_VERT | _NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
}
|
||||
}
|
||||
|
||||
xcb_flush(m_xcbConnection);
|
||||
m_fullscreenState = fullScreenState;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool XcbNativeWindow::ValidateXcbResult(xcb_void_cookie_t cookie)
|
||||
{
|
||||
bool result = true;
|
||||
if (xcb_generic_error_t* error = xcb_request_check(m_xcbConnection, cookie))
|
||||
{
|
||||
AZ_TracePrintf("Error","Error code %d", error->error_code);
|
||||
AZ_TracePrintf("Error", "Error code %d", error->error_code);
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
@@ -205,20 +362,20 @@ namespace AzFramework
|
||||
{
|
||||
switch (event->response_type & s_XcbResponseTypeMask)
|
||||
{
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
{
|
||||
xcb_configure_notify_event_t* cne = reinterpret_cast<xcb_configure_notify_event_t*>(event);
|
||||
WindowSizeChanged(aznumeric_cast<uint32_t>(cne->width),
|
||||
aznumeric_cast<uint32_t>(cne->height));
|
||||
|
||||
if ((cne->width != m_width) || (cne->height != m_height))
|
||||
{
|
||||
WindowSizeChanged(aznumeric_cast<uint32_t>(cne->width), aznumeric_cast<uint32_t>(cne->height));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_CLIENT_MESSAGE:
|
||||
case XCB_CLIENT_MESSAGE:
|
||||
{
|
||||
xcb_client_message_event_t* cme = reinterpret_cast<xcb_client_message_event_t*>(event);
|
||||
if ((cme->type == m_xcbAtomProtocols) &&
|
||||
(cme->format == s_XcbFormatDataSize) &&
|
||||
(cme->data.data32[0] == m_xcbAtomDeleteWindow))
|
||||
|
||||
if ((cme->type == WM_PROTOCOLS) && (cme->format == s_XcbFormatDataSize) && (cme->data.data32[0] == WM_DELETE_WINDOW))
|
||||
{
|
||||
Deactivate();
|
||||
|
||||
@@ -239,7 +396,8 @@ namespace AzFramework
|
||||
|
||||
if (m_activated)
|
||||
{
|
||||
WindowNotificationBus::Event(reinterpret_cast<NativeWindowHandle>(m_xcbWindow), &WindowNotificationBus::Events::OnWindowResized, width, height);
|
||||
WindowNotificationBus::Event(
|
||||
reinterpret_cast<NativeWindowHandle>(m_xcbWindow), &WindowNotificationBus::Events::OnWindowResized, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,16 @@ namespace AzFramework
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NativeWindow::Implementation
|
||||
void InitWindow(const AZStd::string& title,
|
||||
const WindowGeometry& geometry,
|
||||
const WindowStyleMasks& styleMasks) override;
|
||||
void InitWindow(const AZStd::string& title, const WindowGeometry& geometry, const WindowStyleMasks& styleMasks) override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
NativeWindowHandle GetWindowHandle() const override;
|
||||
void SetWindowTitle(const AZStd::string& title) override;
|
||||
void ResizeClientArea(WindowSize clientAreaSize) override;
|
||||
uint32_t GetDisplayRefreshRate() const override;
|
||||
uint32_t GetDisplayRefreshRate() const override;
|
||||
|
||||
bool GetFullScreenState() const override;
|
||||
void SetFullScreenState(bool fullScreenState) override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// XcbEventHandlerBus::Handler
|
||||
@@ -44,10 +45,46 @@ namespace AzFramework
|
||||
private:
|
||||
bool ValidateXcbResult(xcb_void_cookie_t cookie);
|
||||
void WindowSizeChanged(const uint32_t width, const uint32_t height);
|
||||
int SetAtom(xcb_window_t window, xcb_atom_t atom, xcb_atom_t type, size_t len, void* data);
|
||||
|
||||
xcb_connection_t* m_xcbConnection = nullptr;
|
||||
xcb_window_t m_xcbWindow = 0;
|
||||
xcb_atom_t m_xcbAtomProtocols;
|
||||
xcb_atom_t m_xcbAtomDeleteWindow;
|
||||
// Initialize one atom.
|
||||
xcb_atom_t GetAtom(const char* atomName);
|
||||
|
||||
// Initialize all used atoms.
|
||||
void InitializeAtoms();
|
||||
void GetWMStates();
|
||||
|
||||
xcb_connection_t* m_xcbConnection = nullptr;
|
||||
xcb_screen_t* m_xcbRootScreen = nullptr;
|
||||
xcb_window_t m_xcbWindow = 0;
|
||||
int32_t m_posX;
|
||||
int32_t m_posY;
|
||||
bool m_fullscreenState = false;
|
||||
bool m_horizontalyMaximized = false;
|
||||
bool m_verticallyMaximized = false;
|
||||
|
||||
// Use exact atom names for easy readability and usage.
|
||||
xcb_atom_t WM_PROTOCOLS;
|
||||
xcb_atom_t WM_DELETE_WINDOW;
|
||||
// This atom is used to activate a window.
|
||||
xcb_atom_t _NET_ACTIVE_WINDOW;
|
||||
// This atom is use to bypass a compositor. Used during fullscreen mode.
|
||||
xcb_atom_t _NET_WM_BYPASS_COMPOSITOR;
|
||||
// This atom is used to change the state of a window using the WM.
|
||||
xcb_atom_t _NET_WM_STATE;
|
||||
// This atom is used to enable/disable fullscreen mode of a window.
|
||||
xcb_atom_t _NET_WM_STATE_FULLSCREEN;
|
||||
// This atom is used to extend the window to max vertically.
|
||||
xcb_atom_t _NET_WM_STATE_MAXIMIZED_VERT;
|
||||
// This atom is used to extend the window to max horizontally.
|
||||
xcb_atom_t _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
// This atom is used to position and resize a window.
|
||||
xcb_atom_t _NET_MOVERESIZE_WINDOW;
|
||||
// This atom is used to request the extent of the window.
|
||||
xcb_atom_t _NET_REQUEST_FRAME_EXTENTS;
|
||||
// This atom is used to identify the reply event for _NET_REQUEST_FRAME_EXTENTS
|
||||
xcb_atom_t _NET_FRAME_EXTENTS;
|
||||
// This atom is used to allow WM to kill app if not responsive anymore
|
||||
xcb_atom_t _NET_WM_PID;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -12,6 +12,8 @@ set(FILES
|
||||
AzFramework/XcbConnectionManager.h
|
||||
AzFramework/XcbInputDeviceKeyboard.cpp
|
||||
AzFramework/XcbInputDeviceKeyboard.h
|
||||
AzFramework/XcbInputDeviceMouse.cpp
|
||||
AzFramework/XcbInputDeviceMouse.h
|
||||
AzFramework/XcbInterface.h
|
||||
AzFramework/XcbNativeWindow.cpp
|
||||
AzFramework/XcbNativeWindow.h
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
#include <AzFramework/XcbInputDeviceMouse.h>
|
||||
#endif
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
InputDeviceMouse::Implementation* InputDeviceMouse::Implementation::Create(InputDeviceMouse& inputDevice)
|
||||
{
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
return XcbInputDeviceMouse::Create(inputDevice);
|
||||
#elif PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND
|
||||
#error "Linux Window Manager Wayland not supported."
|
||||
return nullptr;
|
||||
#else
|
||||
#error "Linux Window Manager not recognized."
|
||||
return nullptr;
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -22,8 +22,10 @@ if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
PRIVATE
|
||||
3rdParty::X11::xcb
|
||||
3rdParty::X11::xcb_xkb
|
||||
3rdParty::X11::xcb_xfixes
|
||||
3rdParty::X11::xkbcommon
|
||||
3rdParty::X11::xkbcommon_X11
|
||||
xcb-xinput
|
||||
)
|
||||
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "wayland")
|
||||
|
||||
@@ -22,8 +22,8 @@ set(FILES
|
||||
AzFramework/Windowing/NativeWindow_Linux.cpp
|
||||
../Common/Unimplemented/AzFramework/Input/Devices/Gamepad/InputDeviceGamepad_Unimplemented.cpp
|
||||
AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Linux.cpp
|
||||
AzFramework/Input/Devices/Mouse/InputDeviceMouse_Linux.cpp
|
||||
../Common/Unimplemented/AzFramework/Input/Devices/Motion/InputDeviceMotion_Unimplemented.cpp
|
||||
../Common/Unimplemented/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Unimplemented.cpp
|
||||
../Common/Unimplemented/AzFramework/Input/Devices/Touch/InputDeviceTouch_Unimplemented.cpp
|
||||
AzFramework/Input/User/LocalUserId_Platform.h
|
||||
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
|
||||
|
||||
@@ -569,11 +569,12 @@ namespace UnitTest
|
||||
FillSpawnable(NumEntities);
|
||||
CreateEntityReferences(refScheme);
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback =
|
||||
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
AZ_UNUSED(refScheme);
|
||||
AZ_UNUSED(NumEntities);
|
||||
ValidateEntityReferences(refScheme, NumEntities, entities);
|
||||
};
|
||||
|
||||
@@ -591,11 +592,12 @@ namespace UnitTest
|
||||
FillSpawnable(NumEntities);
|
||||
CreateEntityReferences(refScheme);
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback =
|
||||
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
AZ_UNUSED(refScheme);
|
||||
AZ_UNUSED(NumEntities);
|
||||
ValidateEntityReferences(refScheme, NumEntities, entities);
|
||||
};
|
||||
|
||||
@@ -720,11 +722,12 @@ namespace UnitTest
|
||||
FillSpawnable(NumEntities);
|
||||
CreateEntityReferences(refScheme);
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
|
||||
// capture. Newer versions issue unused warning
|
||||
auto callback =
|
||||
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
AZ_UNUSED(refScheme);
|
||||
AZ_UNUSED(NumEntities);
|
||||
ValidateEntityReferences(refScheme, NumEntities, entities);
|
||||
};
|
||||
|
||||
|
||||
@@ -90,19 +90,16 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
//! Filter out integration tests from the test run
|
||||
void excludeIntegTests()
|
||||
{
|
||||
AddExcludeFilter("INTEG_*");
|
||||
AddExcludeFilter("Integ_*");
|
||||
}
|
||||
|
||||
void ApplyGlobalParameters(int* argc, char** argv)
|
||||
{
|
||||
// this is a hook that can be used to apply any other global non-google parameters
|
||||
// that we use.
|
||||
// this is a hook that can be used to apply any other global parameters that we use.
|
||||
AZ_UNUSED(argc);
|
||||
AZ_UNUSED(argv);
|
||||
|
||||
// Disable gtest catching unhandled exceptions, instead, AzTestRunner will do it through:
|
||||
// AZ::Debug::Trace::HandleExceptions(true). This gives us a stack trace when the exception
|
||||
// is thrown (googletest does not).
|
||||
testing::FLAGS_gtest_catch_exceptions = false;
|
||||
}
|
||||
|
||||
//! Print out parameters that are not used by the framework
|
||||
@@ -160,7 +157,6 @@ namespace AZ
|
||||
}
|
||||
|
||||
::testing::InitGoogleMock(&argc, argv);
|
||||
AZ::Test::excludeIntegTests();
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv);
|
||||
AZ::Test::printUnusedParametersWarning(argc, argv);
|
||||
AZ::Test::addTestEnvironments(m_envs);
|
||||
@@ -281,7 +277,6 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Test::excludeIntegTests();
|
||||
AZ::Test::printUnusedParametersWarning(argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
@@ -104,7 +104,6 @@ namespace AZ
|
||||
|
||||
void addTestEnvironment(ITestEnvironment* env);
|
||||
void addTestEnvironments(std::vector<ITestEnvironment*> envs);
|
||||
void excludeIntegTests();
|
||||
|
||||
//! A hook that can be used to read any other misc parameters and remove them before google sees them.
|
||||
//! Note that this modifies argc and argv to delete the parameters it consumes.
|
||||
@@ -266,7 +265,6 @@ namespace AZ
|
||||
::testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); \
|
||||
listeners.Append(new AZ::Test::OutputEventListener); \
|
||||
} \
|
||||
AZ::Test::excludeIntegTests(); \
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv); \
|
||||
AZ::Test::printUnusedParametersWarning(argc, argv); \
|
||||
AZ::Test::addTestEnvironments({TEST_ENV}); \
|
||||
|
||||
+6
-4
@@ -43,8 +43,7 @@ namespace AzToolsFramework
|
||||
};
|
||||
|
||||
//! Provides a bus to notify when the different editor modes are entered/exit.
|
||||
class ViewportEditorModeNotifications
|
||||
: public AZ::EBusTraits
|
||||
class ViewportEditorModeNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -58,14 +57,17 @@ namespace AzToolsFramework
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
//! 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)
|
||||
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)
|
||||
virtual void OnEditorModeDeactivated(
|
||||
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using ViewportEditorModeNotificationsBus = AZ::EBus<ViewportEditorModeNotifications>;
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+52
@@ -137,6 +137,7 @@ namespace AzToolsFramework
|
||||
if (componentTypeIt == m_activeComponentTypes.end())
|
||||
{
|
||||
m_activeComponentTypes.push_back(componentType);
|
||||
m_viewportUiHandlers.emplace_back(componentType);
|
||||
}
|
||||
|
||||
// see if we already have a ComponentModeBuilder for the specific component on this entity
|
||||
@@ -225,6 +226,7 @@ namespace AzToolsFramework
|
||||
if (!m_entitiesAndComponentModes.empty())
|
||||
{
|
||||
RefreshActions();
|
||||
PopulateViewportUi();
|
||||
}
|
||||
|
||||
// if entering ComponentMode not as an undo/redo step (an action was
|
||||
@@ -285,6 +287,10 @@ namespace AzToolsFramework
|
||||
componentModeCommand.release();
|
||||
}
|
||||
|
||||
// remove the component mode viewport border
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
|
||||
|
||||
// notify listeners the editor has left ComponentMode - listeners may
|
||||
// wish to modify state to indicate this (e.g. appearance, functionality etc.)
|
||||
m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Component);
|
||||
@@ -301,6 +307,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
m_entitiesAndComponentModeBuilders.clear();
|
||||
m_activeComponentTypes.clear();
|
||||
m_viewportUiHandlers.clear();
|
||||
|
||||
m_componentMode = false;
|
||||
m_selectedComponentModeIndex = 0;
|
||||
@@ -385,6 +392,24 @@ namespace AzToolsFramework
|
||||
return m_activeComponentTypes.size() > 1;
|
||||
}
|
||||
|
||||
static ComponentModeViewportUi* FindViewportUiHandlerForType(
|
||||
AZStd::vector<ComponentModeViewportUi>& viewportUiHandlers, const AZ::Uuid& componentType)
|
||||
{
|
||||
auto handler = AZStd::find_if(
|
||||
viewportUiHandlers.begin(), viewportUiHandlers.end(),
|
||||
[componentType](const ComponentModeViewportUi& handler)
|
||||
{
|
||||
return handler.GetComponentType() == componentType;
|
||||
});
|
||||
|
||||
if (handler == viewportUiHandlers.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool ComponentModeCollection::ActiveComponentModeChanged(const AZ::Uuid& previousComponentType)
|
||||
{
|
||||
if (m_activeComponentTypes[m_selectedComponentModeIndex] != previousComponentType)
|
||||
@@ -410,6 +435,20 @@ namespace AzToolsFramework
|
||||
// replace the current component mode by invoking the builder
|
||||
// for the new 'active' component mode
|
||||
componentMode.m_componentMode = componentModeBuilder->m_componentModeBuilder();
|
||||
|
||||
// populate the viewport UI with the new component mode
|
||||
PopulateViewportUi();
|
||||
|
||||
// set the appropriate viewportUiHandler to active
|
||||
if (auto viewportUiHandler =
|
||||
FindViewportUiHandlerForType(m_viewportUiHandlers, m_activeComponentTypes[m_selectedComponentModeIndex]))
|
||||
{
|
||||
viewportUiHandler->SetComponentModeViewportUiActive(true);
|
||||
}
|
||||
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
|
||||
componentMode.m_componentMode->GetComponentModeName().c_str());
|
||||
}
|
||||
|
||||
RefreshActions();
|
||||
@@ -519,5 +558,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentModeCollection::PopulateViewportUi()
|
||||
{
|
||||
// update viewport UI for new component type
|
||||
if (m_selectedComponentModeIndex < m_activeComponentTypes.size())
|
||||
{
|
||||
// iterate over all entities and their active Component Mode, populate viewport UI for the new mode
|
||||
for (auto& entityAndComponentMode : m_entitiesAndComponentModes)
|
||||
{
|
||||
// build viewport UI based on current state
|
||||
entityAndComponentMode.m_componentMode->PopulateViewportUi();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace ComponentModeFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ namespace AzToolsFramework
|
||||
GetEntityComponentIdPair(), elementIdsToDisplay);
|
||||
// create the component mode border with the specific name for this component mode
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateComponentModeBorder,
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
|
||||
GetComponentModeName());
|
||||
// set the EntityComponentId for this ComponentMode to active in the ComponentModeViewportUi system
|
||||
ComponentModeViewportUiRequestBus::Event(
|
||||
|
||||
+5
-6
@@ -71,12 +71,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::EntityId previousFocusEntityId = m_focusRoot;
|
||||
m_focusRoot = entityId;
|
||||
FocusModeNotificationBus::Broadcast(&FocusModeNotifications::OnEditorFocusChanged, previousFocusEntityId, m_focusRoot);
|
||||
|
||||
if (auto tracker = AZ::Interface<ViewportEditorModeTrackerInterface>::Get();
|
||||
tracker != nullptr)
|
||||
if (auto tracker = AZ::Interface<ViewportEditorModeTrackerInterface>::Get())
|
||||
{
|
||||
if (!m_focusRoot.IsValid() && entityId.IsValid())
|
||||
{
|
||||
@@ -87,6 +82,10 @@ namespace AzToolsFramework
|
||||
tracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Focus);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::EntityId previousFocusEntityId = m_focusRoot;
|
||||
m_focusRoot = entityId;
|
||||
FocusModeNotificationBus::Broadcast(&FocusModeNotifications::OnEditorFocusChanged, previousFocusEntityId, m_focusRoot);
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::ClearFocusRoot([[maybe_unused]] AzFramework::EntityContextId entityContextId)
|
||||
|
||||
@@ -1052,10 +1052,10 @@ namespace AzToolsFramework
|
||||
DuplicateNestedEntitiesInInstance(commonOwningInstance->get(),
|
||||
entities, instanceDomAfter, duplicatedEntityAndInstanceIds, duplicateEntityAliasMap);
|
||||
|
||||
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication");
|
||||
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication", false);
|
||||
command->SetParent(undoBatch.GetUndoBatch());
|
||||
command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId());
|
||||
command->RedoBatched();
|
||||
command->Redo();
|
||||
|
||||
DuplicateNestedInstancesInInstance(commonOwningInstance->get(),
|
||||
instances, instanceDomAfter, duplicatedEntityAndInstanceIds, newInstanceAliasToOldInstanceMap);
|
||||
@@ -1323,7 +1323,7 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabDom instanceDomAfter;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, parentInstance);
|
||||
|
||||
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment");
|
||||
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment", false);
|
||||
command->Capture(instanceDomBefore, instanceDomAfter, parentTemplateId);
|
||||
command->SetParent(undoBatch.GetUndoBatch());
|
||||
{
|
||||
|
||||
+26
-2
@@ -6,11 +6,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <API/ToolsApplicationAPI.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <Prefab/PrefabSystemScriptingHandler.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <Prefab/EditorPrefabComponent.h>
|
||||
#include <ToolsComponents/TransformComponent.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab
|
||||
{
|
||||
@@ -61,9 +64,30 @@ namespace AzToolsFramework::Prefab
|
||||
entities.push_back(entity);
|
||||
}
|
||||
}
|
||||
|
||||
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)));
|
||||
|
||||
bool result = false;
|
||||
[[maybe_unused]] AZ::EntityId commonRoot;
|
||||
EntityList topLevelEntities;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(result, &AzToolsFramework::ToolsApplicationRequestBus::Events::FindCommonRootInactive,
|
||||
entities, commonRoot, &topLevelEntities);
|
||||
|
||||
auto containerEntity = AZStd::make_unique<AZ::Entity>();
|
||||
containerEntity->CreateComponent<Prefab::EditorPrefabComponent>();
|
||||
|
||||
for (AZ::Entity* entity : topLevelEntities)
|
||||
{
|
||||
AzToolsFramework::Components::TransformComponent* transformComponent =
|
||||
entity->FindComponent<AzToolsFramework::Components::TransformComponent>();
|
||||
|
||||
if (transformComponent)
|
||||
{
|
||||
transformComponent->SetParent(containerEntity->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(
|
||||
entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)), AZStd::move(containerEntity));
|
||||
|
||||
if (!prefab)
|
||||
{
|
||||
AZ_Error("PrefabSystemComponenent", false, "Failed to create prefab %s", filePath.c_str());
|
||||
|
||||
@@ -17,17 +17,16 @@ namespace AzToolsFramework
|
||||
{
|
||||
PrefabUndoBase::PrefabUndoBase(const AZStd::string& undoOperationName)
|
||||
: UndoSystem::URSequencePoint(undoOperationName)
|
||||
, m_changed(true)
|
||||
, m_templateId(InvalidTemplateId)
|
||||
{
|
||||
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
|
||||
AZ_Assert(m_instanceToTemplateInterface, "Failed to grab instance to template interface");
|
||||
}
|
||||
|
||||
//PrefabInstanceUndo
|
||||
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName)
|
||||
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation)
|
||||
: PrefabUndoBase(undoOperationName)
|
||||
{
|
||||
m_useImmediatePropagation = useImmediatePropagation;
|
||||
}
|
||||
|
||||
void PrefabUndoInstance::Capture(
|
||||
@@ -43,17 +42,12 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoInstance::Undo()
|
||||
{
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, true);
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, m_useImmediatePropagation);
|
||||
}
|
||||
|
||||
void PrefabUndoInstance::Redo()
|
||||
{
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, true);
|
||||
}
|
||||
|
||||
void PrefabUndoInstance::RedoBatched()
|
||||
{
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId);
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, m_useImmediatePropagation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,14 +29,15 @@ namespace AzToolsFramework
|
||||
bool Changed() const override { return m_changed; }
|
||||
|
||||
protected:
|
||||
TemplateId m_templateId;
|
||||
TemplateId m_templateId = InvalidTemplateId;
|
||||
|
||||
PrefabDom m_redoPatch;
|
||||
PrefabDom m_undoPatch;
|
||||
|
||||
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
|
||||
|
||||
bool m_changed;
|
||||
bool m_changed = true;
|
||||
bool m_useImmediatePropagation = true;
|
||||
};
|
||||
|
||||
//! handles the addition and removal of entities from instances
|
||||
@@ -44,7 +45,7 @@ namespace AzToolsFramework
|
||||
: public PrefabUndoBase
|
||||
{
|
||||
public:
|
||||
explicit PrefabUndoInstance(const AZStd::string& undoOperationName);
|
||||
explicit PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation = true);
|
||||
|
||||
void Capture(
|
||||
const PrefabDom& initialState,
|
||||
@@ -53,7 +54,6 @@ namespace AzToolsFramework
|
||||
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
void RedoBatched();
|
||||
};
|
||||
|
||||
//! handles entity updates, such as when the values on an entity change
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace AzToolsFramework
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
PrefabDomUtils::StoreInstanceInPrefabDom(instance, instanceDomAfterUpdate);
|
||||
|
||||
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage);
|
||||
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage, false);
|
||||
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, instance.GetTemplateId());
|
||||
state->SetParent(undoBatch);
|
||||
state->RedoBatched();
|
||||
state->Redo();
|
||||
}
|
||||
|
||||
LinkId CreateLink(
|
||||
|
||||
+58
-11
@@ -9,6 +9,7 @@
|
||||
#include "EditorHelpers.h"
|
||||
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Math/VectorConversions.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
@@ -114,6 +115,33 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
CursorEntityIdQuery::CursorEntityIdQuery(AZ::EntityId entityId, AZ::EntityId rootEntityId)
|
||||
: m_entityId(entityId)
|
||||
, m_containerAncestorEntityId(rootEntityId)
|
||||
{
|
||||
}
|
||||
|
||||
AZ::EntityId CursorEntityIdQuery::EntityIdUnderCursor() const
|
||||
{
|
||||
return m_entityId;
|
||||
}
|
||||
|
||||
AZ::EntityId CursorEntityIdQuery::ContainerAncestorEntityId() const
|
||||
{
|
||||
return m_containerAncestorEntityId;
|
||||
}
|
||||
|
||||
bool CursorEntityIdQuery::HasContainerAncestorEntityId() const
|
||||
{
|
||||
if (m_entityId.IsValid())
|
||||
{
|
||||
return m_entityId != m_containerAncestorEntityId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EditorHelpers::EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache)
|
||||
: m_entityDataCache(entityDataCache)
|
||||
{
|
||||
@@ -123,9 +151,14 @@ namespace AzToolsFramework
|
||||
"EditorHelpers - "
|
||||
"Focus Mode Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClicks;
|
||||
invalidClicks.push_back(AZStd::make_unique<FadingText>("Not in focus"));
|
||||
invalidClicks.push_back(AZStd::make_unique<ExpandingFadingCircles>());
|
||||
m_invalidClicks = AZStd::make_unique<InvalidClicks>(AZStd::move(invalidClicks));
|
||||
}
|
||||
|
||||
AZ::EntityId EditorHelpers::HandleMouseInteraction(
|
||||
CursorEntityIdQuery EditorHelpers::FindEntityIdUnderCursor(
|
||||
const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
@@ -186,20 +219,34 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
// Verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
|
||||
if (!IsSelectableAccordingToFocusMode(entityIdUnderCursor))
|
||||
// verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
|
||||
if (entityIdUnderCursor.IsValid() && !IsSelectableAccordingToFocusMode(entityIdUnderCursor))
|
||||
{
|
||||
return AZ::EntityId();
|
||||
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
|
||||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
|
||||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
|
||||
{
|
||||
m_invalidClicks->AddInvalidClick(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
}
|
||||
|
||||
return CursorEntityIdQuery(AZ::EntityId(), AZ::EntityId());
|
||||
}
|
||||
|
||||
// Container Entity support - if the entity that is being selected is part of a closed container,
|
||||
// container entity support - if the entity that is being selected is part of a closed container,
|
||||
// change the selection to the container instead.
|
||||
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
|
||||
{
|
||||
return containerEntityInterface->FindHighestSelectableEntity(entityIdUnderCursor);
|
||||
const auto highestSelectableEntity = containerEntityInterface->FindHighestSelectableEntity(entityIdUnderCursor);
|
||||
return CursorEntityIdQuery(entityIdUnderCursor, highestSelectableEntity);
|
||||
}
|
||||
|
||||
return entityIdUnderCursor;
|
||||
return CursorEntityIdQuery(entityIdUnderCursor, AZ::EntityId());
|
||||
}
|
||||
|
||||
void EditorHelpers::Display2d(
|
||||
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
m_invalidClicks->Display2d(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
void EditorHelpers::DisplayHelpers(
|
||||
@@ -263,19 +310,19 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorHelpers::IsSelectableInViewport(AZ::EntityId entityId)
|
||||
bool EditorHelpers::IsSelectableInViewport(const AZ::EntityId entityId) const
|
||||
{
|
||||
return IsSelectableAccordingToFocusMode(entityId) && IsSelectableAccordingToContainerEntities(entityId);
|
||||
}
|
||||
|
||||
bool EditorHelpers::IsSelectableAccordingToFocusMode(AZ::EntityId entityId)
|
||||
bool EditorHelpers::IsSelectableAccordingToFocusMode(const AZ::EntityId entityId) const
|
||||
{
|
||||
return m_focusModeInterface->IsInFocusSubTree(entityId);
|
||||
}
|
||||
|
||||
bool EditorHelpers::IsSelectableAccordingToContainerEntities(AZ::EntityId entityId)
|
||||
bool EditorHelpers::IsSelectableAccordingToContainerEntities(const AZ::EntityId entityId) const
|
||||
{
|
||||
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
|
||||
if (const auto* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
|
||||
{
|
||||
return !containerEntityInterface->IsUnderClosedContainerEntity(entityId);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -29,6 +32,28 @@ namespace AzToolsFramework
|
||||
struct MouseInteractionEvent;
|
||||
}
|
||||
|
||||
//!< Represents the result of a query to find the id of the entity under the cursor (if any).
|
||||
class CursorEntityIdQuery
|
||||
{
|
||||
public:
|
||||
CursorEntityIdQuery(AZ::EntityId entityId, AZ::EntityId rootEntityId);
|
||||
|
||||
//! Returns the entity id under the cursor (if any).
|
||||
//! @note In the case of no entity id under the cursor, an invalid entity id is returned.
|
||||
AZ::EntityId EntityIdUnderCursor() const;
|
||||
|
||||
//! Returns the topmost container entity id in the hierarchy if the entity id under the cursor is inside a container entity, otherwise returns the entity id.
|
||||
//! @note In the case of no entity id under the cursor, an invalid entity id is returned.
|
||||
AZ::EntityId ContainerAncestorEntityId() const;
|
||||
|
||||
//! Returns true if the query has a container ancestor entity id, otherwise false.
|
||||
bool HasContainerAncestorEntityId() const;
|
||||
|
||||
private:
|
||||
AZ::EntityId m_entityId; //<! The entity id under the cursor.
|
||||
AZ::EntityId m_containerAncestorEntityId; //<! For entities in container entities, the topmost container entity id in the hierarchy, otherwise the entity id under the cursor.
|
||||
};
|
||||
|
||||
//! EditorHelpers are the visualizations that appear for entities
|
||||
//! when 'Display Helpers' is toggled on inside the editor.
|
||||
//! These include but are not limited to entity icons and shape visualizations.
|
||||
@@ -44,9 +69,9 @@ namespace AzToolsFramework
|
||||
EditorHelpers& operator=(const EditorHelpers&) = delete;
|
||||
~EditorHelpers() = default;
|
||||
|
||||
//! Handle any mouse interaction with the EditorHelpers.
|
||||
//! Finds the id of the entity under the cursor (if any). For entities in container entities, also finds the topmost container entity id in the hierarchy.
|
||||
//! Used to check if a particular entity was selected.
|
||||
AZ::EntityId HandleMouseInteraction(
|
||||
CursorEntityIdQuery FindEntityIdUnderCursor(
|
||||
const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
|
||||
|
||||
//! Do the drawing responsible for the EditorHelpers.
|
||||
@@ -58,20 +83,27 @@ namespace AzToolsFramework
|
||||
AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
const AZStd::function<bool(AZ::EntityId)>& showIconCheck);
|
||||
|
||||
//! Handle 2d drawing for EditorHelper functionality.
|
||||
void Display2d(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
AzFramework::DebugDisplayRequests& debugDisplay);
|
||||
|
||||
//! Returns whether the entityId can be selected in the viewport according
|
||||
//! to the current Editor Focus Mode and Container Entity setup.
|
||||
bool IsSelectableInViewport(AZ::EntityId entityId);
|
||||
bool IsSelectableInViewport(AZ::EntityId entityId) const;
|
||||
|
||||
private:
|
||||
//! Returns whether the entityId can be selected in the viewport according
|
||||
//! to the current Editor Focus Mode setup.
|
||||
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId);
|
||||
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId) const;
|
||||
|
||||
//! Returns whether the entityId can be selected in the viewport according
|
||||
//! to the current Container Entityu setup.
|
||||
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId);
|
||||
//! to the current Container Entity setup.
|
||||
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId) const;
|
||||
|
||||
AZStd::unique_ptr<InvalidClicks> m_invalidClicks; //!< Display for invalid click behavior.
|
||||
|
||||
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
|
||||
const FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
const FocusModeInterface* m_focusModeInterface = nullptr; //!< API to interact with focus mode functionality.
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ namespace AzToolsFramework
|
||||
|
||||
const AzFramework::CameraState cameraState = GetCameraState(viewportId);
|
||||
|
||||
m_cachedEntityIdUnderCursor = m_editorHelpers->HandleMouseInteraction(cameraState, mouseInteraction);
|
||||
m_cachedEntityIdUnderCursor = m_editorHelpers->FindEntityIdUnderCursor(cameraState, mouseInteraction).ContainerAncestorEntityId();
|
||||
|
||||
// when left clicking, if we successfully clicked an entity, assign that
|
||||
// to the entity field selected in the entity inspector (RPE)
|
||||
|
||||
+68
-14
@@ -27,6 +27,7 @@
|
||||
#include <AzToolsFramework/Manipulators/ScaleManipulators.h>
|
||||
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
|
||||
#include <AzToolsFramework/Maths/TransformUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLockComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
@@ -1799,7 +1800,8 @@ namespace AzToolsFramework
|
||||
const AzFramework::ViewportId viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId;
|
||||
const AzFramework::CameraState cameraState = GetCameraState(viewportId);
|
||||
|
||||
m_cachedEntityIdUnderCursor = m_editorHelpers->HandleMouseInteraction(cameraState, mouseInteraction);
|
||||
const auto cursorEntityIdQuery = m_editorHelpers->FindEntityIdUnderCursor(cameraState, mouseInteraction);
|
||||
m_cachedEntityIdUnderCursor = cursorEntityIdQuery.ContainerAncestorEntityId();
|
||||
|
||||
const auto selectClickEvent = ClickDetectorEventFromViewportInteraction(mouseInteraction);
|
||||
m_cursorState.SetCurrentPosition(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
@@ -1825,8 +1827,6 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
const AZ::EntityId entityIdUnderCursor = m_cachedEntityIdUnderCursor;
|
||||
|
||||
EditorContextMenuUpdate(m_contextMenu, mouseInteraction);
|
||||
|
||||
m_boxSelect.HandleMouseInteraction(mouseInteraction);
|
||||
@@ -1842,6 +1842,21 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
const AZ::EntityId entityIdUnderCursor = m_cachedEntityIdUnderCursor;
|
||||
|
||||
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick &&
|
||||
mouseInteraction.m_mouseInteraction.m_mouseButtons.Left())
|
||||
{
|
||||
if (cursorEntityIdQuery.HasContainerAncestorEntityId())
|
||||
{
|
||||
if (auto prefabFocusInterface = AZ::Interface<Prefab::PrefabFocusInterface>::Get())
|
||||
{
|
||||
prefabFocusInterface->FocusOnPrefabInstanceOwningEntityId(cursorEntityIdQuery.ContainerAncestorEntityId());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool stickySelect = false;
|
||||
ViewportInteraction::ViewportSettingsRequestBus::EventResult(
|
||||
stickySelect, viewportId, &ViewportInteraction::ViewportSettingsRequestBus::Events::StickySelectEnabled);
|
||||
@@ -3560,6 +3575,8 @@ namespace AzToolsFramework
|
||||
DrawAxisGizmo(viewportInfo, debugDisplay);
|
||||
|
||||
m_boxSelect.Display2d(viewportInfo, debugDisplay);
|
||||
|
||||
m_editorHelpers->Display2d(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::RefreshSelectedEntityIds()
|
||||
@@ -3663,26 +3680,63 @@ namespace AzToolsFramework
|
||||
void EditorTransformComponentSelection::OnEditorModeActivated(
|
||||
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
|
||||
{
|
||||
if (mode == ViewportEditorMode::Component)
|
||||
switch (mode)
|
||||
{
|
||||
SetAllViewportUiVisible(false);
|
||||
case ViewportEditorMode::Component:
|
||||
{
|
||||
SetAllViewportUiVisible(false);
|
||||
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
|
||||
ToolsApplicationNotificationBus::Handler::BusDisconnect();
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
|
||||
ToolsApplicationNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Focus:
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Default:
|
||||
case ViewportEditorMode::Pick:
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::OnEditorModeDeactivated(
|
||||
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
|
||||
const ViewportEditorModesInterface& editorModeState, const ViewportEditorMode mode)
|
||||
{
|
||||
if (mode == ViewportEditorMode::Component)
|
||||
switch (mode)
|
||||
{
|
||||
SetAllViewportUiVisible(true);
|
||||
case ViewportEditorMode::Component:
|
||||
{
|
||||
SetAllViewportUiVisible(true);
|
||||
|
||||
ToolsApplicationNotificationBus::Handler::BusConnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
|
||||
ToolsApplicationNotificationBus::Handler::BusConnect();
|
||||
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
|
||||
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
|
||||
|
||||
// note: when leaving component mode, we check if we're still in focus mode (i.e. component mode was
|
||||
// started from within focus mode), if we are, ensure we create/update the viewport border (as leaving
|
||||
// component mode will attempt to remove it)
|
||||
if (editorModeState.IsModeActive(ViewportEditorMode::Focus))
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Focus:
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Default:
|
||||
case ViewportEditorMode::Pick:
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
|
||||
|
||||
AZ_CVAR(float, ed_invalidClickRadius, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum invalid click radius to expand to");
|
||||
AZ_CVAR(float, ed_invalidClickDuration, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Duration to display the invalid click feedback");
|
||||
AZ_CVAR(float, ed_invalidClickMessageSize, 0.8f, nullptr, AZ::ConsoleFunctorFlags::Null, "Size of text for invalid message");
|
||||
AZ_CVAR(
|
||||
float,
|
||||
ed_invalidClickMessageVerticalOffset,
|
||||
30.0f,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"Vertical offset from cursor of invalid click message");
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
void ExpandingFadingCircles::Begin(const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
FadingCircle fadingCircle;
|
||||
fadingCircle.m_position = screenPoint;
|
||||
fadingCircle.m_opacity = 1.0f;
|
||||
fadingCircle.m_radius = 0.0f;
|
||||
m_fadingCircles.push_back(fadingCircle);
|
||||
}
|
||||
|
||||
void ExpandingFadingCircles::Update(const float deltaTime)
|
||||
{
|
||||
for (auto& fadingCircle : m_fadingCircles)
|
||||
{
|
||||
fadingCircle.m_opacity = AZStd::max(fadingCircle.m_opacity - (deltaTime / ed_invalidClickDuration), 0.0f);
|
||||
fadingCircle.m_radius += deltaTime * ed_invalidClickRadius;
|
||||
}
|
||||
|
||||
m_fadingCircles.erase(
|
||||
AZStd::remove_if(
|
||||
m_fadingCircles.begin(), m_fadingCircles.end(),
|
||||
[](const FadingCircle& fadingCircle)
|
||||
{
|
||||
return fadingCircle.m_opacity <= 0.0f;
|
||||
}),
|
||||
m_fadingCircles.end());
|
||||
}
|
||||
|
||||
bool ExpandingFadingCircles::Updating()
|
||||
{
|
||||
return !m_fadingCircles.empty();
|
||||
}
|
||||
|
||||
void ExpandingFadingCircles::Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
const AZ::Vector2 viewportSize = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId).m_viewportSize;
|
||||
|
||||
for (const auto& fadingCircle : m_fadingCircles)
|
||||
{
|
||||
const auto position = AzFramework::Vector2FromScreenPoint(fadingCircle.m_position) / viewportSize;
|
||||
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, fadingCircle.m_opacity));
|
||||
debugDisplay.DrawWireCircle2d(position, fadingCircle.m_radius * 0.005f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void FadingText::Begin(const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
m_opacity = 1.0f;
|
||||
m_invalidClickPosition = screenPoint;
|
||||
}
|
||||
|
||||
void FadingText::Update(const float deltaTime)
|
||||
{
|
||||
m_opacity -= deltaTime / ed_invalidClickDuration;
|
||||
}
|
||||
|
||||
bool FadingText::Updating()
|
||||
{
|
||||
return m_opacity >= 0.0f;
|
||||
}
|
||||
|
||||
void FadingText::Display(
|
||||
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
if (constexpr float MinOpacity = 0.05f; m_opacity >= MinOpacity)
|
||||
{
|
||||
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, m_opacity));
|
||||
debugDisplay.Draw2dTextLabel(
|
||||
aznumeric_cast<float>(m_invalidClickPosition.m_x),
|
||||
aznumeric_cast<float>(m_invalidClickPosition.m_y) - ed_invalidClickMessageVerticalOffset, ed_invalidClickMessageSize,
|
||||
m_message.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void InvalidClicks::AddInvalidClick(const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
|
||||
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
|
||||
{
|
||||
invalidClickBehavior->Begin(screenPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void InvalidClicks::OnTick(const float deltaTime, [[maybe_unused]] const AZ::ScriptTimePoint time)
|
||||
{
|
||||
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
|
||||
{
|
||||
invalidClickBehavior->Update(deltaTime);
|
||||
}
|
||||
|
||||
const auto updating = AZStd::any_of(
|
||||
m_invalidClickBehaviors.begin(), m_invalidClickBehaviors.end(),
|
||||
[](const auto& invalidClickBehavior)
|
||||
{
|
||||
return invalidClickBehavior->Updating();
|
||||
});
|
||||
|
||||
if (!updating && AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void InvalidClicks::Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
|
||||
{
|
||||
debugDisplay.DepthTestOff();
|
||||
|
||||
for (const auto& invalidClickBehavior : m_invalidClickBehaviors)
|
||||
{
|
||||
invalidClickBehavior->Display(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
debugDisplay.DepthTestOn();
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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/Component/TickBus.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class DebugDisplayRequests;
|
||||
struct ViewportInfo;
|
||||
} // namespace AzFramework
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace ViewportInteraction
|
||||
{
|
||||
struct MouseInteractionEvent;
|
||||
}
|
||||
|
||||
//! An interface to provide invalid click feedback in the editor viewport.
|
||||
class InvalidClick
|
||||
{
|
||||
public:
|
||||
virtual ~InvalidClick() = default;
|
||||
|
||||
//! Begin the feedback.
|
||||
//! @param screenPoint The position of the click in screen coordinates.
|
||||
virtual void Begin(const AzFramework::ScreenPoint& screenPoint) = 0;
|
||||
//! Update the invalid click feedback
|
||||
virtual void Update(float deltaTime) = 0;
|
||||
//! Report if the click feedback is running or not (returning false will signal the TickBus can be disconnected from).
|
||||
virtual bool Updating() = 0;
|
||||
//! Display the click feedback in the viewport.
|
||||
virtual void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) = 0;
|
||||
};
|
||||
|
||||
//! Display expanding fading circles for every click of the mouse that is invalid.
|
||||
class ExpandingFadingCircles : public InvalidClick
|
||||
{
|
||||
public:
|
||||
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
|
||||
void Update(float deltaTime) override;
|
||||
bool Updating() override;
|
||||
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
private:
|
||||
//! Stores a circle representation with a lifetime to grow and fade out over time.
|
||||
struct FadingCircle
|
||||
{
|
||||
AzFramework::ScreenPoint m_position;
|
||||
float m_radius;
|
||||
float m_opacity;
|
||||
};
|
||||
|
||||
using FadingCircles = AZStd::vector<FadingCircle>;
|
||||
FadingCircles m_fadingCircles; //!< Collection of fading circles to draw for clicks that have no effect.
|
||||
};
|
||||
|
||||
//! Display fading text where an invalid click happened.
|
||||
//! @note There is only one fading text, each click will update its position.
|
||||
class FadingText : public InvalidClick
|
||||
{
|
||||
public:
|
||||
explicit FadingText(AZStd::string message)
|
||||
: m_message(AZStd::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
|
||||
void Update(float deltaTime) override;
|
||||
bool Updating() override;
|
||||
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
|
||||
|
||||
private:
|
||||
AZStd::string m_message; //!< Message to display for fading text.
|
||||
float m_opacity = 1.0f; //!< The opacity of the invalid click message.
|
||||
AzFramework::ScreenPoint m_invalidClickPosition; //!< The position to display the invalid click message.
|
||||
};
|
||||
|
||||
//! Interface to begin invalid click feedback (will run all added InvalidClick behaviors).
|
||||
class InvalidClicks : private AZ::TickBus::Handler
|
||||
{
|
||||
public:
|
||||
explicit InvalidClicks(AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClickBehaviors)
|
||||
: m_invalidClickBehaviors(AZStd::move(invalidClickBehaviors))
|
||||
{
|
||||
}
|
||||
|
||||
//! Add an invalid click and activate one or more of the added invalid click behaviors.
|
||||
void AddInvalidClick(const AzFramework::ScreenPoint& screenPoint);
|
||||
|
||||
//! Handle 2d drawing for EditorHelper functionality.
|
||||
void Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay);
|
||||
|
||||
private:
|
||||
//! AZ::TickBus overrides ...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
AZStd::vector<AZStd::unique_ptr<InvalidClick>> m_invalidClickBehaviors; //!< Invalid click behaviors to run.
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
@@ -290,9 +290,9 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::CreateComponentModeBorder(const AZStd::string& borderTitle)
|
||||
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
|
||||
{
|
||||
AZStd::string styleSheet = AZStd::string::format(
|
||||
const AZStd::string styleSheet = AZStd::string::format(
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
|
||||
HighlightBorderColor);
|
||||
m_uiOverlay.setStyleSheet(styleSheet.c_str());
|
||||
@@ -303,7 +303,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_componentModeBorderText.setText(borderTitle.c_str());
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::RemoveComponentModeBorder()
|
||||
void ViewportUiDisplay::RemoveViewportBorder()
|
||||
{
|
||||
m_componentModeBorderText.setVisible(false);
|
||||
m_uiOverlay.setStyleSheet("border: none;");
|
||||
@@ -420,6 +420,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_uiMainWindow.setVisible(true);
|
||||
m_uiOverlay.setVisible(true);
|
||||
}
|
||||
|
||||
m_uiMainWindow.setMask(region);
|
||||
}
|
||||
|
||||
@@ -437,6 +438,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
return element->second;
|
||||
}
|
||||
|
||||
return ViewportUiElementInfo{ nullptr, InvalidViewportUiElementId, false };
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
AZStd::shared_ptr<QWidget> GetViewportUiElement(ViewportUiElementId elementId);
|
||||
bool IsViewportUiElementVisible(ViewportUiElementId elementId);
|
||||
|
||||
void CreateComponentModeBorder(const AZStd::string& borderTitle);
|
||||
void RemoveComponentModeBorder();
|
||||
void CreateViewportBorder(const AZStd::string& borderTitle);
|
||||
void RemoveViewportBorder();
|
||||
|
||||
private:
|
||||
void PrepareWidgetForViewportUi(QPointer<QWidget> widget);
|
||||
|
||||
@@ -240,14 +240,14 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::CreateComponentModeBorder(const AZStd::string& borderTitle)
|
||||
void ViewportUiManager::CreateViewportBorder(const AZStd::string& borderTitle)
|
||||
{
|
||||
m_viewportUi->CreateComponentModeBorder(borderTitle);
|
||||
m_viewportUi->CreateViewportBorder(borderTitle);
|
||||
}
|
||||
|
||||
void ViewportUiManager::RemoveComponentModeBorder()
|
||||
void ViewportUiManager::RemoveViewportBorder()
|
||||
{
|
||||
m_viewportUi->RemoveComponentModeBorder();
|
||||
m_viewportUi->RemoveViewportBorder();
|
||||
}
|
||||
|
||||
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace AzToolsFramework::ViewportUi
|
||||
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 CreateViewportBorder(const AZStd::string& borderTitle) override;
|
||||
void RemoveViewportBorder() override;
|
||||
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
|
||||
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
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;
|
||||
//!
|
||||
//! Removes a switcher from the Viewport UI system.
|
||||
virtual void RemoveSwitcher(SwitcherId switcherId) = 0;
|
||||
//! Sets the visibility of the cluster.
|
||||
virtual void SetClusterVisible(ClusterId clusterId, bool visible) = 0;
|
||||
@@ -96,12 +96,12 @@ namespace AzToolsFramework::ViewportUi
|
||||
//! Sets the visibility of the text field.
|
||||
virtual void SetTextFieldVisible(TextFieldId textFieldId, bool visible) = 0;
|
||||
//! Create the highlight border for Component Mode.
|
||||
virtual void CreateComponentModeBorder(const AZStd::string& borderTitle) = 0;
|
||||
virtual void CreateViewportBorder(const AZStd::string& borderTitle) = 0;
|
||||
//! Remove the highlight border for Component Mode.
|
||||
virtual void RemoveComponentModeBorder() = 0;
|
||||
//! Invoke a button press in a cluster.
|
||||
virtual void RemoveViewportBorder() = 0;
|
||||
//! Invoke a button press on a cluster.
|
||||
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
|
||||
//!
|
||||
//! Invoke a button press on a switcher.
|
||||
virtual void PressButton(SwitcherId switcherId, ButtonId buttonId) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -553,6 +553,8 @@ set(FILES
|
||||
ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp
|
||||
ViewportSelection/EditorVisibleEntityDataCache.h
|
||||
ViewportSelection/EditorVisibleEntityDataCache.cpp
|
||||
ViewportSelection/InvalidClicks.h
|
||||
ViewportSelection/InvalidClicks.cpp
|
||||
ViewportSelection/ViewportEditorModeTracker.cpp
|
||||
ViewportSelection/ViewportEditorModeTracker.h
|
||||
ToolsFileUtils/ToolsFileUtils.h
|
||||
|
||||
@@ -333,7 +333,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierAsyncHandshakeTestTemplate
|
||||
class CarrierAsyncHandshakeTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
{
|
||||
@@ -761,7 +761,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierDisconnectDetectionTestTemplate
|
||||
class CarrierDisconnectDetectionTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
{
|
||||
@@ -846,7 +846,7 @@ namespace UnitTest
|
||||
* Sends reliable messages across different channels to each other
|
||||
*/
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierMultiChannelTestTemplate
|
||||
class CarrierMultiChannelTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
{
|
||||
@@ -950,7 +950,7 @@ namespace UnitTest
|
||||
* Stress tests multiple simultaneous Carriers
|
||||
*/
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierMultiStressTestTemplate
|
||||
class CarrierMultiStressTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
{
|
||||
@@ -977,7 +977,7 @@ namespace UnitTest
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
AZ_TracePrintf("GridMate", "Integ_CarrierMultiStressTest\n\n");
|
||||
AZ_TracePrintf("GridMate", "CarrierMultiStressTest\n\n");
|
||||
|
||||
// initialize transport
|
||||
const int k_numChannels = 1;
|
||||
@@ -1108,7 +1108,7 @@ namespace UnitTest
|
||||
|
||||
/*** Congestion control back pressure test */
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierBackpressureTestTemplate
|
||||
class CarrierBackpressureTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
, public CarrierEventBus::Handler
|
||||
@@ -1380,7 +1380,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
template<class SocketProvider = SocketDriverProvider>
|
||||
class Integ_CarrierACKTestTemplate
|
||||
class CarrierACKTestTemplate
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketProvider
|
||||
{
|
||||
@@ -1544,13 +1544,13 @@ namespace UnitTest
|
||||
//Create specific tests
|
||||
using CarrierBasicTest = CarrierBasicTestTemplate<>;
|
||||
using CarrierTest = CarrierTestTemplate<>;
|
||||
using Integ_CarrierDisconnectDetectionTest = Integ_CarrierDisconnectDetectionTestTemplate<>;
|
||||
using Integ_CarrierAsyncHandshakeTest = Integ_CarrierAsyncHandshakeTestTemplate<>;
|
||||
using Integ_CarrierStressTest = CarrierStressTestTemplate<>;
|
||||
using Integ_CarrierMultiChannelTest = Integ_CarrierMultiChannelTestTemplate<>;
|
||||
using Integ_CarrierMultiStressTest = Integ_CarrierMultiStressTestTemplate<>;
|
||||
using Integ_CarrierBackpressureTest = Integ_CarrierBackpressureTestTemplate<>;
|
||||
using Integ_CarrierACKTest = Integ_CarrierACKTestTemplate<>;
|
||||
using DISABLED_CarrierDisconnectDetectionTest = CarrierDisconnectDetectionTestTemplate<>;
|
||||
using DISABLED_CarrierAsyncHandshakeTest = CarrierAsyncHandshakeTestTemplate<>;
|
||||
using DISABLED_CarrierStressTest = CarrierStressTestTemplate<>;
|
||||
using DISABLED_CarrierMultiChannelTest = CarrierMultiChannelTestTemplate<>;
|
||||
using DISABLED_CarrierMultiStressTest = CarrierMultiStressTestTemplate<>;
|
||||
using DISABLED_CarrierBackpressureTest = CarrierBackpressureTestTemplate<>;
|
||||
using DISABLED_CarrierACKTest = CarrierACKTestTemplate<>;
|
||||
|
||||
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
|
||||
|
||||
@@ -1658,20 +1658,20 @@ namespace UnitTest
|
||||
using SecureProviderBadHost = SecureDriverProvider<SecureSocketDriver, SecureSocketHandshakeDrop<false>>;
|
||||
using SecureProviderBadBoth = SecureDriverProvider<SecureSocketHandshakeDrop<true>, SecureSocketHandshakeDrop<false>>;
|
||||
|
||||
using Integ_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
|
||||
using Integ_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
|
||||
using Integ_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
|
||||
using DISABLED_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
|
||||
using DISABLED_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
|
||||
using DISABLED_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
|
||||
|
||||
//Create secure socket variants of tests
|
||||
using CarrierBasicTestSecure = CarrierBasicTestTemplate<SecureDriverProvider<>>;
|
||||
using CarrierTestSecure = CarrierTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierDisconnectDetectionTestSecure = Integ_CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierAsyncHandshakeTestSecure = Integ_CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierMultiChannelTestSecure = Integ_CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierMultiStressTestSecure = Integ_CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierBackpressureTestSecure = Integ_CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
|
||||
using Integ_CarrierACKTestSecure = Integ_CarrierACKTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierDisconnectDetectionTestSecure = CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierAsyncHandshakeTestSecure = CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierMultiChannelTestSecure = CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierMultiStressTestSecure = CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierBackpressureTestSecure = CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
|
||||
using DISABLED_CarrierACKTestSecure = CarrierACKTestTemplate<SecureDriverProvider<>>;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1720,30 +1720,30 @@ GM_TEST_SUITE(CarrierSuite)
|
||||
GM_TEST(CarrierBasicTest)
|
||||
GM_TEST(CarrierTest)
|
||||
#endif //AZ_TRAIT_GRIDMATE_UNIT_TEST_DISABLE_CARRIER_SESSION_TESTS
|
||||
GM_TEST(Integ_CarrierAsyncHandshakeTest)
|
||||
GM_TEST(DISABLED_CarrierAsyncHandshakeTest)
|
||||
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
|
||||
GM_TEST(Integ_CarrierStressTest)
|
||||
GM_TEST(Integ_CarrierMultiStressTest)
|
||||
GM_TEST(DISABLED_CarrierStressTest)
|
||||
GM_TEST(DISABLED_CarrierMultiStressTest)
|
||||
#endif
|
||||
GM_TEST(Integ_CarrierMultiChannelTest)
|
||||
GM_TEST(Integ_CarrierBackpressureTest)
|
||||
GM_TEST(Integ_CarrierACKTest)
|
||||
GM_TEST(DISABLED_CarrierMultiChannelTest)
|
||||
GM_TEST(DISABLED_CarrierBackpressureTest)
|
||||
GM_TEST(DISABLED_CarrierACKTest)
|
||||
|
||||
|
||||
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
|
||||
GM_TEST(CarrierBasicTestSecure)
|
||||
GM_TEST(Integ_CarrierSecureSocketHandshakeTestClient)
|
||||
GM_TEST(Integ_CarrierSecureSocketHandshakeTestHost)
|
||||
GM_TEST(Integ_CarrierSecureSocketHandshakeTestBoth)
|
||||
GM_TEST(DISABLED_CarrierBasicTestSecure)
|
||||
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestClient)
|
||||
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestHost)
|
||||
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestBoth)
|
||||
GM_TEST(CarrierTestSecure)
|
||||
GM_TEST(Integ_CarrierAsyncHandshakeTestSecure)
|
||||
GM_TEST(DISABLED_CarrierAsyncHandshakeTestSecure)
|
||||
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
|
||||
GM_TEST(Integ_CarrierStressTestSecure)
|
||||
GM_TEST(Integ_CarrierMultiStressTestSecure)
|
||||
GM_TEST(DISABLED_CarrierStressTestSecure)
|
||||
GM_TEST(DISABLED_CarrierMultiStressTestSecure)
|
||||
#endif
|
||||
GM_TEST(Integ_CarrierMultiChannelTestSecure)
|
||||
GM_TEST(Integ_CarrierBackpressureTestSecure)
|
||||
GM_TEST(Integ_CarrierACKTestSecure)
|
||||
GM_TEST(DISABLED_CarrierMultiChannelTestSecure)
|
||||
GM_TEST(DISABLED_CarrierBackpressureTestSecure)
|
||||
GM_TEST(DISABLED_CarrierACKTestSecure)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class Integ_CarrierStreamBasicTest
|
||||
class DISABLED_CarrierStreamBasicTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
{
|
||||
@@ -330,7 +330,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_CarrierStreamAsyncHandshakeTest
|
||||
class DISABLED_CarrierStreamAsyncHandshakeTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
{
|
||||
@@ -462,7 +462,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_CarrierStreamStressTest
|
||||
class CarrierStreamStressTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
, public ::testing::Test
|
||||
@@ -470,7 +470,7 @@ namespace UnitTest
|
||||
public:
|
||||
};
|
||||
|
||||
TEST_F(Integ_CarrierStreamStressTest, Stress_Test)
|
||||
TEST_F(CarrierStreamStressTest, DISABLED_Stress_Test)
|
||||
{
|
||||
CarrierStreamCallbacksHandler clientCB, serverCB;
|
||||
UnitTest::TestCarrierDesc serverCarrierDesc, clientCarrierDesc;
|
||||
@@ -581,7 +581,7 @@ namespace UnitTest
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
class Integ_CarrierStreamTest
|
||||
class DISABLED_CarrierStreamTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
{
|
||||
@@ -783,7 +783,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_CarrierStreamDisconnectDetectionTest
|
||||
class DISABLED_CarrierStreamDisconnectDetectionTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
{
|
||||
@@ -873,7 +873,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_CarrierStreamMultiChannelTest
|
||||
class DISABLED_CarrierStreamMultiChannelTest
|
||||
: public GridMateMPTestFixture
|
||||
, protected SocketDriverSupplier
|
||||
{
|
||||
@@ -999,8 +999,8 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
GM_TEST_SUITE(CarrierStreamSuite)
|
||||
GM_TEST(Integ_CarrierStreamBasicTest)
|
||||
GM_TEST(Integ_CarrierStreamTest)
|
||||
GM_TEST(Integ_CarrierStreamAsyncHandshakeTest)
|
||||
GM_TEST(Integ_CarrierStreamMultiChannelTest)
|
||||
GM_TEST(DISABLED_CarrierStreamBasicTest)
|
||||
GM_TEST(DISABLED_CarrierStreamTest)
|
||||
GM_TEST(DISABLED_CarrierStreamAsyncHandshakeTest)
|
||||
GM_TEST(DISABLED_CarrierStreamMultiChannelTest)
|
||||
GM_TEST_SUITE_END()
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
#include "Tests.h"
|
||||
#include "TestProfiler.h"
|
||||
|
||||
#include <GridMate/Replica/ReplicaFunctions.h>
|
||||
|
||||
@@ -1888,12 +1887,12 @@ protected:
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Integ_ReplicaGMTest
|
||||
class ReplicaGMTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ::testing::Test
|
||||
{};
|
||||
|
||||
TEST_F(Integ_ReplicaGMTest, ReplicaTest)
|
||||
TEST_F(ReplicaGMTest, DISABLED_ReplicaTest)
|
||||
{
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
|
||||
@@ -2157,7 +2156,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest)
|
||||
}
|
||||
}
|
||||
|
||||
class Integ_ForcedReplicaMigrationTest
|
||||
class ForcedReplicaMigrationTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ReplicaMgrCallbackBus::Handler
|
||||
, public MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler
|
||||
@@ -2186,8 +2185,8 @@ class Integ_ForcedReplicaMigrationTest
|
||||
}
|
||||
|
||||
public:
|
||||
Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
|
||||
~Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
|
||||
ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
|
||||
~ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
|
||||
|
||||
|
||||
enum
|
||||
@@ -2205,11 +2204,11 @@ public:
|
||||
AZStd::unordered_map<ReplicaId, ReplicaManager*> m_replicaOwnership;
|
||||
};
|
||||
|
||||
const int Integ_ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
|
||||
const int Integ_ForcedReplicaMigrationTest::k_numFramesToRun;
|
||||
const int Integ_ForcedReplicaMigrationTest::k_hostSendRateMs;
|
||||
const int ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
|
||||
const int ForcedReplicaMigrationTest::k_numFramesToRun;
|
||||
const int ForcedReplicaMigrationTest::k_hostSendRateMs;
|
||||
|
||||
TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
|
||||
TEST_F(ForcedReplicaMigrationTest, DISABLED_ForcedReplicaMigrationTest)
|
||||
{
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
|
||||
@@ -2360,7 +2359,7 @@ TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
|
||||
MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
class Integ_ReplicaMigrationRequestTest
|
||||
class ReplicaMigrationRequestTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ::testing::Test
|
||||
{
|
||||
@@ -2516,7 +2515,7 @@ public:
|
||||
static const int k_hostSendTimeMs = k_frameTimePerNodeMs * TotalNodes * 4; // limiting host send rate to be x4 times slower than tick
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
|
||||
TEST_F(ReplicaMigrationRequestTest, DISABLED_ReplicaMigrationRequestTest)
|
||||
{
|
||||
/*
|
||||
Topology:
|
||||
@@ -2837,11 +2836,11 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
|
||||
}
|
||||
}
|
||||
|
||||
const int Integ_ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
|
||||
const int Integ_ReplicaMigrationRequestTest::k_hostSendTimeMs;
|
||||
const int ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
|
||||
const int ReplicaMigrationRequestTest::k_hostSendTimeMs;
|
||||
|
||||
|
||||
class Integ_PeerRejoinTest
|
||||
class PeerRejoinTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ReplicaMgrCallbackBus::Handler
|
||||
, public ::testing::Test
|
||||
@@ -2860,11 +2859,11 @@ class Integ_PeerRejoinTest
|
||||
}
|
||||
|
||||
public:
|
||||
Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
|
||||
~Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
|
||||
PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
|
||||
~PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
|
||||
};
|
||||
|
||||
TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
|
||||
TEST_F(PeerRejoinTest, DISABLED_PeerRejoinTest)
|
||||
{
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
|
||||
@@ -3011,7 +3010,7 @@ TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
|
||||
}
|
||||
}
|
||||
|
||||
class Integ_ReplicationSecurityOptionsTest
|
||||
class ReplicationSecurityOptionsTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ::testing::Test
|
||||
{
|
||||
@@ -3156,7 +3155,7 @@ public:
|
||||
using TestChunkPtr = AZStd::intrusive_ptr<TestChunk> ;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
|
||||
TEST_F(ReplicationSecurityOptionsTest, DISABLED_ReplicationSecurityOptionsTest)
|
||||
{
|
||||
AZ_TracePrintf("GridMate", "\n");
|
||||
|
||||
@@ -3356,7 +3355,7 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
|
||||
Replica update time (msec): avg=4.94, min=1, max=9 (peers=40, replicas=16000, freq=10%, samples=4000)
|
||||
Replica update time (msec): avg=8.05, min=6, max=15 (peers=40, replicas=16000, freq=100%, samples=4000)
|
||||
*/
|
||||
class Integ_ReplicaStressTest
|
||||
class DISABLED_ReplicaStressTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -3388,7 +3387,7 @@ public:
|
||||
static const int BASE_PORT = 44270;
|
||||
|
||||
// TODO: Reduce the size or disable the test for platforms which can't allocate 2 GiB
|
||||
Integ_ReplicaStressTest()
|
||||
DISABLED_ReplicaStressTest()
|
||||
: UnitTest::GridMateMPTestFixture(2000u * 1024u * 1024u)
|
||||
{}
|
||||
|
||||
@@ -3516,33 +3515,33 @@ public:
|
||||
virtual void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas)
|
||||
{
|
||||
// testing 3 cases & waiting for system to settle in between
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
Wait(sessions, replicas, 50, FRAME_TIME);
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
//TestProfiler::PrintProfilingTotal("GridMate");
|
||||
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.0); // no replicas are dirty
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
//TestProfiler::PrintProfilingTotal("GridMate");
|
||||
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 1, FRAME_TIME, 1.0); // single burst dirty replicas
|
||||
Wait(sessions, replicas, 2, FRAME_TIME);
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
//TestProfiler::PrintProfilingTotal("GridMate");
|
||||
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1); // 10% of replicas are marked dirty every frame
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
//TestProfiler::PrintProfilingTotal("GridMate");
|
||||
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 100, FRAME_TIME, 1.0); // every replica is marked dirty every frame
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
TestProfiler::PrintProfilingSelf("GridMate");
|
||||
//TestProfiler::PrintProfilingTotal("GridMate");
|
||||
//TestProfiler::PrintProfilingSelf("GridMate");
|
||||
|
||||
TestProfiler::StopProfiling();
|
||||
//TestProfiler::StopProfiling();
|
||||
}
|
||||
|
||||
virtual void MarkChanging(vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas, double freq)
|
||||
@@ -3623,8 +3622,8 @@ public:
|
||||
Replica update time (msec): avg=2.01, min=1, max=5 (peers=40, replicas=16000, freq=10%, samples=4000)
|
||||
Replica update time (msec): avg=4.61, min=3, max=10 (peers=40, replicas=16000, freq=50%, samples=4000)
|
||||
*/
|
||||
class Integ_ReplicaStableStressTest
|
||||
: public Integ_ReplicaStressTest
|
||||
class DISABLED_ReplicaStableStressTest
|
||||
: public DISABLED_ReplicaStressTest
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -3636,21 +3635,21 @@ public:
|
||||
|
||||
void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas) override
|
||||
{
|
||||
Integ_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
|
||||
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1);
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
TestProfiler::PrintProfilingSelf("GridMate");
|
||||
/*TestProfiler::PrintProfilingTotal("GridMate");
|
||||
TestProfiler::PrintProfilingSelf("GridMate");*/
|
||||
|
||||
Integ_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
|
||||
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
|
||||
Wait(sessions, replicas, 20, FRAME_TIME);
|
||||
TestProfiler::StartProfiling();
|
||||
//TestProfiler::StartProfiling();
|
||||
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.5);
|
||||
TestProfiler::PrintProfilingTotal("GridMate");
|
||||
/*TestProfiler::PrintProfilingTotal("GridMate");
|
||||
TestProfiler::PrintProfilingSelf("GridMate");
|
||||
|
||||
TestProfiler::StopProfiling();
|
||||
TestProfiler::StopProfiling();*/
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3666,7 +3665,7 @@ public:
|
||||
* expected |none |brst | capped |under cap |brst | capped |
|
||||
*
|
||||
*/
|
||||
class Integ_ReplicaBandiwdthTest
|
||||
class DISABLED_ReplicaBandiwdthTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -3944,9 +3943,9 @@ GM_TEST_SUITE(ReplicaSuite)
|
||||
GM_TEST(InterpolatorTest)
|
||||
|
||||
#if !defined(AZ_DEBUG_BUILD) // these tests are a little slow for debug
|
||||
GM_TEST(Integ_ReplicaBandiwdthTest)
|
||||
GM_TEST(Integ_ReplicaStressTest)
|
||||
GM_TEST(Integ_ReplicaStableStressTest)
|
||||
GM_TEST(DISABLED_ReplicaBandiwdthTest)
|
||||
GM_TEST(DISABLED_ReplicaStressTest)
|
||||
GM_TEST(DISABLED_ReplicaStableStressTest)
|
||||
#endif
|
||||
|
||||
GM_TEST_SUITE_END()
|
||||
|
||||
@@ -457,13 +457,13 @@ namespace ReplicaBehavior {
|
||||
Completed,
|
||||
};
|
||||
|
||||
class Integ_SimpleBehaviorTest
|
||||
class SimpleBehaviorTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
//GM_CLASS_ALLOCATOR(SimpleBehaviorTest);
|
||||
|
||||
Integ_SimpleBehaviorTest()
|
||||
SimpleBehaviorTest()
|
||||
: m_sessionCount(0) { }
|
||||
|
||||
virtual int GetNumSessions() { return 0; }
|
||||
@@ -654,11 +654,11 @@ namespace ReplicaBehavior {
|
||||
*
|
||||
* This is a simple sanity check to ensure the logic sends the update when it's necessary.
|
||||
*/
|
||||
class Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class Replica_DontSendDataSets_WithNoDiffFromCtorData
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData()
|
||||
Replica_DontSendDataSets_WithNoDiffFromCtorData()
|
||||
: m_replicaIdDefault(InvalidReplicaId), m_replicaIdModified(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -774,9 +774,9 @@ namespace ReplicaBehavior {
|
||||
FilteredHook<LargeChunkWithDefaults> m_driller;
|
||||
};
|
||||
|
||||
TEST(Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData, Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData)
|
||||
TEST(Replica_DontSendDataSets_WithNoDiffFromCtorData, DISABLED_Replica_DontSendDataSets_WithNoDiffFromCtorData)
|
||||
{
|
||||
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
|
||||
Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
@@ -784,11 +784,11 @@ namespace ReplicaBehavior {
|
||||
* This test checks the actual size of the replica as marshalled in the binary payload.
|
||||
* The assessment of the payload size is done using driller EBus.
|
||||
*/
|
||||
class Integ_ReplicaDefaultDataSetDriller
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class ReplicaDefaultDataSetDriller
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaDefaultDataSetDriller()
|
||||
ReplicaDefaultDataSetDriller()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -815,7 +815,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_ReplicaDefaultDataSetDriller() override
|
||||
~ReplicaDefaultDataSetDriller() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -880,11 +880,11 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
const int Integ_ReplicaDefaultDataSetDriller::NonDefaultValue;
|
||||
const int ReplicaDefaultDataSetDriller::NonDefaultValue;
|
||||
|
||||
TEST(Integ_ReplicaDefaultDataSetDriller, Integ_ReplicaDefaultDataSetDriller)
|
||||
TEST(ReplicaDefaultDataSetDriller, DISABLED_ReplicaDefaultDataSetDriller)
|
||||
{
|
||||
Integ_ReplicaDefaultDataSetDriller tester;
|
||||
ReplicaDefaultDataSetDriller tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
@@ -892,11 +892,11 @@ namespace ReplicaBehavior {
|
||||
* This test checks the actual size of the replica as marshalled in the binary payload.
|
||||
* The assessment of the payload size is done using driller EBus.
|
||||
*/
|
||||
class Integ_Replica_ComparePackingBoolsVsU8
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class Replica_ComparePackingBoolsVsU8
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_Replica_ComparePackingBoolsVsU8()
|
||||
Replica_ComparePackingBoolsVsU8()
|
||||
: m_replicaBoolsId(InvalidReplicaId)
|
||||
, m_replicaU8Id(InvalidReplicaId)
|
||||
{
|
||||
@@ -928,7 +928,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica2);
|
||||
}
|
||||
|
||||
~Integ_Replica_ComparePackingBoolsVsU8() override
|
||||
~Replica_ComparePackingBoolsVsU8() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -1020,17 +1020,17 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaU8Id;
|
||||
};
|
||||
|
||||
TEST(Integ_Replica_ComparePackingBoolsVsU8, Integ_Replica_ComparePackingBoolsVsU8)
|
||||
TEST(Replica_ComparePackingBoolsVsU8, DISABLED_Replica_ComparePackingBoolsVsU8)
|
||||
{
|
||||
Integ_Replica_ComparePackingBoolsVsU8 tester;
|
||||
Replica_ComparePackingBoolsVsU8 tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class CheckDataSetStreamIsntWrittenMoreThanNecessary
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary()
|
||||
CheckDataSetStreamIsntWrittenMoreThanNecessary()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -1057,7 +1057,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary() override
|
||||
~CheckDataSetStreamIsntWrittenMoreThanNecessary() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -1117,17 +1117,17 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary)
|
||||
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessary, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessary)
|
||||
{
|
||||
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
|
||||
CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
|
||||
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -1154,7 +1154,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
|
||||
~CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -1213,17 +1213,17 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
|
||||
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
|
||||
{
|
||||
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
|
||||
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
class Integ_CheckReplicaIsntSentWithNoChanges
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class CheckReplicaIsntSentWithNoChanges
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_CheckReplicaIsntSentWithNoChanges()
|
||||
CheckReplicaIsntSentWithNoChanges()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -1248,7 +1248,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_CheckReplicaIsntSentWithNoChanges() override
|
||||
~CheckReplicaIsntSentWithNoChanges() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -1323,17 +1323,17 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST(Integ_CheckReplicaIsntSentWithNoChanges, Integ_CheckReplicaIsntSentWithNoChanges)
|
||||
TEST(CheckReplicaIsntSentWithNoChanges, DISABLED_CheckReplicaIsntSentWithNoChanges)
|
||||
{
|
||||
Integ_CheckReplicaIsntSentWithNoChanges tester;
|
||||
CheckReplicaIsntSentWithNoChanges tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
class Integ_CheckEntityScriptReplicaIsntSentWithNoChanges
|
||||
: public Integ_SimpleBehaviorTest
|
||||
class CheckEntityScriptReplicaIsntSentWithNoChanges
|
||||
: public SimpleBehaviorTest
|
||||
{
|
||||
public:
|
||||
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges()
|
||||
CheckEntityScriptReplicaIsntSentWithNoChanges()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -1359,7 +1359,7 @@ namespace ReplicaBehavior {
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_CheckEntityScriptReplicaIsntSentWithNoChanges() override
|
||||
~CheckEntityScriptReplicaIsntSentWithNoChanges() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -1410,9 +1410,9 @@ namespace ReplicaBehavior {
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST(Integ_CheckEntityScriptReplicaIsntSentWithNoChanges, Integ_CheckEntityScriptReplicaIsntSentWithNoChanges)
|
||||
TEST(CheckEntityScriptReplicaIsntSentWithNoChanges, DISABLED_CheckEntityScriptReplicaIsntSentWithNoChanges)
|
||||
{
|
||||
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges tester;
|
||||
CheckEntityScriptReplicaIsntSentWithNoChanges tester;
|
||||
tester.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -596,12 +596,12 @@ public:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class MPSession
|
||||
class MPSessionMedium
|
||||
: public CarrierEventBus::Handler
|
||||
{
|
||||
public:
|
||||
|
||||
~MPSession() override
|
||||
~MPSessionMedium() override
|
||||
{
|
||||
CarrierEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
@@ -708,14 +708,14 @@ enum class TestStatus
|
||||
Completed,
|
||||
};
|
||||
|
||||
class Integ_SimpleTest
|
||||
class SimpleTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ::testing::Test
|
||||
{
|
||||
public:
|
||||
//GM_CLASS_ALLOCATOR(Integ_SimpleTest);
|
||||
//GM_CLASS_ALLOCATOR(SimpleTest);
|
||||
|
||||
Integ_SimpleTest()
|
||||
SimpleTest()
|
||||
: m_sessionCount(0) { }
|
||||
|
||||
virtual int GetNumSessions() { return 0; }
|
||||
@@ -858,15 +858,15 @@ public:
|
||||
}
|
||||
|
||||
int m_sessionCount;
|
||||
AZStd::array<MPSession, 10> m_sessions;
|
||||
AZStd::array<MPSessionMedium, 10> m_sessions;
|
||||
AZStd::unique_ptr<DefaultSimulator> m_defaultSimulator;
|
||||
};
|
||||
|
||||
class Integ_ReplicaChunkRPCExec
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaChunkRPCExec
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaChunkRPCExec()
|
||||
ReplicaChunkRPCExec()
|
||||
: m_chunk(nullptr)
|
||||
, m_replicaId(0)
|
||||
{ }
|
||||
@@ -893,7 +893,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec)
|
||||
TEST_F(ReplicaChunkRPCExec, DISABLED_ReplicaChunkRPCExec)
|
||||
{
|
||||
RunTickLoop([this](int tick) -> TestStatus
|
||||
{
|
||||
@@ -1050,8 +1050,8 @@ int DestroyRPCChunk::s_afterDestroyFromPrimaryCalls = 0;
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Integ_ReplicaDestroyedInRPC
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaDestroyedInRPC
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
@@ -1080,7 +1080,7 @@ public:
|
||||
ReplicaId m_repId[2];
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
|
||||
TEST_F(ReplicaDestroyedInRPC, DISABLED_ReplicaDestroyedInRPC)
|
||||
{
|
||||
RunTickLoop([this](int tick)->TestStatus
|
||||
{
|
||||
@@ -1129,11 +1129,11 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
|
||||
});
|
||||
}
|
||||
|
||||
class Integ_ReplicaChunkAddWhileReplicated
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaChunkAddWhileReplicated
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaChunkAddWhileReplicated()
|
||||
ReplicaChunkAddWhileReplicated()
|
||||
: m_replica(nullptr)
|
||||
, m_chunk(nullptr)
|
||||
, m_replicaId(0)
|
||||
@@ -1161,7 +1161,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
|
||||
TEST_F(ReplicaChunkAddWhileReplicated, DISABLED_ReplicaChunkAddWhileReplicated)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1203,11 +1203,11 @@ TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaRPCValues
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaRPCValues
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaRPCValues()
|
||||
ReplicaRPCValues()
|
||||
: m_replica(nullptr)
|
||||
, m_chunk(nullptr)
|
||||
, m_replicaId(0)
|
||||
@@ -1236,7 +1236,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
|
||||
TEST_F(ReplicaRPCValues, DISABLED_ReplicaRPCValues)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1257,11 +1257,11 @@ TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
|
||||
});
|
||||
}
|
||||
|
||||
class Integ_FullRPCValues
|
||||
: public Integ_SimpleTest
|
||||
class FullRPCValues
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_FullRPCValues()
|
||||
FullRPCValues()
|
||||
: m_replica(nullptr)
|
||||
, m_chunk(nullptr)
|
||||
, m_replicaId(0)
|
||||
@@ -1290,7 +1290,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_FullRPCValues, FullRPCValues)
|
||||
TEST_F(FullRPCValues, DISABLED_FullRPCValues)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1364,11 +1364,11 @@ TEST_F(Integ_FullRPCValues, FullRPCValues)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaRemoveProxy
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaRemoveProxy
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaRemoveProxy()
|
||||
ReplicaRemoveProxy()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
{
|
||||
@@ -1395,7 +1395,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
|
||||
TEST_F(ReplicaRemoveProxy, DISABLED_ReplicaRemoveProxy)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1424,11 +1424,11 @@ TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaChunkEvents
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaChunkEvents
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaChunkEvents()
|
||||
ReplicaChunkEvents()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
, m_chunk(nullptr)
|
||||
, m_proxyChunk(nullptr)
|
||||
@@ -1463,7 +1463,7 @@ public:
|
||||
AllEventChunk::Ptr m_proxyChunk;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
|
||||
TEST_F(ReplicaChunkEvents, DISABLED_ReplicaChunkEvents)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1501,11 +1501,11 @@ TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaChunksBeyond32
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaChunksBeyond32
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaChunksBeyond32()
|
||||
ReplicaChunksBeyond32()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -1537,7 +1537,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
|
||||
TEST_F(ReplicaChunksBeyond32, DISABLED_ReplicaChunksBeyond32)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1565,11 +1565,11 @@ TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaChunkEventsDeactivate
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaChunkEventsDeactivate
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaChunkEventsDeactivate()
|
||||
ReplicaChunkEventsDeactivate()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
, m_chunk(nullptr)
|
||||
@@ -1604,7 +1604,7 @@ public:
|
||||
AllEventChunk::Ptr m_proxyChunk;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
|
||||
TEST_F(ReplicaChunkEventsDeactivate, DISABLED_ReplicaChunkEventsDeactivate)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -1649,11 +1649,11 @@ TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
|
||||
}
|
||||
|
||||
|
||||
class Integ_ReplicaDriller
|
||||
: public Integ_SimpleTest
|
||||
class ReplicaDriller
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_ReplicaDriller()
|
||||
ReplicaDriller()
|
||||
: m_replicaId(InvalidReplicaId)
|
||||
{
|
||||
}
|
||||
@@ -2007,7 +2007,7 @@ public:
|
||||
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
|
||||
}
|
||||
|
||||
~Integ_ReplicaDriller() override
|
||||
~ReplicaDriller() override
|
||||
{
|
||||
m_driller.BusDisconnect();
|
||||
}
|
||||
@@ -2016,7 +2016,7 @@ public:
|
||||
ReplicaId m_replicaId;
|
||||
};
|
||||
|
||||
TEST_F(Integ_ReplicaDriller, ReplicaDriller)
|
||||
TEST_F(ReplicaDriller, DISABLED_ReplicaDriller)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2082,11 +2082,11 @@ TEST_F(Integ_ReplicaDriller, ReplicaDriller)
|
||||
}
|
||||
|
||||
|
||||
class Integ_DataSetChangedTest
|
||||
: public Integ_SimpleTest
|
||||
class DataSetChangedTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_DataSetChangedTest()
|
||||
DataSetChangedTest()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
, m_chunk(nullptr)
|
||||
@@ -2115,7 +2115,7 @@ public:
|
||||
DataSetChunk::Ptr m_chunk;
|
||||
};
|
||||
|
||||
TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
|
||||
TEST_F(DataSetChangedTest, DISABLED_DataSetChangedTest)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2144,11 +2144,11 @@ TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
|
||||
}
|
||||
|
||||
|
||||
class Integ_CustomHandlerTest
|
||||
: public Integ_SimpleTest
|
||||
class CustomHandlerTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_CustomHandlerTest()
|
||||
CustomHandlerTest()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
, m_chunk(nullptr)
|
||||
@@ -2181,7 +2181,7 @@ public:
|
||||
AZStd::scoped_ptr<CustomHandler> m_proxyHandler;
|
||||
};
|
||||
|
||||
TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
|
||||
TEST_F(CustomHandlerTest, DISABLED_CustomHandlerTest)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2234,11 +2234,11 @@ TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
|
||||
}
|
||||
|
||||
|
||||
class Integ_NonConstMarshalerTest
|
||||
: public Integ_SimpleTest
|
||||
class NonConstMarshalerTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_NonConstMarshalerTest()
|
||||
NonConstMarshalerTest()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
, m_chunk(nullptr)
|
||||
@@ -2266,7 +2266,7 @@ public:
|
||||
NonConstMarshalerChunk::Ptr m_chunk;
|
||||
};
|
||||
|
||||
TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
|
||||
TEST_F(NonConstMarshalerTest, DISABLED_NonConstMarshalerTest)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2309,11 +2309,11 @@ TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
|
||||
}
|
||||
|
||||
|
||||
class Integ_SourcePeerTest
|
||||
: public Integ_SimpleTest
|
||||
class SourcePeerTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
Integ_SourcePeerTest()
|
||||
SourcePeerTest()
|
||||
: m_replica(nullptr)
|
||||
, m_replicaId(0)
|
||||
, m_chunk(nullptr)
|
||||
@@ -2343,7 +2343,7 @@ public:
|
||||
SourcePeerChunk::Ptr m_chunk2;
|
||||
};
|
||||
|
||||
TEST_F(Integ_SourcePeerTest, SourcePeerTest)
|
||||
TEST_F(SourcePeerTest, DISABLED_SourcePeerTest)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2404,8 +2404,8 @@ TEST_F(Integ_SourcePeerTest, SourcePeerTest)
|
||||
}
|
||||
|
||||
|
||||
class Integ_SendWithPriority
|
||||
: public Integ_SimpleTest
|
||||
class SendWithPriority
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
@@ -2438,8 +2438,8 @@ public:
|
||||
{
|
||||
public:
|
||||
ReplicaDrillerHook()
|
||||
: m_expectedSendValue(Integ_SendWithPriority::kNumReplicas)
|
||||
, m_expectedRecvValue(Integ_SendWithPriority::kNumReplicas)
|
||||
: m_expectedSendValue(SendWithPriority::kNumReplicas)
|
||||
, m_expectedRecvValue(SendWithPriority::kNumReplicas)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2495,7 +2495,7 @@ public:
|
||||
PriorityChunk::Ptr m_chunks[kNumReplicas];
|
||||
};
|
||||
|
||||
TEST_F(Integ_SendWithPriority, SendWithPriority)
|
||||
TEST_F(SendWithPriority, DISABLED_SendWithPriority)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2511,8 +2511,8 @@ TEST_F(Integ_SendWithPriority, SendWithPriority)
|
||||
}
|
||||
|
||||
|
||||
class Integ_SuspendUpdatesTest
|
||||
: public Integ_SimpleTest
|
||||
class SuspendUpdatesTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
@@ -2597,7 +2597,7 @@ public:
|
||||
unsigned int m_numRpcCalled = 0;
|
||||
};
|
||||
|
||||
TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
|
||||
TEST_F(SuspendUpdatesTest, DISABLED_SuspendUpdatesTest)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2657,7 +2657,7 @@ TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
|
||||
}
|
||||
|
||||
|
||||
class Integ_BasicHostChunkDescriptorTest
|
||||
class BasicHostChunkDescriptorTest
|
||||
: public UnitTest::GridMateMPTestFixture
|
||||
, public ::testing::Test
|
||||
{
|
||||
@@ -2694,17 +2694,17 @@ public:
|
||||
static int nProxyActivations;
|
||||
};
|
||||
};
|
||||
int Integ_BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
|
||||
int Integ_BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
|
||||
int BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
|
||||
int BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
|
||||
|
||||
TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
|
||||
TEST_F(BasicHostChunkDescriptorTest, DISABLED_BasicHostChunkDescriptorTest)
|
||||
{
|
||||
AZ_TracePrintf("GridMate", "\n");
|
||||
|
||||
// Register test chunks
|
||||
ReplicaChunkDescriptorTable::Get().RegisterChunkType<HostChunk, GridMate::BasicHostChunkDescriptor<HostChunk>>();
|
||||
|
||||
MPSession nodes[nNodes];
|
||||
MPSessionMedium nodes[nNodes];
|
||||
|
||||
// initialize transport
|
||||
int basePort = 4427;
|
||||
@@ -2791,8 +2791,8 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
|
||||
* Create and immedietly destroy primary replica
|
||||
* Test that it does not result in any network sync
|
||||
*/
|
||||
class Integ_CreateDestroyPrimary
|
||||
: public Integ_SimpleTest
|
||||
class CreateDestroyPrimary
|
||||
: public SimpleTest
|
||||
, public Debug::ReplicaDrillerBus::Handler
|
||||
{
|
||||
public:
|
||||
@@ -2827,7 +2827,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
|
||||
TEST_F(CreateDestroyPrimary, DISABLED_CreateDestroyPrimary)
|
||||
{
|
||||
RunTickLoop([this](int tick)-> TestStatus
|
||||
{
|
||||
@@ -2861,7 +2861,7 @@ TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
|
||||
* The ReplicaTarget will prevent sending more updates.
|
||||
*/
|
||||
class ReplicaACKfeedbackTestFixture
|
||||
: public Integ_SimpleTest
|
||||
: public SimpleTest
|
||||
{
|
||||
public:
|
||||
ReplicaACKfeedbackTestFixture()
|
||||
@@ -2900,7 +2900,7 @@ public:
|
||||
|
||||
size_t m_replicaBytesSentPrev = 0;
|
||||
ReplicaId m_replicaId;
|
||||
Integ_ReplicaDriller::ReplicaDrillerHook m_driller;
|
||||
ReplicaDriller::ReplicaDrillerHook m_driller;
|
||||
};
|
||||
|
||||
TEST_F(ReplicaACKfeedbackTestFixture, ReplicaACKfeedbackTest)
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
class Integ_LANSessionMatchmakingParamsTest
|
||||
class DISABLED_LANSessionMatchmakingParamsTest
|
||||
: public GridMateMPTestFixture
|
||||
, public SessionEventBus::MultiHandler
|
||||
{
|
||||
@@ -52,7 +52,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
public:
|
||||
Integ_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
|
||||
DISABLED_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
|
||||
: m_hostSession(nullptr)
|
||||
, m_clientGridMate(nullptr)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ namespace UnitTest
|
||||
AZ_TEST_ASSERT(GridMate::LANSessionServiceBus::FindFirstHandler(m_clientGridMate) != nullptr);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
~Integ_LANSessionMatchmakingParamsTest() override
|
||||
~DISABLED_LANSessionMatchmakingParamsTest() override
|
||||
{
|
||||
SessionEventBus::MultiHandler::BusDisconnect(m_gridMate);
|
||||
SessionEventBus::MultiHandler::BusDisconnect(m_clientGridMate);
|
||||
@@ -192,7 +192,7 @@ namespace UnitTest
|
||||
IGridMate* m_clientGridMate;
|
||||
};
|
||||
|
||||
class Integ_LANSessionTest
|
||||
class DISABLED_LANSessionTest
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
class TestPeerInfo
|
||||
@@ -264,7 +264,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
public:
|
||||
Integ_LANSessionTest(bool useIPv6 = false)
|
||||
DISABLED_LANSessionTest(bool useIPv6 = false)
|
||||
{
|
||||
m_driverType = useIPv6 ? Driver::BSD_AF_INET6 : Driver::BSD_AF_INET;
|
||||
m_doSessionParamsTest = k_numMachines > 1;
|
||||
@@ -290,7 +290,7 @@ namespace UnitTest
|
||||
AZ_TEST_ASSERT(LANSessionServiceBus::FindFirstHandler(m_peers[i].m_gridMate) != nullptr);
|
||||
}
|
||||
}
|
||||
~Integ_LANSessionTest() override
|
||||
~DISABLED_LANSessionTest() override
|
||||
{
|
||||
StopGridMateService<LANSessionService>(m_peers[0].m_gridMate);
|
||||
|
||||
@@ -555,15 +555,15 @@ namespace UnitTest
|
||||
bool m_doSessionParamsTest;
|
||||
};
|
||||
|
||||
class Integ_LANSessionTestIPv6
|
||||
: public Integ_LANSessionTest
|
||||
class DISABLED_LANSessionTestIPv6
|
||||
: public DISABLED_LANSessionTest
|
||||
{
|
||||
public:
|
||||
Integ_LANSessionTestIPv6()
|
||||
: Integ_LANSessionTest(true) {}
|
||||
DISABLED_LANSessionTestIPv6()
|
||||
: DISABLED_LANSessionTest(true) {}
|
||||
};
|
||||
|
||||
class Integ_LANMultipleSessionTest
|
||||
class DISABLED_LANMultipleSessionTest
|
||||
: public GridMateMPTestFixture
|
||||
, public SessionEventBus::Handler
|
||||
{
|
||||
@@ -620,7 +620,7 @@ namespace UnitTest
|
||||
m_sessions[i] = nullptr;
|
||||
}
|
||||
|
||||
Integ_LANMultipleSessionTest()
|
||||
DISABLED_LANMultipleSessionTest()
|
||||
: GridMateMPTestFixture(200 * 1024 * 1024)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -645,7 +645,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
~Integ_LANMultipleSessionTest() override
|
||||
~DISABLED_LANMultipleSessionTest() override
|
||||
{
|
||||
GridMate::StopGridMateService<GridMate::LANSessionService>(m_gridMates[0]);
|
||||
|
||||
@@ -799,7 +799,7 @@ namespace UnitTest
|
||||
* Testing session with low latency. This is special mode usually used by tools and communication channels
|
||||
* where we try to response instantly on messages.
|
||||
*/
|
||||
class Integ_LANLatencySessionTest
|
||||
class DISABLED_LANLatencySessionTest
|
||||
: public GridMateMPTestFixture
|
||||
, public SessionEventBus::Handler
|
||||
{
|
||||
@@ -857,7 +857,7 @@ namespace UnitTest
|
||||
m_sessions[i] = nullptr;
|
||||
}
|
||||
|
||||
Integ_LANLatencySessionTest()
|
||||
DISABLED_LANLatencySessionTest()
|
||||
#ifdef AZ_TEST_LANLATENCY_ENABLE_MONSTER_BUFFER
|
||||
: GridMateMPTestFixture(50 * 1024 * 1024)
|
||||
#endif
|
||||
@@ -884,7 +884,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
~Integ_LANLatencySessionTest() override
|
||||
~DISABLED_LANLatencySessionTest() override
|
||||
{
|
||||
StopGridMateService<LANSessionService>(m_gridMates[0]);
|
||||
|
||||
@@ -1162,7 +1162,7 @@ namespace UnitTest
|
||||
* 5. After host migration we drop the new host again. (after migration we have 3 members).
|
||||
* Session should be fully operational at the end with 3 members left.
|
||||
*/
|
||||
class Integ_LANSessionMigarationTestTest
|
||||
class LANSessionMigarationTestTest
|
||||
: public SessionEventBus::Handler
|
||||
, public GridMateMPTestFixture
|
||||
{
|
||||
@@ -1257,7 +1257,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
Integ_LANSessionMigarationTestTest()
|
||||
LANSessionMigarationTestTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Create all grid mates
|
||||
@@ -1283,7 +1283,7 @@ namespace UnitTest
|
||||
//StartDrilling("lanmigration");
|
||||
}
|
||||
|
||||
~Integ_LANSessionMigarationTestTest() override
|
||||
~LANSessionMigarationTestTest() override
|
||||
{
|
||||
StopGridMateService<LANSessionService>(m_gridMates[0]);
|
||||
|
||||
@@ -1476,7 +1476,7 @@ namespace UnitTest
|
||||
* 5. We join a 2 new members to the session.
|
||||
* Session should be fully operational at the end with 4 members in it.
|
||||
*/
|
||||
class Integ_LANSessionMigarationTestTest2
|
||||
class LANSessionMigarationTestTest2
|
||||
: public SessionEventBus::Handler
|
||||
, public GridMateMPTestFixture
|
||||
{
|
||||
@@ -1571,7 +1571,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
}
|
||||
Integ_LANSessionMigarationTestTest2()
|
||||
LANSessionMigarationTestTest2()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Create all grid mates
|
||||
@@ -1597,7 +1597,7 @@ namespace UnitTest
|
||||
|
||||
//StartDrilling("lanmigration2");
|
||||
}
|
||||
~Integ_LANSessionMigarationTestTest2() override
|
||||
~LANSessionMigarationTestTest2() override
|
||||
{
|
||||
StopGridMateService<LANSessionService>(m_gridMates[0]);
|
||||
|
||||
@@ -1816,7 +1816,7 @@ namespace UnitTest
|
||||
* 3. Add 2 new joins to the original session.
|
||||
* Original session should remain fully operational with 4 members in it.
|
||||
*/
|
||||
class Integ_LANSessionMigarationTestTest3
|
||||
class LANSessionMigarationTestTest3
|
||||
: public SessionEventBus::Handler
|
||||
, public GridMateMPTestFixture
|
||||
{
|
||||
@@ -1910,7 +1910,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
}
|
||||
Integ_LANSessionMigarationTestTest3()
|
||||
LANSessionMigarationTestTest3()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Create all grid mates
|
||||
@@ -1936,7 +1936,7 @@ namespace UnitTest
|
||||
//StartDrilling("lanmigration2");
|
||||
}
|
||||
|
||||
~Integ_LANSessionMigarationTestTest3() override
|
||||
~LANSessionMigarationTestTest3() override
|
||||
{
|
||||
StopGridMateService<LANSessionService>(m_gridMates[0]);
|
||||
|
||||
@@ -2122,13 +2122,13 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
GM_TEST_SUITE(SessionSuite)
|
||||
GM_TEST(Integ_LANSessionMatchmakingParamsTest)
|
||||
GM_TEST(Integ_LANSessionTest)
|
||||
GM_TEST(DISABLED_LANSessionMatchmakingParamsTest)
|
||||
GM_TEST(DISABLED_LANSessionTest)
|
||||
#if (AZ_TRAIT_GRIDMATE_TEST_SOCKET_IPV6_SUPPORT_ENABLED)
|
||||
GM_TEST(Integ_LANSessionTestIPv6)
|
||||
GM_TEST(DISABLED_LANSessionTestIPv6)
|
||||
#endif
|
||||
GM_TEST(Integ_LANMultipleSessionTest)
|
||||
GM_TEST(Integ_LANLatencySessionTest)
|
||||
GM_TEST(DISABLED_LANMultipleSessionTest)
|
||||
GM_TEST(DISABLED_LANLatencySessionTest)
|
||||
|
||||
// Manually enabled tests (require 2+ machines and online services)
|
||||
//GM_TEST(LANSessionMigarationTestTest)
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace UnitTest
|
||||
std::array<char, SIZE> m_buffer;
|
||||
};
|
||||
|
||||
class Integ_StreamSecureSocketDriverTestsBindSocketEmpty
|
||||
class DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -134,7 +134,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_StreamSecureSocketDriverTestsConnection
|
||||
class DISABLED_StreamSecureSocketDriverTestsConnection
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -146,7 +146,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld
|
||||
class DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -190,7 +190,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_StreamSecureSocketDriverTestsPingPong
|
||||
class DISABLED_StreamSecureSocketDriverTestsPingPong
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -425,13 +425,13 @@ namespace UnitTest
|
||||
|
||||
void BuildStateMachine()
|
||||
{
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
|
||||
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
|
||||
m_stateMachine.Start();
|
||||
}
|
||||
|
||||
@@ -486,10 +486,10 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
GM_TEST_SUITE(StreamSecureSocketDriverTests)
|
||||
GM_TEST(Integ_StreamSecureSocketDriverTestsBindSocketEmpty);
|
||||
GM_TEST(Integ_StreamSecureSocketDriverTestsConnection);
|
||||
GM_TEST(Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
|
||||
GM_TEST(Integ_StreamSecureSocketDriverTestsPingPong);
|
||||
GM_TEST(DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty);
|
||||
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnection);
|
||||
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
|
||||
GM_TEST(DISABLED_StreamSecureSocketDriverTestsPingPong);
|
||||
GM_TEST_SUITE_END()
|
||||
|
||||
#endif // AZ_TRAIT_GRIDMATE_ENABLE_OPENSSL
|
||||
|
||||
@@ -308,7 +308,7 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class Integ_StreamSocketDriverTestsTooManyConnections
|
||||
class DISABLED_StreamSocketDriverTestsTooManyConnections
|
||||
: public GridMateMPTestFixture
|
||||
{
|
||||
public:
|
||||
@@ -529,7 +529,7 @@ GM_TEST_SUITE(StreamSocketDriverTests)
|
||||
GM_TEST(StreamSocketDriverTestsSimpleLockStepConnection);
|
||||
GM_TEST(StreamSocketDriverTestsEstablishConnectAndSend);
|
||||
GM_TEST(StreamSocketDriverTestsManyRandomPackets);
|
||||
GM_TEST(Integ_StreamSocketDriverTestsTooManyConnections);
|
||||
GM_TEST(DISABLED_StreamSocketDriverTestsTooManyConnections);
|
||||
GM_TEST(StreamSocketDriverTestsClientToInvalidServer);
|
||||
GM_TEST(StreamSocketDriverTestsManySends);
|
||||
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "Tests.h"
|
||||
#include "TestProfiler.h"
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
|
||||
#include <GridMate/Containers/set.h>
|
||||
#include <GridMate/Containers/unordered_set.h>
|
||||
|
||||
using namespace GridMate;
|
||||
|
||||
typedef set<const AZ::Debug::ProfilerRegister*> ProfilerSet;
|
||||
|
||||
static bool CollectPerformanceCounters(const AZ::Debug::ProfilerRegister& reg, const AZStd::thread_id&, ProfilerSet& profilers, const char* systemId)
|
||||
{
|
||||
if (reg.m_type != AZ::Debug::ProfilerRegister::PRT_TIME)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (reg.m_systemId != AZ::Crc32(systemId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const AZ::Debug::ProfilerRegister* profReg = ®
|
||||
profilers.insert(profReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static AZStd::string FormatString(const AZStd::string& pre, const AZStd::string& name, const AZStd::string& post, AZ::u64 time, AZ::u64 calls)
|
||||
{
|
||||
AZStd::string units = "us";
|
||||
if (AZ::u64 divtime = time / 1000)
|
||||
{
|
||||
time = divtime;
|
||||
units = "ms";
|
||||
}
|
||||
return AZStd::string::format("%s%s %s %10llu%s (%llu calls)\n", pre.c_str(), name.c_str(), post.c_str(), time, units.c_str(), calls);
|
||||
}
|
||||
|
||||
struct TotalSortContainer
|
||||
{
|
||||
TotalSortContainer(const AZ::Debug::ProfilerRegister* self = nullptr)
|
||||
{
|
||||
m_self = self;
|
||||
}
|
||||
|
||||
void Print(AZ::s32 level, const char* systemId)
|
||||
{
|
||||
if (m_self && level >= 0)
|
||||
{
|
||||
AZStd::string levelIndent;
|
||||
for (AZ::s32 i = 0; i < level; i++)
|
||||
{
|
||||
levelIndent += (i == level - 1) ? "+---" : "| ";
|
||||
}
|
||||
AZStd::string name = m_self->m_name ? m_self->m_name : m_self->m_function;
|
||||
AZStd::string outputTotal = FormatString(levelIndent, name, " Total:", m_self->m_timeData.m_time, m_self->m_timeData.m_calls);
|
||||
AZ_Printf(systemId, outputTotal.c_str());
|
||||
|
||||
if (m_self->m_timeData.m_childrenTime || m_self->m_timeData.m_childrenCalls)
|
||||
{
|
||||
AZStd::string childIndent = levelIndent;
|
||||
for (auto i = name.begin(); i != name.end(); ++i)
|
||||
{
|
||||
childIndent += " ";
|
||||
}
|
||||
childIndent[level * 4] = '|';
|
||||
|
||||
AZStd::string outputChild = FormatString(childIndent, "", "Child:", m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_childrenCalls);
|
||||
AZ_Printf(systemId, outputChild.c_str());
|
||||
|
||||
AZStd::string outputSelf = FormatString(childIndent, "", "Self :", m_self->m_timeData.m_time - m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_calls);
|
||||
AZ_Printf(systemId, outputSelf.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = m_children.begin(); i != m_children.end(); ++i)
|
||||
{
|
||||
i->Print(level + 1, systemId);
|
||||
}
|
||||
}
|
||||
|
||||
TotalSortContainer* Find(const AZ::Debug::ProfilerRegister* obj)
|
||||
{
|
||||
if (m_self == obj)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
for (TotalSortContainer& child : m_children)
|
||||
{
|
||||
TotalSortContainer* found = child.Find(obj);
|
||||
if (found)
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct TotalSorter
|
||||
{
|
||||
bool operator()(const TotalSortContainer& a, const TotalSortContainer& b) const
|
||||
{
|
||||
if (a.m_self->m_timeData.m_time == b.m_self->m_timeData.m_time)
|
||||
{
|
||||
return a.m_self > b.m_self;
|
||||
}
|
||||
return a.m_self->m_timeData.m_time > b.m_self->m_timeData.m_time;
|
||||
}
|
||||
};
|
||||
set<TotalSortContainer, TotalSorter> m_children;
|
||||
const AZ::Debug::ProfilerRegister* m_self;
|
||||
};
|
||||
|
||||
void TestProfiler::StartProfiling()
|
||||
{
|
||||
StopProfiling();
|
||||
|
||||
AZ::Debug::Profiler::Create();
|
||||
}
|
||||
|
||||
void TestProfiler::StopProfiling()
|
||||
{
|
||||
if (AZ::Debug::Profiler::IsReady())
|
||||
{
|
||||
AZ::Debug::Profiler::Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void TestProfiler::PrintProfilingTotal(const char* systemId)
|
||||
{
|
||||
if (!AZ::Debug::Profiler::IsReady())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProfilerSet profilers;
|
||||
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
|
||||
|
||||
// Validate we wont get stuck in an infinite loop
|
||||
TotalSortContainer root;
|
||||
for (auto i = profilers.begin(); i != profilers.end(); )
|
||||
{
|
||||
const AZ::Debug::ProfilerRegister* profile = *i;
|
||||
if (profile->m_timeData.m_lastParent)
|
||||
{
|
||||
auto parent = profilers.find(profile->m_timeData.m_lastParent);
|
||||
if (parent == profilers.end())
|
||||
{
|
||||
// Error, just ignore this entry
|
||||
i = profilers.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// Put all root nodes into the final list
|
||||
for (auto i = profilers.begin(); i != profilers.end(); )
|
||||
{
|
||||
const AZ::Debug::ProfilerRegister* profile = *i;
|
||||
if (!profile->m_timeData.m_lastParent)
|
||||
{
|
||||
root.m_children.insert(profile);
|
||||
i = profilers.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Put all non-root nodes into the final list
|
||||
while (!profilers.empty())
|
||||
{
|
||||
for (auto i = profilers.begin(); i != profilers.end(); )
|
||||
{
|
||||
const AZ::Debug::ProfilerRegister* profile = *i;
|
||||
TotalSortContainer* found = root.Find(profile->m_timeData.m_lastParent);
|
||||
if (found)
|
||||
{
|
||||
found->m_children.insert(profile);
|
||||
i = profilers.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Printf(systemId, "Profiling timers by total execution time:\n");
|
||||
root.Print(-1, systemId);
|
||||
}
|
||||
|
||||
void TestProfiler::PrintProfilingSelf(const char* systemId)
|
||||
{
|
||||
if (!AZ::Debug::Profiler::IsReady())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProfilerSet profilers;
|
||||
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
|
||||
|
||||
struct SelfSorter
|
||||
{
|
||||
bool operator()(const AZ::Debug::ProfilerRegister* a, const AZ::Debug::ProfilerRegister* b) const
|
||||
{
|
||||
auto aTime = a->m_timeData.m_time - a->m_timeData.m_childrenTime;
|
||||
auto bTime = b->m_timeData.m_time - b->m_timeData.m_childrenTime;
|
||||
|
||||
if (aTime == bTime)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
return aTime > bTime;
|
||||
}
|
||||
};
|
||||
|
||||
set<const AZ::Debug::ProfilerRegister*, SelfSorter> selfSorted;
|
||||
for (auto& profiler : profilers)
|
||||
{
|
||||
selfSorted.insert(profiler);
|
||||
}
|
||||
|
||||
AZ_Printf(systemId, "Profiling timers by exclusive execution time:\n");
|
||||
for (auto profiler : selfSorted)
|
||||
{
|
||||
AZStd::string str = FormatString("", profiler->m_name ? profiler->m_name : profiler->m_function, "Self Time:",
|
||||
profiler->m_timeData.m_time - profiler->m_timeData.m_childrenTime, profiler->m_timeData.m_calls);
|
||||
AZ_Printf(systemId, str.c_str());
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef GM_TEST_PROFILER_H
|
||||
#define GM_TEST_PROFILER_H
|
||||
|
||||
namespace GridMate
|
||||
{
|
||||
class TestProfiler
|
||||
{
|
||||
public:
|
||||
static void StartProfiling();
|
||||
static void StopProfiling();
|
||||
|
||||
static void PrintProfilingTotal(const char* systemId);
|
||||
static void PrintProfilingSelf(const char* systemId);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@ set(FILES
|
||||
Session.cpp
|
||||
Serialize.cpp
|
||||
Certificates.cpp
|
||||
Replica.cpp
|
||||
ReplicaSmall.cpp
|
||||
ReplicaMedium.cpp
|
||||
ReplicaBehavior.cpp
|
||||
|
||||
@@ -291,6 +291,9 @@ namespace AssetBundler
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
AZ::Debug::Trace::HandleExceptions(true);
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv);
|
||||
|
||||
INVOKE_AZ_UNIT_TEST_MAIN();
|
||||
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace UnitTests
|
||||
|
||||
auto result = m_data->m_reporter->ComputeDestination(entryContainer, m_data->m_platformConfig.GetScanFolderByPath(scanFolderEntry.m_scanFolder.c_str()), source, destination, destInfo);
|
||||
|
||||
ASSERT_EQ(result.IsSuccess(), expectSuccess) << result.GetError().c_str();
|
||||
ASSERT_EQ(result.IsSuccess(), expectSuccess) << (!result.IsSuccess() ? result.GetError().c_str() : "");
|
||||
|
||||
if (expectSuccess)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,9 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "1");
|
||||
|
||||
AZ::Debug::Trace::HandleExceptions(true);
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv);
|
||||
|
||||
// If "--unittest" is present on the command line, run unit testing
|
||||
// and return immediately. Otherwise, continue as normal.
|
||||
AZ::Test::addTestEnvironment(new BaseAssetProcessorTestEnvironment());
|
||||
|
||||
@@ -18,45 +18,35 @@ namespace AzTestRunner
|
||||
const int LIB_NOT_FOUND = 102;
|
||||
const int SYMBOL_NOT_FOUND = 103;
|
||||
|
||||
// note that MODULE_SKIPPED is not an error condition, but not 0 to indicate its not the
|
||||
// same as successfully running tests and finding them.
|
||||
const int MODULE_SKIPPED = 104;
|
||||
const char* INTEG_BOOTSTRAP = "AzTestIntegBootstrap";
|
||||
|
||||
//! display proper usage of the application
|
||||
void usage([[maybe_unused]] AZ::Test::Platform& platform)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"AzTestRunner\n"
|
||||
"Runs AZ unit and integration tests. Exit code is the result from GoogleTest.\n"
|
||||
"Runs AZ tests. Exit code is the result from GoogleTest.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunIntegTests) [--integ] [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
|
||||
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunBenchmarks) [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" <lib>: the module to test\n"
|
||||
" <hook>: the name of the aztest hook function to run in the <lib>\n"
|
||||
" 'AzRunUnitTests' will hook into unit tests\n"
|
||||
" 'AzRunIntegTests' will hook into integration tests\n"
|
||||
" --integ: tells runner to bootstrap the engine, needed for integration tests\n"
|
||||
" Note: you can run unit tests with a bootstrapped engine (AzRunUnitTests --integ),\n"
|
||||
" but running integration tests without a bootstrapped engine (AzRunIntegTests w/ no --integ) might not work.\n"
|
||||
" 'AzRunBenchmarks' will hook into benchmark tests\n"
|
||||
" --wait-for-debugger: tells runner to wait for debugger to attach to process (on supported platforms)\n"
|
||||
" --pause-on-completion: tells the runner to pause after running the tests\n"
|
||||
" --quiet: disables stdout for minimal output while running tests\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
" AzTestRunner.exe CrySystem.dll AzRunUnitTests --pause-on-completion\n"
|
||||
" AzTestRunner.exe CrySystem.dll AzRunIntegTests --integ\n"
|
||||
" AzTestRunner.exe AzCore.Tests.dll AzRunUnitTests --pause-on-completion\n"
|
||||
"\n"
|
||||
"Exit Codes:\n"
|
||||
" 0 - all tests pass\n"
|
||||
" 1 - test failure\n"
|
||||
<< " " << INCORRECT_USAGE << " - incorrect usage (see above)\n"
|
||||
<< " " << LIB_NOT_FOUND << " - library/dll could not be loaded\n"
|
||||
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n"
|
||||
<< " " << MODULE_SKIPPED << " - non-integ module was skipped (not an error)\n";
|
||||
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n";
|
||||
|
||||
std::cerr << ss.str() << std::endl;
|
||||
}
|
||||
@@ -82,7 +72,6 @@ namespace AzTestRunner
|
||||
|
||||
// capture optional arguments
|
||||
bool waitForDebugger = false;
|
||||
bool isInteg = false;
|
||||
bool pauseOnCompletion = false;
|
||||
bool quiet = false;
|
||||
for (int i = 0; i < argc; i++)
|
||||
@@ -93,12 +82,6 @@ namespace AzTestRunner
|
||||
AZ::Test::RemoveParameters(argc, argv, i, i);
|
||||
i--;
|
||||
}
|
||||
else if (strcmp(argv[i], "--integ") == 0)
|
||||
{
|
||||
isInteg = true;
|
||||
AZ::Test::RemoveParameters(argc, argv, i, i);
|
||||
i--;
|
||||
}
|
||||
else if (strcmp(argv[i], "--pause-on-completion") == 0)
|
||||
{
|
||||
pauseOnCompletion = true;
|
||||
@@ -172,47 +155,11 @@ namespace AzTestRunner
|
||||
if (result != 0)
|
||||
{
|
||||
module.reset();
|
||||
|
||||
if ((isInteg) && (result == SYMBOL_NOT_FOUND))
|
||||
{
|
||||
// special case: It is not required to put an INTEG test inside every DLL - so if
|
||||
// we failed to find the INTEG entry point in this DLL, its not an error.
|
||||
// its only an error if we find it and there are no tests, or we find it and tests actually
|
||||
// fail.
|
||||
std::cerr << "INTEG module has no entry point and will be skipped: " << lib << std::endl;
|
||||
return MODULE_SKIPPED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
platform.SuppressPopupWindows();
|
||||
|
||||
// Grab a bootstrapper library if requested
|
||||
std::shared_ptr<AZ::Test::IModuleHandle> bootstrap;
|
||||
if (isInteg)
|
||||
{
|
||||
bootstrap = platform.GetModule(INTEG_BOOTSTRAP);
|
||||
if (!bootstrap->IsValid())
|
||||
{
|
||||
std::cerr << "FAILED to load bootstrapper" << std::endl;
|
||||
return LIB_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Initialize the bootstrapper
|
||||
auto init = bootstrap->GetFunction("Initialize");
|
||||
if (init->IsValid())
|
||||
{
|
||||
int initResult = (*init)();
|
||||
if (initResult != 0)
|
||||
{
|
||||
std::cerr << "Bootstrapper Initialize failed with code " << initResult << ", exiting" << std::endl;
|
||||
return initResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// run the test main function.
|
||||
if (testMainFunction->IsValid())
|
||||
{
|
||||
@@ -231,22 +178,6 @@ namespace AzTestRunner
|
||||
// system allocator / etc.
|
||||
module.reset();
|
||||
|
||||
// Shutdown the bootstrapper
|
||||
if (bootstrap)
|
||||
{
|
||||
auto shutdown = bootstrap->GetFunction("Shutdown");
|
||||
if (shutdown->IsValid())
|
||||
{
|
||||
int shutdownResult = (*shutdown)();
|
||||
if (shutdownResult != 0)
|
||||
{
|
||||
std::cerr << "Bootstrapper shutdown failed with code " << shutdownResult << ", exiting" << std::endl;
|
||||
return shutdownResult;
|
||||
}
|
||||
}
|
||||
bootstrap.reset();
|
||||
}
|
||||
|
||||
if (pauseOnCompletion)
|
||||
{
|
||||
AzTestRunner::pause_on_completion();
|
||||
@@ -258,6 +189,8 @@ namespace AzTestRunner
|
||||
|
||||
int wrapped_main(int argc/*=0*/, char** argv/*=nullptr*/)
|
||||
{
|
||||
AZ::Debug::Trace::HandleExceptions(true);
|
||||
|
||||
if (argc>0 && argv!=nullptr)
|
||||
{
|
||||
return wrapped_command_arg_main(argc, argv);
|
||||
|
||||
@@ -18,6 +18,9 @@ int runDefaultRunner(int argc, char* argv[])
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
AZ::Debug::Trace::HandleExceptions(true);
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv);
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
// if no parameters are provided, add the --unittests parameter
|
||||
|
||||
@@ -23,6 +23,9 @@ int runDefaultRunner(int argc, char* argv[])
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
AZ::Debug::Trace::HandleExceptions(true);
|
||||
AZ::Test::ApplyGlobalParameters(&argc, argv);
|
||||
|
||||
// ran with no parameters?
|
||||
if (argc == 1)
|
||||
{
|
||||
|
||||
-76
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
#include "JitterTablePcf.azsli"
|
||||
#include "Shadow.azsli"
|
||||
#include "ShadowmapAtlasLib.azsli"
|
||||
#include "BicubicPcfFilters.azsli"
|
||||
@@ -82,12 +81,6 @@ class DirectionalLightShadow
|
||||
// result.y == true if the given coordinate is in shadow.
|
||||
bool2 IsShadowed(float3 shadowCoord, uint indexOfCascade);
|
||||
|
||||
// This checks if the point is shadowed or not for the given center coordinate and jitter.
|
||||
bool IsShadowedWithJitter(
|
||||
float3 jitterUnit,
|
||||
float jitterDepthDiffBase,
|
||||
uint jitterIndex);
|
||||
|
||||
// This outputs visibility ratio (from 0.0 to 1.0) of the given coordinate
|
||||
// from the light origin without filtering.
|
||||
float GetVisibilityFromLightNoFilter();
|
||||
@@ -189,75 +182,6 @@ bool2 DirectionalLightShadow::IsShadowed(float3 shadowCoord, uint indexOfCascade
|
||||
return bool2(false, false);
|
||||
}
|
||||
|
||||
bool DirectionalLightShadow::IsShadowedWithJitter(
|
||||
float3 jitterUnit,
|
||||
float jitterDepthDiffBase,
|
||||
uint jitterIndex)
|
||||
{
|
||||
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
|
||||
const float4x4 worldToLightViewMatrices[ViewSrg::MaxCascadeCount] =
|
||||
ViewSrg::m_directionalLightShadows[m_lightIndex].m_worldToLightViewMatrices;
|
||||
const float4x4 lightViewToShadowmapMatrices[ViewSrg::MaxCascadeCount] =
|
||||
ViewSrg::m_directionalLightShadows[m_lightIndex].m_lightViewToShadowmapMatrices;
|
||||
const float boundaryScale =
|
||||
ViewSrg::m_directionalLightShadows[m_lightIndex].m_boundaryScale;
|
||||
|
||||
const float2 jitterXY = g_jitterTablePcf[jitterIndex];
|
||||
|
||||
// jitterLightView is the jittering diff vector from the lighted point on the surface
|
||||
// in the light view space. It is remarked as "v_J" in the comment
|
||||
// named "Calculate depth adjusting diff for jittered samples"
|
||||
// just before the function GetJitterUnitVectorDepthDiffBase.
|
||||
const float4 jitterLightView = float4(jitterXY, 0., 0.) * boundaryScale;
|
||||
|
||||
// It checks the jittered point is lit or shadowed from the detailed cascade
|
||||
// to the less detailed one.
|
||||
for (uint indexOfCascade = 0; indexOfCascade < cascadeCount; ++indexOfCascade)
|
||||
{
|
||||
// jitterShadowmap is the jittering diff vector in the shadowmap space.
|
||||
const float4 jitterShadowmap = mul(lightViewToShadowmapMatrices[indexOfCascade], jitterLightView);
|
||||
|
||||
// Calculation of the jittering for Z-coordinate (light direction) is required
|
||||
// to check lit/shadowed for the jittered point.
|
||||
// jitterDepthDiff is the Z-coordinate of the jittering diff vector
|
||||
// in the shadowmap space.
|
||||
float jitterDepthDiff = 0.;
|
||||
|
||||
// jitterDepthDiffBase is "1/tan(theta)" in the comment.
|
||||
if (jitterDepthDiffBase != 0.)
|
||||
{
|
||||
// jitterUnitLightView is the unit vector in the light view space
|
||||
// noted as "v_M" in the comment.
|
||||
const float3 jitterUnitLightView =
|
||||
normalize(mul(worldToLightViewMatrices[indexOfCascade], float4(jitterUnit, 0.)).xyz);
|
||||
const float lightViewToShadowmapZScale = -lightViewToShadowmapMatrices[indexOfCascade]._m22;
|
||||
// jitterDepthDiff is the "d" in the note, and it is calculated by
|
||||
// d = (v_J . v_M) / tan(theta)
|
||||
// in the light view space. Furthermore it have to be converted
|
||||
// to the light clip space, which can be done by lightViewToShadowmapZScale.
|
||||
jitterDepthDiff =
|
||||
dot(jitterLightView.xyz, jitterUnitLightView) * jitterDepthDiffBase *
|
||||
lightViewToShadowmapZScale;
|
||||
}
|
||||
// jitteredCoord is the coordinate of the jittered point in the shadowmap space.
|
||||
const float3 jitteredCoord =
|
||||
m_shadowCoords[indexOfCascade] + float3(jitterShadowmap.xy, jitterDepthDiff);
|
||||
// Check for the jittered point is lit or shadowed.
|
||||
const bool2 checkedShadowed = IsShadowed(
|
||||
jitteredCoord,
|
||||
indexOfCascade);
|
||||
// If check is done, return the lit/shadowed flag.
|
||||
// Otherwise make it pend to the next cascade.
|
||||
if (checkedShadowed.x)
|
||||
{
|
||||
m_debugInfo.m_cascadeIndex = indexOfCascade;
|
||||
return checkedShadowed.y;
|
||||
}
|
||||
}
|
||||
m_debugInfo.m_cascadeIndex = cascadeCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
float DirectionalLightShadow::GetVisibilityFromLightNoFilter()
|
||||
{
|
||||
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
The following is the output of
|
||||
$ python3 pcf_jitter_table.py 6 g_jitterTablePcf 0
|
||||
where pcf_jitter_table.py has the following contents.
|
||||
|
||||
@code
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import random
|
||||
import sys
|
||||
import math
|
||||
|
||||
|
||||
""" Returns if a point in the range
|
||||
[radius_min, radius_sup)*[angle_min, angle_sup)
|
||||
is contained in the tuple polar coordinates.
|
||||
"""
|
||||
def is_point_include(radius_min, radius_sup, angle_min, angle_sup, polars):
|
||||
for polar in polars:
|
||||
if (radius_min <= polar[0] and polar[0] < radius_sup and
|
||||
angle_min <= polar[1] and polar[1] < angle_sup):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
""" Insert a randomly generated polar coordianted point in each
|
||||
range [r0, r1)*[a0, a1) if there has not been such a point
|
||||
in tuple coords yet, where [0, 1)*[0, 2pi) is divided
|
||||
into the rad_count*agl_count ranges.
|
||||
"""
|
||||
def add_jitter_coords(radius_count, angle_count, polars):
|
||||
radius_base = 1.0 / math.sqrt(radius_count)
|
||||
for radius_index in range(radius_count):
|
||||
# range of radius
|
||||
radius_min = math.sqrt(radius_index) * radius_base
|
||||
radius_sup = math.sqrt(radius_index + 1) * radius_base
|
||||
|
||||
# randomize angle order
|
||||
random_state = random.getstate()
|
||||
angle_indices = list(range(angle_count))
|
||||
random.shuffle(angle_indices)
|
||||
random.setstate(random_state)
|
||||
|
||||
for angle_index in angle_indices:
|
||||
# range of angle
|
||||
angle_min = 2 * math.pi * angle_index / angle_count
|
||||
angle_sup = 2 * math.pi * (angle_index + 1) / angle_count
|
||||
|
||||
# if no point in the radius/angle range, add a new point
|
||||
if not is_point_include(radius_min, radius_sup,
|
||||
angle_min, angle_sup,
|
||||
polars):
|
||||
radius = radius_min + (radius_sup - radius_min) * random.random()
|
||||
angle = angle_min + (angle_sup - angle_min) * random.random()
|
||||
polars += [[radius, angle]]
|
||||
|
||||
|
||||
""" Return a formatted string readable as an array of
|
||||
orthogonal coordinated points which are in inside of the unit disk.
|
||||
"""
|
||||
def conv_array_string(polars):
|
||||
result = "{\n"
|
||||
for [radius, angle] in polars:
|
||||
x = radius * math.cos(angle)
|
||||
y = radius * math.sin(angle)
|
||||
result += str.format(" float2({: 1.20e}, {: 1.20e}),\n", x, y)
|
||||
result = result.rstrip(",\n") + "\n};\n"
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rad_size = 1
|
||||
ang_size = 1
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
random_seed = int(sys.argv[3])
|
||||
else:
|
||||
random_seed = 0
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
array_name = sys.argv[2]
|
||||
else:
|
||||
array_name = False
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
len_log = int(sys.argv[1])
|
||||
else:
|
||||
print(" usage: {} array_len_log2 [array_file_name] [random_seed]".format(__file__))
|
||||
print(" array_len_log2 = 2 -> array length = 4")
|
||||
print(" array_len_log2 = 6 -> array length = 64")
|
||||
sys.exit()
|
||||
|
||||
random.seed(random_seed)
|
||||
coords = []
|
||||
add_jitter_coords(rad_size, ang_size, coords)
|
||||
for index in range(len_log):
|
||||
if index % 2 == 0:
|
||||
rad_size *= 2
|
||||
else:
|
||||
ang_size *= 2
|
||||
add_jitter_coords(rad_size, ang_size, coords)
|
||||
|
||||
if array_name:
|
||||
print(str.format("static const float2 {}[{}] =", array_name, len(coords)))
|
||||
print(conv_array_string(coords))
|
||||
|
||||
@endcode
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const float2 g_jitterTablePcf[64] =
|
||||
{
|
||||
float2( 4.21857815578105532772e-02, -8.43367430701083664601e-01),
|
||||
float2(-1.66526814909220763350e-02, 2.96922406531470617352e-01),
|
||||
float2(-1.06374665780382349212e-01, -3.45521852905696924552e-01),
|
||||
float2( 5.42648241814168375008e-01, 7.63475573328278533936e-01),
|
||||
float2(-1.55045122122251910479e-01, 5.78282315712970729216e-01),
|
||||
float2( 1.01310018770242576264e-02, -6.88001749851880561870e-01),
|
||||
float2(-5.41276603451248283783e-01, 5.21888233660957712168e-01),
|
||||
float2(-6.69885071867917680777e-01, -6.72019666097878665134e-01),
|
||||
float2( 1.22985029409499718039e-02, 4.54706838949524849713e-01),
|
||||
float2( 4.00334354168925599105e-01, -6.20112671104014120949e-02),
|
||||
float2( 2.32326155804074424571e-01, 5.14183027524470093184e-01),
|
||||
float2(-3.26788693165450228051e-01, -6.03339478694129849323e-01),
|
||||
float2( 7.72374386126136736053e-01, 1.23204314299169448432e-01),
|
||||
float2(-4.45379212004159807936e-01, -6.35591042627205338178e-01),
|
||||
float2( 9.86986293787213919693e-01, -5.18195017297516449806e-02),
|
||||
float2(-9.09197225477999193544e-01, 1.95281945570711268356e-01),
|
||||
float2( 8.78123785413316704229e-02, -2.77671865082058690055e-02),
|
||||
float2( 1.93947312440399088906e-01, 4.27852204081567363825e-03),
|
||||
float2(-2.06133675819526185347e-01, -1.49183652412411493771e-01),
|
||||
float2(-4.11351098583102647854e-01, 2.36214692717993696158e-01),
|
||||
float2( 3.50058750095615767162e-01, -3.57193658067260721989e-01),
|
||||
float2(-5.54174780014121681759e-01, -2.23361040823672196698e-01),
|
||||
float2(-6.29913348094886860196e-01, 1.29962593232600148729e-01),
|
||||
float2( 3.96119563669521335125e-01, 4.90495219155295036906e-01),
|
||||
float2( 7.26077464944819728210e-01, -3.70531027878536270426e-02),
|
||||
float2(-5.50726266551596621568e-01, 6.48997654184258587762e-01),
|
||||
float2(-6.98067624269093189859e-01, -3.83843898992943299842e-01),
|
||||
float2( 8.72900706885875177221e-02, 8.24287559846993866941e-01),
|
||||
float2( 6.65413234189638491678e-01, -5.66029707430476647367e-01),
|
||||
float2(-5.97071574457786802270e-01, -6.93417220711863180327e-01),
|
||||
float2( 6.09778569514949131403e-01, 6.92279483269558570946e-01),
|
||||
float2(-8.10051800827623957879e-01, 5.82366304247235455627e-01),
|
||||
float2(-8.77200948157437071506e-02, -1.88326609190753474499e-01),
|
||||
float2( 9.79306884403889771340e-02, 1.86693151785678163046e-01),
|
||||
float2( 4.60071424048798319206e-02, -1.98255149016034859510e-01),
|
||||
float2(-5.37585860722621794450e-02, 3.99205315590760584366e-02),
|
||||
float2( 2.18621803321778829243e-01, -3.85632280444686503795e-01),
|
||||
float2(-2.98409571230789372187e-02, 4.22286693608096730390e-01),
|
||||
float2( 3.58654757584850270025e-01, 2.95175871390239985548e-01),
|
||||
float2(-3.85631921979480485341e-01, -3.00322047091407640096e-01),
|
||||
float2( 4.49800763439369810648e-01, 3.98492182500493397068e-01),
|
||||
float2(-4.97878650048238891035e-01, 2.57984038389083569776e-01),
|
||||
float2(-3.12055242602567339816e-01, -4.88013525550807125697e-01),
|
||||
float2( 5.87078632117718268724e-01, -6.97256834327608099322e-02),
|
||||
float2( 6.23692403999373534695e-01, 3.11519734097943645779e-01),
|
||||
float2( 6.64426445690903810792e-01, -2.27661844509491811950e-01),
|
||||
float2(-3.24662942872471160793e-01, 5.68939932480760024447e-01),
|
||||
float2(-5.31263995010459511015e-01, -4.66108719959298256619e-01),
|
||||
float2( 5.10323549430644951563e-01, 5.81027848262460677731e-01),
|
||||
float2( 2.82695533021593392586e-01, -7.03582425015577883620e-01),
|
||||
float2(-5.98419541732174709026e-01, -4.68015982003612274198e-01),
|
||||
float2(-3.95281650646674975746e-01, 6.10614720709622194050e-01),
|
||||
float2( 7.87454411900813555647e-01, 1.37726315874787758053e-01),
|
||||
float2(-7.36310249594224086600e-01, 4.25723821775386646049e-01),
|
||||
float2( 6.48232481978769037312e-01, -5.53108138515975955585e-01),
|
||||
float2(-1.88558544306507869237e-01, -7.79120748356531223067e-01),
|
||||
float2(-3.78614630625567993860e-01, 7.82366459873827913007e-01),
|
||||
float2(-8.48582606942172357201e-01, -3.78504015913022351381e-01),
|
||||
float2( 1.91472859899175090748e-02, -9.13050020447597532325e-01),
|
||||
float2( 8.08826910050883585157e-01, 4.17202663034078935489e-01),
|
||||
float2(-9.27062588380768493046e-01, -2.94160352051227980130e-01),
|
||||
float2( 6.67882607007592055126e-01, -6.88642020601400450808e-01),
|
||||
float2(-1.59349274307943010454e-02, 9.37629353656756814317e-01),
|
||||
float2( 9.86975590293644233775e-01, 1.44401793964158337014e-01)
|
||||
};
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <Atom/Features/Shadow/ShadowmapAtlasLib.azsli>
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "BicubicPcfFilters.azsli"
|
||||
#include "JitterTablePcf.azsli"
|
||||
#include "Shadow.azsli"
|
||||
|
||||
// ProjectedShadow calculates shadowed area projected from a light.
|
||||
@@ -44,11 +43,6 @@ class ProjectedShadow
|
||||
float GetThickness();
|
||||
|
||||
bool IsShadowed(float3 shadowPosition);
|
||||
bool IsShadowedWithJitter(
|
||||
float3 jitterUnitX,
|
||||
float3 jitterUnitY,
|
||||
float jitterDepthDiffBase,
|
||||
uint jitterIndex);
|
||||
void SetShadowPosition();
|
||||
float3 GetAtlasPosition(float2 texturePosition);
|
||||
static float UnprojectDepth(uint shadowIndex, float depthBufferValue);
|
||||
@@ -321,35 +315,6 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProjectedShadow::IsShadowedWithJitter(
|
||||
float3 jitterUnitX,
|
||||
float3 jitterUnitY,
|
||||
float jitterDepthDiffBase,
|
||||
uint jitterIndex)
|
||||
{
|
||||
ViewSrg::ProjectedShadow shadow = ViewSrg::m_projectedShadows[m_shadowIndex];
|
||||
const float4x4 depthBiasMatrix = shadow.m_depthBiasMatrix;
|
||||
const float boundaryScale = shadow.m_boundaryScale;
|
||||
|
||||
const float2 jitterXY = g_jitterTablePcf[jitterIndex];
|
||||
|
||||
const float dist = distance(m_worldPosition, m_viewPosition);
|
||||
const float boundaryRadius = dist * tan(boundaryScale);
|
||||
// jitterWorldXY is the jittering diff vector from the lighted point on the surface
|
||||
// in the world space. It is remarked as "v_J" in the comment
|
||||
// named "Calculate depth adjusting diff for jittered samples"
|
||||
// just before the function GetJitterUnitVectorDepthDiffBase.
|
||||
const float3 jitterWorldXY = jitterUnitX * (jitterXY.x * boundaryRadius) + jitterUnitY * (jitterXY.y * boundaryRadius);
|
||||
// The adjusting diff of depth ("d" in the comment) is calculated by
|
||||
// jitterXY.y * boundaryRadius * jitterDepthDiffBase.
|
||||
const float3 jitterWorldZ = m_lightDirection * (jitterXY.y * boundaryRadius * jitterDepthDiffBase);
|
||||
|
||||
const float3 jitteredWorldPosition = m_worldPosition + jitterWorldXY + jitterWorldZ;
|
||||
const float4 jitteredShadowmapHomogeneous = mul(depthBiasMatrix, float4(jitteredWorldPosition, 1));
|
||||
|
||||
return IsShadowed(jitteredShadowmapHomogeneous.xyz / jitteredShadowmapHomogeneous.w);
|
||||
}
|
||||
|
||||
void ProjectedShadow::SetShadowPosition()
|
||||
{
|
||||
const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix;
|
||||
|
||||
@@ -23,14 +23,11 @@ struct FilterParameter
|
||||
uint m_isEnabled;
|
||||
uint2 m_shadowmapOriginInSlice;
|
||||
uint m_shadowmapSize;
|
||||
uint m_parameterOffset;
|
||||
uint m_parameterCount;
|
||||
float m_lightDistanceOfCameraViewFrustum;
|
||||
float m_n_f_n; // n / (f - n)
|
||||
float m_n_f; // n - f
|
||||
float m_f; // f
|
||||
// where n: nearDepth, f: farDepth.
|
||||
float2 m_padding; // explicit padding
|
||||
};
|
||||
|
||||
class Shadow
|
||||
|
||||
@@ -22,14 +22,11 @@ partial ShaderResourceGroup ViewSrg
|
||||
uint m_isEnabled;
|
||||
uint2 m_shadowmapOriginInSlice;
|
||||
uint m_shadowmapSize;
|
||||
uint m_parameterOffset;
|
||||
uint m_parameterCount;
|
||||
float m_lightDistanceOfCameraViewFrustum;
|
||||
float m_n_f_n; // n / (f - n)
|
||||
float m_n_f; // n - f
|
||||
float m_f; // f
|
||||
// where n: nearDepth, f: farDepth.
|
||||
float2 m_padding; // explicit padding
|
||||
};
|
||||
|
||||
// Simple Point Lights
|
||||
|
||||
@@ -286,7 +286,6 @@ set(FILES
|
||||
ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli
|
||||
ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli
|
||||
ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli
|
||||
ShaderLib/Atom/Features/Shadow/JitterTablePcf.azsli
|
||||
ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli
|
||||
ShaderLib/Atom/Features/Shadow/Shadow.azsli
|
||||
ShaderLib/Atom/Features/Shadow/ShadowmapAtlasLib.azsli
|
||||
|
||||
-6
@@ -154,12 +154,6 @@ namespace AZ
|
||||
//! @param count Sample Count for filtering (up to 64)
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
|
||||
//! This specifies the width of boundary between shadowed area and lit area.
|
||||
//! @param handle the light handle.
|
||||
//! @param width Boundary width. The shadow is gradually changed the degree of shadowed.
|
||||
//! If width == 0, softening edge is disabled. Units are in meters.
|
||||
virtual void SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth) = 0;
|
||||
|
||||
//! Sets whether the directional shadowmap should use receiver plane bias.
|
||||
//! This attempts to reduce shadow acne when using large pcf filters.
|
||||
virtual void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) = 0;
|
||||
|
||||
-2
@@ -90,8 +90,6 @@ namespace AZ
|
||||
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
|
||||
//! Specifies filter method of shadows.
|
||||
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
|
||||
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on the boundary. 0 disables softening.
|
||||
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
|
||||
//! Sets sample count for filtering of shadow boundary (up to 64)
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
|
||||
|
||||
-3
@@ -70,9 +70,6 @@ namespace AZ
|
||||
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Specifies filter method of shadows.
|
||||
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
|
||||
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on
|
||||
//! the boundary. 0 disables softening.
|
||||
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
|
||||
//! Sets sample count for filtering of shadow boundary (up to 64)
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace AZ
|
||||
// [GFX TODO][ATOM-2408] Make the max number of cascade modifiable at runtime.
|
||||
static constexpr uint16_t MaxNumberOfCascades = 4;
|
||||
static constexpr uint16_t MaxPcfSamplingCount = 64;
|
||||
static constexpr float MaxSofteningBoundaryWidth = 0.1f;
|
||||
} // namespace Shadow
|
||||
|
||||
} // namespace Render
|
||||
|
||||
-2
@@ -54,8 +54,6 @@ namespace AZ::Render
|
||||
virtual void SetShadowBias(ShadowId id, float bias) = 0;
|
||||
//! Sets the shadow filter method
|
||||
virtual void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) = 0;
|
||||
//! Sets the width of boundary between shadowed area and lit area.
|
||||
virtual void SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians) = 0;
|
||||
//! Sets the sample count for filtering of the shadow boundary, max 64.
|
||||
virtual void SetFilteringSampleCount(ShadowId id, uint16_t count) = 0;
|
||||
//! Sets all of the shadow properites in one call
|
||||
|
||||
+2
-68
@@ -584,15 +584,6 @@ namespace AZ
|
||||
m_shadowBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth)
|
||||
{
|
||||
for (auto& it : m_shadowData)
|
||||
{
|
||||
it.second.GetData(handle.GetIndex()).m_boundaryScale = boundaryWidth / 2.f;
|
||||
}
|
||||
m_shadowBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable)
|
||||
{
|
||||
m_shadowProperties.GetData(handle.GetIndex()).m_isReceiverPlaneBiasEnabled = enable;
|
||||
@@ -1116,50 +1107,13 @@ namespace AZ
|
||||
for (const auto& passIt : m_esmShadowmapsPasses)
|
||||
{
|
||||
const RPI::View* cameraView = passIt.second.front()->GetRenderPipeline()->GetDefaultView().get();
|
||||
UpdateStandardDeviations(handle, cameraView);
|
||||
UpdateFilterOffsetsCounts(handle, cameraView);
|
||||
UpdateFilterEnabled(handle, cameraView);
|
||||
UpdateShadowmapPositionInAtlas(handle, cameraView);
|
||||
SetFilterParameterToPass(handle, cameraView);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::UpdateStandardDeviations(LightHandle handle, const RPI::View* cameraView)
|
||||
{
|
||||
if (handle != m_shadowingLightHandle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const DirectionalLightShadowData& data = m_shadowData.at(cameraView).GetData(handle.GetIndex());
|
||||
const ShadowProperty& property = m_shadowProperties.GetData(handle.GetIndex());
|
||||
AZStd::fixed_vector<float, Shadow::MaxNumberOfCascades> standardDeviations;
|
||||
for (size_t cascadeIndex = 0; cascadeIndex < property.m_segments.at(cameraView).size(); ++cascadeIndex)
|
||||
{
|
||||
const Aabb& aabb = property.m_segments.at(cameraView)[cascadeIndex].m_aabb;
|
||||
const float aabbDiameter = AZStd::GetMax(
|
||||
aabb.GetMax().GetX() - aabb.GetMin().GetX(),
|
||||
aabb.GetMax().GetZ() - aabb.GetMin().GetZ());
|
||||
float standardDeviation = 0.f;
|
||||
if (aabbDiameter > 0.f)
|
||||
{
|
||||
const float boundaryWidth = data.m_boundaryScale * 2.f;
|
||||
const float ratioToAabbWidth = boundaryWidth / aabbDiameter;
|
||||
const float widthInPixels = ratioToAabbWidth * data.m_shadowmapSize;
|
||||
standardDeviation = widthInPixels / (2 * GaussianMathFilter::ReliableSectionFactor);
|
||||
}
|
||||
standardDeviations.push_back(standardDeviation);
|
||||
}
|
||||
|
||||
for (const RPI::RenderPipelineId& pipelineId : m_renderPipelineIdsForPersistentView.at(cameraView))
|
||||
{
|
||||
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses.at(pipelineId))
|
||||
{
|
||||
esmPass->SetFilterParameters(standardDeviations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::UpdateFilterOffsetsCounts(LightHandle handle, const RPI::View* cameraView)
|
||||
void DirectionalLightFeatureProcessor::UpdateFilterEnabled(LightHandle handle, const RPI::View* cameraView)
|
||||
{
|
||||
if (handle != m_shadowingLightHandle)
|
||||
{
|
||||
@@ -1170,29 +1124,11 @@ namespace AZ
|
||||
if (shadowData.m_shadowFilterMethod == aznumeric_cast<uint32_t>(ShadowFilterMethod::Esm) ||
|
||||
(shadowData.m_shadowFilterMethod == aznumeric_cast<uint32_t>(ShadowFilterMethod::EsmPcf)))
|
||||
{
|
||||
// Get array of filter counts for the camera view.
|
||||
const RPI::RenderPipelineId& pipelineId = m_renderPipelineIdsForPersistentView.at(cameraView).front();
|
||||
AZ_Assert(!m_esmShadowmapsPasses.at(pipelineId).empty(), "Cannot find a EsmShadowmapsPass.");
|
||||
const AZStd::array_view<uint32_t> filterCounts = m_esmShadowmapsPasses.at(pipelineId).front()->GetFilterCounts();
|
||||
AZ_Assert(filterCounts.size() == GetCascadeCount(handle), "FilterCounts differs with cascade count.");
|
||||
|
||||
// Create array of filter offsets
|
||||
AZStd::vector<uint32_t> filterOffsets;
|
||||
filterOffsets.reserve(filterCounts.size());
|
||||
uint32_t filterOffset = 0;
|
||||
for (const uint32_t count : filterCounts)
|
||||
{
|
||||
filterOffsets.push_back(filterOffset);
|
||||
filterOffset += count;
|
||||
}
|
||||
|
||||
// Write filter offsets and filter counts to ESM data
|
||||
for (uint16_t index = 0; index < GetCascadeCount(handle); ++index)
|
||||
{
|
||||
EsmShadowmapsPass::FilterParameter& filterParameter = m_esmParameterData.at(cameraView).GetData(index);
|
||||
filterParameter.m_isEnabled = true;
|
||||
filterParameter.m_parameterOffset = filterOffsets[index];
|
||||
filterParameter.m_parameterCount = filterCounts[index];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1202,8 +1138,6 @@ namespace AZ
|
||||
{
|
||||
EsmShadowmapsPass::FilterParameter& filterParameter = m_esmParameterData.at(cameraView).GetData(index);
|
||||
filterParameter.m_isEnabled = false;
|
||||
filterParameter.m_parameterOffset = 0;
|
||||
filterParameter.m_parameterCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,6 @@ namespace AZ
|
||||
void SetDebugFlags(LightHandle handle, DebugDrawFlags flags) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth) override;
|
||||
void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) override;
|
||||
|
||||
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
|
||||
@@ -278,10 +277,8 @@ namespace AZ
|
||||
|
||||
//! This updates the parameter of Gaussian filter used in ESM.
|
||||
void UpdateFilterParameters(LightHandle handle);
|
||||
//! This updates standard deviations for each cascade.
|
||||
void UpdateStandardDeviations(LightHandle handle, const RPI::View* cameraView);
|
||||
//! This updates filter offset and size for each cascade.
|
||||
void UpdateFilterOffsetsCounts(LightHandle handle, const RPI::View* cameraView);
|
||||
//! This updates if the filter is enabled.
|
||||
void UpdateFilterEnabled(LightHandle handle, const RPI::View* cameraView);
|
||||
//! This updates shadowmap position(origin and size) in the atlas for each cascade.
|
||||
void UpdateShadowmapPositionInAtlas(LightHandle handle, const RPI::View* cameraView);
|
||||
//! This set filter parameters to passes which execute filtering.
|
||||
|
||||
@@ -322,11 +322,6 @@ namespace AZ
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
|
||||
{
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace AZ
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetEsmExponent(LightHandle handle, float esmExponent) override;
|
||||
|
||||
|
||||
@@ -42,28 +42,6 @@ namespace AZ
|
||||
return m_lightTypeName;
|
||||
}
|
||||
|
||||
void EsmShadowmapsPass::SetFilterParameters(const AZStd::array_view<float>& standardDeviations)
|
||||
{
|
||||
// Set descriptor for Gaussian filters for given set of standard deviations.
|
||||
MathFilterDescriptor descriptor;
|
||||
descriptor.m_kind = MathFilterKind::Gaussian;
|
||||
descriptor.m_gaussians.reserve(standardDeviations.size());
|
||||
for (const float standardDeviation : standardDeviations)
|
||||
{
|
||||
descriptor.m_gaussians.emplace_back(GaussianFilterDescriptor{ standardDeviation });
|
||||
}
|
||||
|
||||
// Set filter paramter buffer along with element counts for each filter.
|
||||
MathFilter::BufferWithElementCounts bufferCounts = MathFilter::FindOrCreateFilterBuffer(descriptor);
|
||||
m_filterTableBuffer = bufferCounts.first;
|
||||
m_filterCounts = AZStd::move(bufferCounts.second);
|
||||
}
|
||||
|
||||
AZStd::array_view<uint32_t> EsmShadowmapsPass::GetFilterCounts() const
|
||||
{
|
||||
return m_filterCounts;
|
||||
}
|
||||
|
||||
void EsmShadowmapsPass::SetShadowmapIndexTableBuffer(const Data::Instance<RPI::Buffer>& tableBuffer)
|
||||
{
|
||||
m_shadowmapIndexTableBuffer = tableBuffer;
|
||||
|
||||
@@ -50,14 +50,11 @@ namespace AZ
|
||||
uint32_t m_isEnabled = false;
|
||||
AZStd::array<uint32_t, 2> m_shadowmapOriginInSlice = { {0, 0 } }; // shadowmap origin in the slice of the atlas.
|
||||
uint32_t m_shadowmapSize = static_cast<uint32_t>(ShadowmapSize::None); // width and height of shadowmap.
|
||||
uint32_t m_parameterOffset; // offset of the filter parameter.
|
||||
uint32_t m_parameterCount; // element count of the filter parameter.
|
||||
float m_lightDistanceOfCameraViewFrustum = 0.f;
|
||||
float m_n_f_n = 0.f; // n / (f - n)
|
||||
float m_n_f = 0.f; // n - f
|
||||
float m_f = 0.f; // f
|
||||
// where n: nearDepth, f: farDepth.
|
||||
AZStd::array<float, 2> m_padding = {{0.f, 0.f}}; // explicit padding
|
||||
};
|
||||
|
||||
virtual ~EsmShadowmapsPass() = default;
|
||||
@@ -65,13 +62,6 @@ namespace AZ
|
||||
|
||||
const Name& GetLightTypeName() const;
|
||||
|
||||
//! This sets the standard deviations of the Gaussian filter
|
||||
//! for each cascade.
|
||||
void SetFilterParameters(const AZStd::array_view<float>& standardDeviations);
|
||||
|
||||
//! This returns element count of filters.
|
||||
AZStd::array_view<uint32_t> GetFilterCounts() const;
|
||||
|
||||
//! This sets the buffer of the table which enable to get shadowmap index
|
||||
//! from the coordinate in the atlas.
|
||||
//! Note that shadowmpa index is shader light index for a spot light
|
||||
|
||||
@@ -292,11 +292,6 @@ namespace AZ
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetFilteringSampleCount, count);
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace AZ
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetEsmExponent(LightHandle handle, float esmExponent) override;
|
||||
void SetPointData(LightHandle handle, const PointLightData& data) override;
|
||||
|
||||
@@ -54,10 +54,14 @@ namespace AZ
|
||||
{
|
||||
AZStd::shared_ptr<AZStd::vector<uint8_t>> buffer = readbackResult.m_dataBuffer;
|
||||
|
||||
RHI::Format format = readbackResult.m_imageDescriptor.m_format;
|
||||
|
||||
// convert bgra to rgba by swapping channels
|
||||
const int numChannels = AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format);
|
||||
if (readbackResult.m_imageDescriptor.m_format == RHI::Format::B8G8R8A8_UNORM)
|
||||
if (format == RHI::Format::B8G8R8A8_UNORM)
|
||||
{
|
||||
format = RHI::Format::R8G8B8A8_UNORM;
|
||||
|
||||
buffer = AZStd::make_shared<AZStd::vector<uint8_t>>(readbackResult.m_dataBuffer->size());
|
||||
AZStd::copy(readbackResult.m_dataBuffer->begin(), readbackResult.m_dataBuffer->end(), buffer->begin());
|
||||
|
||||
@@ -89,7 +93,7 @@ namespace AZ
|
||||
jobCompletion.StartAndWaitForCompletion();
|
||||
}
|
||||
|
||||
Utils::PngFile image = Utils::PngFile::Create(readbackResult.m_imageDescriptor.m_size, readbackResult.m_imageDescriptor.m_format, *buffer);
|
||||
Utils::PngFile image = Utils::PngFile::Create(readbackResult.m_imageDescriptor.m_size, format, *buffer);
|
||||
|
||||
Utils::PngFile::SaveSettings saveSettings;
|
||||
saveSettings.m_compressionLevel = r_pngCompressionLevel;
|
||||
|
||||
@@ -507,7 +507,8 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
//Check if buffer view data changed from previous frame.
|
||||
// Check if buffer view data changed from previous frame.
|
||||
// Look into making 'm_meshBuffers != meshBuffers' faster by possibly building a crc and doing a crc check.
|
||||
if (m_meshBuffers.size() != meshBuffers.size() || m_meshBuffers != meshBuffers)
|
||||
{
|
||||
m_meshBuffers = meshBuffers;
|
||||
|
||||
@@ -186,17 +186,6 @@ namespace AZ::Render
|
||||
m_filterParameterNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians)
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowBoundaryWidthAngle().");
|
||||
|
||||
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(id.GetIndex());
|
||||
shadowData.m_boundaryScale = boundaryWidthRadians / 2.0f;
|
||||
|
||||
m_shadowmapPassNeedsUpdate = true;
|
||||
m_filterParameterNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetFilteringSampleCount(ShadowId id, uint16_t count)
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetFilteringSampleCount().");
|
||||
@@ -368,14 +357,13 @@ namespace AZ::Render
|
||||
{
|
||||
if (m_filterParameterNeedsUpdate)
|
||||
{
|
||||
UpdateStandardDeviations();
|
||||
UpdateFilterOffsetsCounts();
|
||||
UpdateEsmPassEnabled();
|
||||
SetFilterParameterToPass();
|
||||
m_filterParameterNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::UpdateStandardDeviations()
|
||||
void ProjectedShadowFeatureProcessor::UpdateEsmPassEnabled()
|
||||
{
|
||||
if (m_esmShadowmapsPasses.empty())
|
||||
{
|
||||
@@ -383,24 +371,7 @@ namespace AZ::Render
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<float> standardDeviations(m_shadowProperties.GetDataCount());
|
||||
|
||||
for (uint32_t i = 0; i < m_shadowProperties.GetDataCount(); ++i)
|
||||
{
|
||||
ShadowProperty& shadowProperty = m_shadowProperties.GetDataVector().at(i);
|
||||
const ShadowData& shadow = m_shadowData.GetElement<ShadowDataIndex>(shadowProperty.m_shadowId.GetIndex());
|
||||
if (!FilterMethodIsEsm(shadow))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const FilterParameter& filter = m_shadowData.GetElement<FilterParamIndex>(shadowProperty.m_shadowId.GetIndex());
|
||||
const float boundaryWidthAngle = shadow.m_boundaryScale * 2.0f;
|
||||
const float fieldOfView = GetMax(shadowProperty.m_desc.m_fieldOfViewYRadians, MinimumFieldOfView);
|
||||
const float ratioToEntireWidth = boundaryWidthAngle / fieldOfView;
|
||||
const float widthInPixels = ratioToEntireWidth * filter.m_shadowmapSize;
|
||||
standardDeviations.at(i) = widthInPixels / (2.0f * GaussianMathFilter::ReliableSectionFactor);
|
||||
}
|
||||
if (standardDeviations.empty())
|
||||
if (m_shadowProperties.GetDataCount() == 0)
|
||||
{
|
||||
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses)
|
||||
{
|
||||
@@ -411,50 +382,6 @@ namespace AZ::Render
|
||||
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses)
|
||||
{
|
||||
esmPass->SetEnabledComputation(true);
|
||||
esmPass->SetFilterParameters(standardDeviations);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::UpdateFilterOffsetsCounts()
|
||||
{
|
||||
if (m_esmShadowmapsPasses.empty())
|
||||
{
|
||||
AZ_Error("ProjectedShadowFeatureProcessor", false, "Cannot find a required pass.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get array of filter counts for the camera view.
|
||||
const AZStd::array_view<uint32_t> filterCounts = m_esmShadowmapsPasses.front()->GetFilterCounts();
|
||||
|
||||
// Create array of filter offsets.
|
||||
AZStd::vector<uint32_t> filterOffsets;
|
||||
filterOffsets.reserve(filterCounts.size());
|
||||
uint32_t filterOffset = 0;
|
||||
for (const uint32_t count : filterCounts)
|
||||
{
|
||||
filterOffsets.push_back(filterOffset);
|
||||
filterOffset += count;
|
||||
}
|
||||
|
||||
auto& shadowProperties = m_shadowProperties.GetDataVector();
|
||||
for (uint32_t i = 0; i < shadowProperties.size(); ++i)
|
||||
{
|
||||
ShadowProperty& shadowProperty = shadowProperties.at(i);
|
||||
const ShadowId shadowId = shadowProperty.m_shadowId;
|
||||
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(shadowId.GetIndex());
|
||||
FilterParameter& filterData = m_shadowData.GetElement<FilterParamIndex>(shadowId.GetIndex());
|
||||
|
||||
if (FilterMethodIsEsm(shadowData))
|
||||
{
|
||||
filterData.m_parameterOffset = filterOffsets[i];
|
||||
filterData.m_parameterCount = filterCounts[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If filter is not required, reset offsets and counts of filter in ESM data.
|
||||
filterData.m_parameterOffset = 0;
|
||||
filterData.m_parameterCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace AZ::Render
|
||||
void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override;
|
||||
void SetShadowBias(ShadowId id, float bias) override;
|
||||
void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians) override;
|
||||
void SetFilteringSampleCount(ShadowId id, uint16_t count) override;
|
||||
void SetShadowProperties(ShadowId id, const ProjectedShadowDescriptor& descriptor) override;
|
||||
const ProjectedShadowDescriptor& GetShadowProperties(ShadowId id) override;
|
||||
@@ -101,8 +100,7 @@ namespace AZ::Render
|
||||
|
||||
//! Functions to update the parameter of Gaussian filter used in ESM.
|
||||
void UpdateFilterParameters();
|
||||
void UpdateStandardDeviations();
|
||||
void UpdateFilterOffsetsCounts();
|
||||
void UpdateEsmPassEnabled();
|
||||
void SetFilterParameterToPass();
|
||||
bool FilterMethodIsEsm(const ShadowData& shadowData) const;
|
||||
|
||||
|
||||
@@ -109,13 +109,11 @@ namespace AZ
|
||||
{
|
||||
if (attachment->GetFirstScopeAttachment() == nullptr)
|
||||
{
|
||||
//We allow the rendering to continue even if an attachment is not used.
|
||||
AZ_Error(
|
||||
"FrameGraph", false,
|
||||
"Invalid State: attachment '%s' was added but never used!",
|
||||
attachment->GetId().GetCStr());
|
||||
|
||||
Clear();
|
||||
return ResultCode::InvalidOperation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,13 +111,19 @@ namespace AZ
|
||||
{
|
||||
AZStd::lock_guard<AZStd::shared_mutex> lock(m_groupsToCompileMutex);
|
||||
|
||||
AZ_Assert(!shaderResourceGroup.IsQueuedForCompile(), "Attempting to compile an SRG that's already been queued for compile. Only compile an SRG once per frame.");
|
||||
bool isQueuedForCompile = shaderResourceGroup.IsQueuedForCompile();
|
||||
AZ_Warning(
|
||||
"ShaderResourceGroupPool", !isQueuedForCompile,
|
||||
"Attempting to compile an SRG that's already been queued for compile. Only compile an SRG once per frame.");
|
||||
|
||||
CalculateGroupDataDiff(shaderResourceGroup, groupData);
|
||||
if (!isQueuedForCompile)
|
||||
{
|
||||
CalculateGroupDataDiff(shaderResourceGroup, groupData);
|
||||
|
||||
shaderResourceGroup.SetData(groupData);
|
||||
shaderResourceGroup.SetData(groupData);
|
||||
|
||||
QueueForCompileNoLock(shaderResourceGroup);
|
||||
QueueForCompileNoLock(shaderResourceGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::QueueForCompile(ShaderResourceGroup& group)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user