Merge remote-tracking branch 'upstream/development' into Atom/santorac/WarnOnMaterialPsoChanges
This commit is contained in:
@@ -46,4 +46,15 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
AutomatedTesting.Assets
|
||||
Editor
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AtomRenderer_HydraTests_ShaderBuildPipeline
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_ShaderBuildPipelineSuite.py
|
||||
TEST_SERIAL
|
||||
TIMEOUT 600
|
||||
RUNTIME_DEPENDENCIES
|
||||
AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Editor
|
||||
)
|
||||
endif()
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a dummy shader used to validate detection of "#included files"
|
||||
*/
|
||||
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
|
||||
#include "Test1Color.azsli"
|
||||
#include <Test3Color.azsli>
|
||||
|
||||
ShaderResourceGroup DummySrg : SRG_PerDraw
|
||||
{
|
||||
float4 m_color;
|
||||
}
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 m_position : POSITION;
|
||||
float4 m_color : COLOR0;
|
||||
};
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 m_position : SV_Position;
|
||||
float4 m_color : COLOR0;
|
||||
};
|
||||
|
||||
VSOutput MainVS(VSInput vsInput)
|
||||
{
|
||||
VSOutput OUT;
|
||||
OUT.m_position = float4(vsInput.m_position, 1.0);
|
||||
OUT.m_color = vsInput.m_color;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
float4 m_color : SV_Target0;
|
||||
};
|
||||
|
||||
PSOutput MainPS(VSOutput vsOutput)
|
||||
{
|
||||
PSOutput OUT;
|
||||
|
||||
OUT.m_color = GetTest1Color(DummySrg::m_color) + GetTest3Color(DummySrg::m_color);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// This is a dummy shader used to validate detection of "#included files"
|
||||
{
|
||||
"Source" : "DependencyValidation.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : { "Enable" : false, "CompareFunc" : "GreaterEqual" }
|
||||
},
|
||||
|
||||
"DrawList" : "forward",
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a dummy shader used to validate detection of "#included files"
|
||||
*/
|
||||
|
||||
#include "Test2Color.azsli"
|
||||
|
||||
float4 GetTest1Color(float4 color)
|
||||
{
|
||||
return color + GetTest2Color(color);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a dummy shader used to validate detection of "#included files"
|
||||
*/
|
||||
|
||||
float4 GetTest2Color(float4 color)
|
||||
{
|
||||
return color * 0.5;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a dummy shader used to validate detection of "#included files"
|
||||
*/
|
||||
|
||||
float4 GetTest3Color(float4 color)
|
||||
{
|
||||
return color * 0.13;
|
||||
}
|
||||
+20
-2
@@ -3,8 +3,6 @@ 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
|
||||
|
||||
Hydra script that creates an entity and attaches Atom components to it for test verification.
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -17,6 +15,7 @@ import azlmbr.asset as asset
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.render as render
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
|
||||
@@ -125,6 +124,19 @@ def run():
|
||||
def verify_set_property(entity_obj, path, value):
|
||||
entity_obj.get_set_test(0, path, value)
|
||||
|
||||
# Verify cubemap generation
|
||||
def verify_cubemap_generation(component_name, entity_obj):
|
||||
# Initially Check if the component has Reflection Probe component
|
||||
if not hydra.has_components(entity_obj.id, ["Reflection Probe"]):
|
||||
raise ValueError(f"Given entity {entity_obj.name} has no Reflection Probe component")
|
||||
render.EditorReflectionProbeBus(azlmbr.bus.Event, "BakeReflectionProbe", entity_obj.id)
|
||||
|
||||
def get_value():
|
||||
hydra.get_component_property_value(entity_obj.components[0], "Cubemap|Baked Cubemap Path")
|
||||
|
||||
TestHelper.wait_for_condition(lambda: get_value() != "", 20.0)
|
||||
general.log(f"{component_name}_test: Cubemap is generated: {get_value() != ''}")
|
||||
|
||||
# Wait for Editor idle loop before executing Python hydra scripts.
|
||||
TestHelper.init_idle()
|
||||
|
||||
@@ -215,6 +227,12 @@ def run():
|
||||
# Display Mapper Component
|
||||
ComponentTests("Display Mapper")
|
||||
|
||||
# Reflection Probe Component
|
||||
reflection_probe = "Reflection Probe"
|
||||
ComponentTests(
|
||||
reflection_probe,
|
||||
lambda entity_obj: verify_required_component_addition(entity_obj, ["Box Shape"], reflection_probe),
|
||||
lambda entity_obj: verify_cubemap_generation(reflection_probe, entity_obj),)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
||||
-2
@@ -31,8 +31,6 @@ SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
|
||||
("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF
|
||||
("Controller|Configuration|Shadows|Filtering sample count", 4.0),
|
||||
("Controller|Configuration|Shadows|Filtering sample count", 64.0),
|
||||
("Controller|Configuration|Shadows|PCF method", 0), # Bicubic
|
||||
("Controller|Configuration|Shadows|PCF method", 1), # Boundary search
|
||||
("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM
|
||||
("Controller|Configuration|Shadows|ESM exponent", 50),
|
||||
("Controller|Configuration|Shadows|ESM exponent", 5000),
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
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
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
def _copy_file(src_file, src_path, target_file, target_path):
|
||||
# type: (str, str, str, str) -> None
|
||||
"""
|
||||
Copies the [src_file] located in [src_path] to the [target_file] located at [target_path].
|
||||
Leaves the [target_file] unlocked for reading and writing privileges
|
||||
:param src_file: The source file to copy (file name)
|
||||
:param src_path: The source file's path
|
||||
:param target_file: The target file to copy into (file name)
|
||||
:param target_path: The target file's path
|
||||
:return: None
|
||||
"""
|
||||
target_file_path = os.path.join(target_path, target_file)
|
||||
src_file_path = os.path.join(src_path, src_file)
|
||||
if os.path.exists(target_file_path):
|
||||
fs.unlock_file(target_file_path)
|
||||
shutil.copyfile(src_file_path, target_file_path)
|
||||
|
||||
def _copy_tmp_files_in_order(src_directory, file_list, dst_directory, wait_time_in_between = 0.0):
|
||||
# type: (str, list, str, float) -> None
|
||||
"""
|
||||
This function assumes that for each file name listed in @file_list
|
||||
there's file named "@filename.txt" which the original source file
|
||||
but they will be copied with just the @filename (.txt removed).
|
||||
"""
|
||||
for filename in file_list:
|
||||
src_name = f"{filename}.txt"
|
||||
_copy_file(src_name, src_directory, filename, dst_directory)
|
||||
if wait_time_in_between > 0.0:
|
||||
print(f"Created {filename} in {dst_directory}")
|
||||
general.idle_wait(wait_time_in_between)
|
||||
|
||||
|
||||
def _remove_file(src_file, src_path):
|
||||
# type: (str, str) -> None
|
||||
"""
|
||||
Removes the [src_file] located in [src_path].
|
||||
:param src_file: The source file to copy (file name)
|
||||
:param src_path: The source file's path
|
||||
:return: None
|
||||
"""
|
||||
src_file_path = os.path.join(src_path, src_file)
|
||||
if os.path.exists(src_file_path):
|
||||
fs.unlock_file(src_file_path)
|
||||
os.remove(src_file_path)
|
||||
|
||||
|
||||
def _remove_files(directory, file_list):
|
||||
for filename in file_list:
|
||||
_remove_file(filename, directory)
|
||||
|
||||
|
||||
def _asset_exists(cache_relative_path):
|
||||
asset_id = azasset.AssetCatalogRequestBus(azbus.Broadcast, "GetAssetIdByPath", cache_relative_path, azmath.Uuid(), False)
|
||||
return asset_id.is_valid()
|
||||
|
||||
# List of results that we want to check, this is not 100% necessary but it's a good
|
||||
# practice to make it easier to debug tests.
|
||||
# Here we define a tuple of tests
|
||||
class Results():
|
||||
azshader_was_removed = ("azshader was removed", "Failed to remove azshader")
|
||||
azshader_was_compiled = ("azshader was compiled", "Failed to compile azshader")
|
||||
|
||||
|
||||
def ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges():
|
||||
"""
|
||||
This test validates [ATOM-5441] Shader Builders May Fail When Multiple New Files Are Added
|
||||
It creates source assets to compile a particular shader.
|
||||
1- The first phase generates the source assets out of order and slowly. The AP should
|
||||
wakeup each time one of the source dependencies appears but will fail each time. Only when the
|
||||
last dependency appears then the shader should build successfully.
|
||||
2- The second phase is similar as above, except that all source assets will be created
|
||||
at once and We also expect that in the end the shader is built successfully.
|
||||
"""
|
||||
# Required for automated tests
|
||||
helper.init_idle()
|
||||
|
||||
game_root_path = os.path.normpath(general.get_game_folder())
|
||||
game_asset_path = os.path.join(game_root_path, "Assets")
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
src_assets_subdir = os.path.join(base_dir, "TestAssets", "ShaderAssetBuilder")
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# The script drives the execution of the test, to return the flow back to the editor,
|
||||
# we will tick it one time
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# This is the order in which the source assets should be deployed
|
||||
# to avoid source dependency issues with the old MCPP-based CreateJobs.
|
||||
file_list = [
|
||||
"Test2Color.azsli",
|
||||
"Test3Color.azsli",
|
||||
"Test1Color.azsli",
|
||||
"DependencyValidation.azsl",
|
||||
"DependencyValidation.shader"
|
||||
]
|
||||
|
||||
reverse_file_list = file_list[::-1]
|
||||
|
||||
# Remove files in reverse order
|
||||
_remove_files(game_asset_path, reverse_file_list)
|
||||
|
||||
# Wait here until the azshader doesn't exist anymore.
|
||||
azshader_name = "assets/dependencyvalidation.azshader"
|
||||
helper.wait_for_condition(lambda: not _asset_exists(azshader_name), 5.0)
|
||||
|
||||
Report.critical_result(Results.azshader_was_removed, not _asset_exists(azshader_name))
|
||||
|
||||
_copy_tmp_files_in_order(src_assets_subdir, file_list, game_asset_path, 1.0)
|
||||
|
||||
# Give enough time to AP to compile the shader
|
||||
helper.wait_for_condition(lambda: _asset_exists(azshader_name), 60.0)
|
||||
|
||||
Report.critical_result(Results.azshader_was_compiled, _asset_exists(azshader_name))
|
||||
|
||||
# The first part was about compiling the shader under normal conditions.
|
||||
# Let's remove the files from the previous phase and will proceed
|
||||
# to make the source files visible to the AP in reverse order. The
|
||||
# ShaderAssetBuilder will only succeed when the last file becomes visible.
|
||||
_remove_files(game_asset_path, reverse_file_list)
|
||||
helper.wait_for_condition(lambda: not _asset_exists(azshader_name), 5.0)
|
||||
Report.critical_result(Results.azshader_was_removed, not _asset_exists(azshader_name))
|
||||
|
||||
# Remark, if you are running this test manually from the Editor with "pyRunFile",
|
||||
# You'll notice how the AP issues notifications that it fails to compile the shader
|
||||
# as the source files are being copied to the "Assets" subfolder.
|
||||
# Those errors are OK and also expected because We need the AP to wake up as each
|
||||
# reported source dependency exists. Once the last file is copied then all source
|
||||
# dependencies are fully satisfied and the shader should compile successfully.
|
||||
# And this summarizes the importance of this Test: The previous version
|
||||
# of ShaderAssetBuilder::CreateJobs was incapable of compiling the shader under the conditions
|
||||
# presented in this test, but with the new version of ShaderAssetBuilder::CreateJobs, which
|
||||
# doesn't use MCPP for #include files discovery, it should eventually compile the shader
|
||||
# once all the source files are in place.
|
||||
_copy_tmp_files_in_order(src_assets_subdir, reverse_file_list, game_asset_path, 3.0)
|
||||
|
||||
# Give enough time to AP to compile the shader
|
||||
helper.wait_for_condition(lambda: _asset_exists(azshader_name), 60.0)
|
||||
|
||||
Report.critical_result(Results.azshader_was_compiled, _asset_exists(azshader_name))
|
||||
|
||||
# The last phase of the test puts stress on potential race conditions
|
||||
# when all required files appear as soon as possible.
|
||||
|
||||
# First Clean up.
|
||||
# Remove left over files.
|
||||
_remove_files(game_asset_path, reverse_file_list)
|
||||
helper.wait_for_condition(lambda: not _asset_exists(azshader_name), 5.0)
|
||||
Report.critical_result(Results.azshader_was_removed, not _asset_exists(azshader_name))
|
||||
|
||||
# Now let's copy all the source files to the "Assets" folder as fast as possible.
|
||||
_copy_tmp_files_in_order(src_assets_subdir, reverse_file_list, game_asset_path)
|
||||
|
||||
# Give enough time to AP to compile the shader
|
||||
helper.wait_for_condition(lambda: _asset_exists(azshader_name), 60.0)
|
||||
|
||||
Report.critical_result(Results.azshader_was_compiled, _asset_exists(azshader_name))
|
||||
|
||||
# All good, let's cleanup leftover files before closing the test.
|
||||
_remove_files(game_asset_path, reverse_file_list)
|
||||
helper.wait_for_condition(lambda: not _asset_exists(azshader_name), 5.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# All exposed python bindings are in azlmbr
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as azbus
|
||||
import azlmbr.asset as azasset
|
||||
import azlmbr.math as azmath
|
||||
|
||||
# Import report and test helper utilities
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.utils import Tracer
|
||||
import ly_test_tools.environment.file_system as fs
|
||||
|
||||
Report.start_test(ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges)
|
||||
@@ -161,6 +161,21 @@ class TestAtomEditorComponentsMain(object):
|
||||
"Display Mapper_test: Entity deleted: True",
|
||||
"Display Mapper_test: UNDO entity deletion works: True",
|
||||
"Display Mapper_test: REDO entity deletion works: True",
|
||||
# Reflection Probe Component
|
||||
"Reflection Probe Entity successfully created",
|
||||
"Reflection Probe_test: Component added to the entity: True",
|
||||
"Reflection Probe_test: Component removed after UNDO: True",
|
||||
"Reflection Probe_test: Component added after REDO: True",
|
||||
"Reflection Probe_test: Entered game mode: True",
|
||||
"Reflection Probe_test: Exit game mode: True",
|
||||
"Reflection Probe_test: Entity disabled initially: True",
|
||||
"Reflection Probe_test: Entity enabled after adding required components: True",
|
||||
"Reflection Probe_test: Cubemap is generated: True",
|
||||
"Reflection Probe_test: Entity is hidden: True",
|
||||
"Reflection Probe_test: Entity is shown: True",
|
||||
"Reflection Probe_test: Entity deleted: True",
|
||||
"Reflection Probe_test: UNDO entity deletion works: True",
|
||||
"Reflection Probe_test: REDO entity deletion works: True",
|
||||
]
|
||||
|
||||
unexpected_lines = [
|
||||
@@ -200,8 +215,6 @@ class TestAtomEditorComponentsMain(object):
|
||||
"Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
|
||||
"Controller|Configuration|Shadows|Filtering sample count set to 4",
|
||||
"Controller|Configuration|Shadows|Filtering sample count set to 64",
|
||||
"Controller|Configuration|Shadows|PCF method set to 0",
|
||||
"Controller|Configuration|Shadows|PCF method set to 1",
|
||||
"Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
|
||||
"Controller|Configuration|Shadows|ESM exponent set to 50.0",
|
||||
"Controller|Configuration|Shadows|ESM exponent set to 5000.0",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Main suite tests for the Shader Build Pipeline.
|
||||
"""
|
||||
import pytest
|
||||
from ly_test_tools import LAUNCHERS
|
||||
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSingleTest
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
class TestShaderBuildPipelineMain(EditorTestSuite):
|
||||
"""Holds tests for Shader Build Pipeline validation"""
|
||||
|
||||
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSingleTest):
|
||||
from .atom_hydra_scripts import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
@@ -20,6 +20,7 @@
|
||||
// AzCore
|
||||
#include <AzCore/Casting/numeric_cast.h> // for aznumeric_cast
|
||||
|
||||
#include <AzQtComponents/Utilities/PixmapScaleUtilities.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <ui_AboutDialog.h>
|
||||
@@ -46,8 +47,13 @@ CAboutDialog::CAboutDialog(QString versionText, QString richTextCopyrightNotice,
|
||||
CAboutDialog > QLabel#link { text-decoration: underline; color: #94D2FF; }");
|
||||
|
||||
// Prepare background image
|
||||
QImage backgroundImage(QStringLiteral(":/StartupLogoDialog/splashscreen_background_developer_preview.jpg"));
|
||||
m_backgroundImage = QPixmap::fromImage(backgroundImage.scaled(m_enforcedWidth, m_enforcedHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
m_backgroundImage = AzQtComponents::ScalePixmapForScreenDpi(
|
||||
QPixmap(QStringLiteral(":/StartupLogoDialog/splashscreen_background_developer_preview.jpg")),
|
||||
screen(),
|
||||
QSize(m_enforcedWidth, m_enforcedHeight),
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation
|
||||
);
|
||||
|
||||
// Draw the Open 3D Engine logo from svg
|
||||
m_ui->m_logo->load(QStringLiteral(":/StartupLogoDialog/o3de_logo.svg"));
|
||||
|
||||
@@ -44,7 +44,7 @@ enum
|
||||
{
|
||||
// in milliseconds
|
||||
GameModeIdleFrequency = 0,
|
||||
EditorModeIdleFrequency = 1,
|
||||
EditorModeIdleFrequency = 0,
|
||||
InactiveModeFrequency = 10,
|
||||
UninitializedFrequency = 9999,
|
||||
};
|
||||
|
||||
@@ -77,10 +77,6 @@ namespace
|
||||
// This closes the current document (level)
|
||||
currentLevel->OnNewDocument();
|
||||
|
||||
// Then we freeze the viewport's input
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Broadcast(
|
||||
&AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Events::FreezeViewportInput, true);
|
||||
|
||||
// Then we need to tell the game engine there is no level to render anymore
|
||||
if (GetIEditor()->GetGameEngine())
|
||||
{
|
||||
|
||||
@@ -669,16 +669,6 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
|
||||
case eNotify_OnEndSceneSave:
|
||||
PopDisableRendering();
|
||||
break;
|
||||
|
||||
case eNotify_OnBeginLoad: // disables viewport input when starting to load an existing level
|
||||
case eNotify_OnBeginCreate: // disables viewport input when starting to create a new level
|
||||
m_freezeViewportInput = true;
|
||||
break;
|
||||
|
||||
case eNotify_OnEndLoad: // enables viewport input when finished loading an existing level
|
||||
case eNotify_OnEndCreate: // enables viewport input when finished creating a new level
|
||||
m_freezeViewportInput = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,16 +952,6 @@ AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::V
|
||||
return m_renderViewport->ViewportWorldToScreen(worldPosition);
|
||||
}
|
||||
|
||||
bool EditorViewportWidget::IsViewportInputFrozen()
|
||||
{
|
||||
return m_freezeViewportInput;
|
||||
}
|
||||
|
||||
void EditorViewportWidget::FreezeViewportInput(bool freeze)
|
||||
{
|
||||
m_freezeViewportInput = freeze;
|
||||
}
|
||||
|
||||
QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu()
|
||||
{
|
||||
return this;
|
||||
@@ -1057,9 +1037,9 @@ void EditorViewportWidget::SetViewportId(int id)
|
||||
|
||||
void EditorViewportWidget::ConnectViewportInteractionRequestBus()
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect();
|
||||
m_viewportUi.ConnectViewportUiBus(GetViewportId());
|
||||
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusConnect();
|
||||
@@ -1070,9 +1050,9 @@ void EditorViewportWidget::DisconnectViewportInteractionRequestBus()
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_viewportUi.DisconnectViewportUiBus();
|
||||
AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
namespace AZ::ViewportHelpers
|
||||
|
||||
@@ -89,7 +89,6 @@ class SANDBOX_API EditorViewportWidget final
|
||||
, private Camera::EditorCameraRequestBus::Handler
|
||||
, private Camera::CameraNotificationBus::Handler
|
||||
, private AzFramework::InputSystemCursorConstraintRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler
|
||||
@@ -202,10 +201,6 @@ private:
|
||||
// AzFramework::InputSystemCursorConstraintRequestBus overrides ...
|
||||
void* GetSystemCursorConstraintWindow() const override;
|
||||
|
||||
// AzToolsFramework::ViewportFreezeRequestBus overrides ...
|
||||
bool IsViewportInputFrozen() override;
|
||||
void FreezeViewportInput(bool freeze) override;
|
||||
|
||||
// AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ...
|
||||
AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) override;
|
||||
AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override;
|
||||
@@ -387,9 +382,6 @@ private:
|
||||
// Unclear if it's still necessary.
|
||||
QSet<int> m_keyDown;
|
||||
|
||||
// State for ViewportFreezeRequestBus, currently does nothing
|
||||
bool m_freezeViewportInput = false;
|
||||
|
||||
// This widget holds a reference to the manipulator manage because its responsible for drawing manipulators
|
||||
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager;
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ void CGameExporter::ExportLevelInfo(const QString& path)
|
||||
root->setAttr("Name", levelName.toUtf8().data());
|
||||
auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler();
|
||||
const AZ::Aabb terrainAabb = terrain ? terrain->GetTerrainAabb() : AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
|
||||
const AZ::Vector2 terrainGridResolution = terrain ? terrain->GetTerrainGridResolution() : AZ::Vector2::CreateOne();
|
||||
const AZ::Vector2 terrainGridResolution = terrain ? terrain->GetTerrainHeightQueryResolution() : AZ::Vector2::CreateOne();
|
||||
const int compiledHeightmapSize = static_cast<int>(terrainAabb.GetXExtent() / terrainGridResolution.GetX());
|
||||
root->setAttr("HeightmapSize", compiledHeightmapSize);
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
// Description : implementation file
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "StartupLogoDialog.h"
|
||||
|
||||
#include <AzQtComponents/Utilities/PixmapScaleUtilities.h>
|
||||
|
||||
// Qt
|
||||
#include <QPainter>
|
||||
#include <QThread>
|
||||
@@ -22,8 +22,6 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <ui_StartupLogoDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CStartupLogoDialog dialog
|
||||
|
||||
@@ -36,13 +34,16 @@ CStartupLogoDialog::CStartupLogoDialog(QString versionText, QString richTextCopy
|
||||
m_ui->setupUi(this);
|
||||
|
||||
s_pLogoWindow = this;
|
||||
|
||||
m_backgroundImage = QPixmap(QStringLiteral(":/StartupLogoDialog/splashscreen_background_developer_preview.jpg"));
|
||||
setFixedSize(QSize(600, 300));
|
||||
|
||||
// Prepare background image
|
||||
QImage backgroundImage(QStringLiteral(":/StartupLogoDialog/splashscreen_background_developer_preview.jpg"));
|
||||
m_backgroundImage = QPixmap::fromImage(backgroundImage.scaled(m_enforcedWidth, m_enforcedHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
m_backgroundImage = AzQtComponents::ScalePixmapForScreenDpi(
|
||||
QPixmap(QStringLiteral(":/StartupLogoDialog/splashscreen_background_developer_preview.jpg")),
|
||||
screen(),
|
||||
QSize(m_enforcedWidth, m_enforcedHeight),
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation
|
||||
);
|
||||
|
||||
// Draw the Open 3D Engine logo from svg
|
||||
m_ui->m_logo->load(QStringLiteral(":/StartupLogoDialog/o3de_logo.svg"));
|
||||
|
||||
@@ -191,94 +191,4 @@ ConsoleTextEdit:focus,
|
||||
border-width: 0px;
|
||||
border-color: #e9e9e9;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
/* Welcome Screen styling */
|
||||
|
||||
WelcomeScreenDialog QLabel
|
||||
{
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
line-height: 20px;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QLabel#currentProjectLabel
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QPushButton
|
||||
{
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QWidget#articleViewContainerRoot
|
||||
{
|
||||
background: #444444;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QWidget#levelViewFTUEContainer
|
||||
{
|
||||
background: #282828;
|
||||
}
|
||||
|
||||
QTableWidget#recentLevelTable::item {
|
||||
background-color: rgb(64,64,64);
|
||||
margin-bottom: 4px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Particle Editor */
|
||||
|
||||
#NumParticlesLabel
|
||||
{
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
#LibrarySearchIcon
|
||||
{
|
||||
max-width: 16px;
|
||||
max-height: 16px;
|
||||
qproperty-iconSize: 16px 16px;
|
||||
}
|
||||
|
||||
|
||||
#ClosePrefabDialog, #SavePrefabDialog
|
||||
{
|
||||
min-width : 640px;
|
||||
}
|
||||
|
||||
#SaveDependentPrefabsCard
|
||||
{
|
||||
margin: 0px 15px 10px 15px;
|
||||
}
|
||||
|
||||
#PrefabSavedMessageFrame{
|
||||
border: 1px solid green;
|
||||
margin: 10px 15px 10px 15px;
|
||||
border-radius: 2px;
|
||||
padding: 5px 2px 5px 2px;
|
||||
}
|
||||
|
||||
#ClosePrefabDialog #PrefabSaveWarningFrame
|
||||
{
|
||||
border: 1px solid orange;
|
||||
margin: 10px 15px 10px 15px;
|
||||
border-radius: 2px;
|
||||
padding: 5px 2px 5px 2px;
|
||||
color : white;
|
||||
}
|
||||
|
||||
#SavePrefabDialog #FooterSeparatorLine
|
||||
{
|
||||
color: gray;
|
||||
}
|
||||
|
||||
#SavePrefabDialog #PrefabSavePreferenceHint
|
||||
{
|
||||
font: italic;
|
||||
color: #999999;
|
||||
}
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "CryEdit.h"
|
||||
#include "Viewport.h"
|
||||
|
||||
// Atom Renderer
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <TrackView/ui_SequenceBatchRenderDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
@@ -1234,6 +1237,13 @@ void CSequenceBatchRenderDialog::OnKickIdleTimout()
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
|
||||
// Directly tick the renderer, as it's no longer part of the system tick
|
||||
if (auto rpiSystem = AZ::RPI::RPISystemInterface::Get())
|
||||
{
|
||||
rpiSystem->SimulationTick();
|
||||
rpiSystem->RenderTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
// AzQtComponents
|
||||
#include <AzQtComponents/Components/Widgets/CheckBox.h>
|
||||
#include <AzQtComponents/Components/WindowDecorationWrapper.h>
|
||||
#include <AzQtComponents/Utilities/PixmapScaleUtilities.h>
|
||||
|
||||
// Editor
|
||||
#include "Settings.h"
|
||||
@@ -79,8 +80,11 @@ WelcomeScreenDialog::WelcomeScreenDialog(QWidget* pParent)
|
||||
{
|
||||
projectPreviewPath = ":/WelcomeScreenDialog/DefaultProjectImage.png";
|
||||
}
|
||||
|
||||
ui->activeProjectIcon->setPixmap(
|
||||
QPixmap(projectPreviewPath).scaled(
|
||||
AzQtComponents::ScalePixmapForScreenDpi(
|
||||
QPixmap(projectPreviewPath),
|
||||
screen(),
|
||||
ui->activeProjectIcon->size(),
|
||||
Qt::KeepAspectRatioByExpanding,
|
||||
Qt::SmoothTransformation
|
||||
|
||||
@@ -74,6 +74,8 @@
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
AZ_CVAR(float, g_simulation_tick_rate, 0, nullptr, AZ::ConsoleFunctorFlags::Null, "The rate at which the game simulation tick loop runs, or 0 for as fast as possible");
|
||||
|
||||
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (arguments.empty())
|
||||
@@ -1392,6 +1394,23 @@ namespace AZ
|
||||
AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
|
||||
EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
|
||||
}
|
||||
|
||||
// If tick rate limiting is on, ensure (1 / g_simulation_tick_rate) ms has elapsed since the last frame,
|
||||
// sleeping if there's still time remaining.
|
||||
if (g_simulation_tick_rate > 0.f)
|
||||
{
|
||||
now = AZStd::chrono::system_clock::now();
|
||||
|
||||
// Work in microsecond durations here as that's the native measurement time for time_point
|
||||
constexpr float microsecondsPerSecond = 1000.f * 1000.f;
|
||||
const AZStd::chrono::microseconds timeBudgetPerTick(static_cast<int>(microsecondsPerSecond / g_simulation_tick_rate));
|
||||
AZStd::chrono::microseconds timeUntilNextTick = m_currentTime + timeBudgetPerTick - now;
|
||||
|
||||
if (timeUntilNextTick.count() > 0)
|
||||
{
|
||||
AZStd::this_thread::sleep_for(timeUntilNextTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace AZ
|
||||
|
||||
TICK_PRE_RENDER = 750, ///< Suggested tick handler position to update render-related data.
|
||||
|
||||
TICK_RENDER = 800, ///< Suggested tick handler position for rendering.
|
||||
|
||||
TICK_DEFAULT = 1000, ///< Default tick handler position when the handler is constructed.
|
||||
|
||||
TICK_UI = 2000, ///< Suggested tick handler position for UI components.
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace AZ
|
||||
|
||||
const char* get_name() const { return m_name; }
|
||||
void set_name(const char* name) { m_name = name; }
|
||||
size_type get_max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
|
||||
constexpr size_type max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
|
||||
size_type get_allocated_size() const { return 0; }
|
||||
|
||||
bool is_lock_free() { return false; }
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace AZ::IO
|
||||
// If the path input = 'D:bar', then the new PathIterable parts = [D:, 'bar' ]
|
||||
static constexpr void AppendNormalPathParts(PathIterable& pathIterableResult, const AZ::IO::PathView& path) noexcept;
|
||||
|
||||
constexpr int compare_string_view(AZStd::string_view other) const;
|
||||
constexpr int ComparePathView(const PathView& other) const;
|
||||
constexpr AZStd::string_view root_name_view() const;
|
||||
constexpr AZStd::string_view root_directory_view() const;
|
||||
constexpr AZStd::string_view root_path_raw_view() const;
|
||||
@@ -480,6 +480,8 @@ namespace AZ::IO
|
||||
// compare
|
||||
//! Performs a compare of each of the path parts for equivalence
|
||||
//! Each part of the path is compare using string comparison
|
||||
//! If both *this path and the input path uses the WindowsPathSeparator
|
||||
//! then a non-case sensitive compare is performed
|
||||
//! Ex: Comparing "test/foo" against "test/fop" returns -1;
|
||||
//! Path separators of the contained path string aren't compared
|
||||
//! Ex. Comparing "C:/test\foo" against C:\test/foo" returns 0;
|
||||
|
||||
@@ -224,15 +224,15 @@ namespace AZ::IO
|
||||
// compare
|
||||
constexpr int PathView::Compare(const PathView& other) const noexcept
|
||||
{
|
||||
return compare_string_view(other.m_path);
|
||||
return ComparePathView(other);
|
||||
}
|
||||
constexpr int PathView::Compare(AZStd::string_view pathView) const noexcept
|
||||
{
|
||||
return compare_string_view(pathView);
|
||||
return ComparePathView(PathView(pathView, m_preferred_separator));
|
||||
}
|
||||
constexpr int PathView::Compare(const value_type* path) const noexcept
|
||||
{
|
||||
return compare_string_view(path);
|
||||
return ComparePathView(PathView(path, m_preferred_separator));
|
||||
}
|
||||
|
||||
constexpr AZStd::fixed_string<MaxPathLength> PathView::FixedMaxPathString() const noexcept
|
||||
@@ -398,10 +398,10 @@ namespace AZ::IO
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr int PathView::compare_string_view(AZStd::string_view pathView) const
|
||||
constexpr int PathView::ComparePathView(const PathView& other) const
|
||||
{
|
||||
auto lhsPathParser = parser::PathParser::CreateBegin(m_path, m_preferred_separator);
|
||||
auto rhsPathParser = parser::PathParser::CreateBegin(pathView, m_preferred_separator);
|
||||
auto rhsPathParser = parser::PathParser::CreateBegin(other.m_path, other.m_preferred_separator);
|
||||
|
||||
if (int res = CompareRootName(&lhsPathParser, &rhsPathParser); res != 0)
|
||||
{
|
||||
@@ -476,6 +476,8 @@ namespace AZ::IO
|
||||
template <typename PathResultType>
|
||||
constexpr void PathView::MakeRelativeTo(PathResultType& pathResult, const AZ::IO::PathView& path, const AZ::IO::PathView& base)
|
||||
{
|
||||
const bool exactCaseCompare = path.m_preferred_separator == PosixPathSeparator
|
||||
|| base.m_preferred_separator == PosixPathSeparator;
|
||||
{
|
||||
// perform root-name/root-directory mismatch checks
|
||||
auto pathParser = parser::PathParser::CreateBegin(path.m_path, path.m_preferred_separator);
|
||||
@@ -487,7 +489,7 @@ namespace AZ::IO
|
||||
};
|
||||
if (pathParser.InRootName() && pathParserBase.InRootName())
|
||||
{
|
||||
if (int res = Internal::ComparePathSegment(*pathParser, *pathParserBase, pathParser.m_preferred_separator);
|
||||
if (int res = Internal::ComparePathSegment(*pathParser, *pathParserBase, exactCaseCompare);
|
||||
res != 0)
|
||||
{
|
||||
pathResult.m_path = AZStd::string_view{};
|
||||
@@ -519,7 +521,7 @@ namespace AZ::IO
|
||||
auto pathParser = parser::PathParser::CreateBegin(path.m_path, path.m_preferred_separator);
|
||||
auto pathParserBase = parser::PathParser::CreateBegin(base.m_path, base.m_preferred_separator);
|
||||
while (pathParser && pathParserBase && pathParser.m_parser_state == pathParserBase.m_parser_state &&
|
||||
Internal::ComparePathSegment(*pathParser, *pathParserBase, pathParser.m_preferred_separator) == 0)
|
||||
Internal::ComparePathSegment(*pathParser, *pathParserBase, exactCaseCompare) == 0)
|
||||
{
|
||||
++pathParser;
|
||||
++pathParserBase;
|
||||
@@ -1080,25 +1082,25 @@ namespace AZ::IO
|
||||
template <typename StringType>
|
||||
constexpr int BasicPath<StringType>::Compare(const PathView& other) const noexcept
|
||||
{
|
||||
return static_cast<PathView>(*this).compare_string_view(other.m_path);
|
||||
return static_cast<PathView>(*this).ComparePathView(other);
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
constexpr int BasicPath<StringType>::Compare(const string_type& pathString) const
|
||||
{
|
||||
return static_cast<PathView>(*this).compare_string_view(pathString);
|
||||
return static_cast<PathView>(*this).ComparePathView(PathView(pathString, m_preferred_separator));
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
constexpr int BasicPath<StringType>::Compare(AZStd::string_view pathView) const noexcept
|
||||
{
|
||||
return static_cast<PathView>(*this).compare_string_view(pathView);
|
||||
return static_cast<PathView>(*this).ComparePathView(pathView);
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
constexpr int BasicPath<StringType>::Compare(const value_type* pathString) const noexcept
|
||||
{
|
||||
return static_cast<PathView>(*this).compare_string_view(pathString);
|
||||
return static_cast<PathView>(*this).ComparePathView(pathString);
|
||||
}
|
||||
|
||||
// decomposition
|
||||
@@ -1330,10 +1332,12 @@ namespace AZ::IO
|
||||
// PathView::LexicallyRelative is not being used as it returns a FixedMaxPath
|
||||
// which has a limitation that it requires the relative path to fit within
|
||||
// an AZ::IO::MaxPathLength buffer
|
||||
auto ComparePathPart = [pathSeparator = m_preferred_separator](
|
||||
const bool exactCaseCompare = m_preferred_separator == PosixPathSeparator
|
||||
|| base.m_preferred_separator == PosixPathSeparator;
|
||||
auto ComparePathPart = [exactCaseCompare](
|
||||
const PathIterable::PartKindPair& left, const PathIterable::PartKindPair& right) -> bool
|
||||
{
|
||||
return Internal::ComparePathSegment(left.first, right.first, pathSeparator) == 0;
|
||||
return Internal::ComparePathSegment(left.first, right.first, exactCaseCompare) == 0;
|
||||
};
|
||||
|
||||
const PathIterable thisPathParts = GetNormalPathParts(*this);
|
||||
@@ -1471,37 +1475,16 @@ namespace AZStd
|
||||
template <>
|
||||
struct hash<AZ::IO::PathView>
|
||||
{
|
||||
/// Path is using FNV-1a algorithm 64 bit version.
|
||||
static size_t hash_path(AZStd::string_view pathSegment, const char pathSeparator)
|
||||
{
|
||||
size_t hash = 14695981039346656037ULL;
|
||||
constexpr size_t fnvPrime = 1099511628211ULL;
|
||||
|
||||
for (const char first : pathSegment)
|
||||
{
|
||||
hash ^= static_cast<size_t>((pathSeparator == AZ::IO::PosixPathSeparator)
|
||||
? first : tolower(first));
|
||||
hash *= fnvPrime;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
size_t operator()(const AZ::IO::PathView& pathToHash) noexcept
|
||||
{
|
||||
auto pathParser = AZ::IO::parser::PathParser::CreateBegin(pathToHash.Native(), pathToHash.m_preferred_separator);
|
||||
size_t hash_value = 0;
|
||||
while (pathParser)
|
||||
{
|
||||
AZStd::hash_combine(hash_value, hash_path(*pathParser, pathToHash.m_preferred_separator));
|
||||
++pathParser;
|
||||
}
|
||||
return hash_value;
|
||||
return AZ::IO::parser::HashPath(pathParser);
|
||||
}
|
||||
};
|
||||
template <typename StringType>
|
||||
struct hash<AZ::IO::BasicPath<StringType>>
|
||||
{
|
||||
const size_t operator()(const AZ::IO::BasicPath<StringType>& pathToHash) noexcept
|
||||
size_t operator()(const AZ::IO::BasicPath<StringType>& pathToHash) noexcept
|
||||
{
|
||||
return AZStd::hash<AZ::IO::PathView>{}(pathToHash);
|
||||
}
|
||||
|
||||
@@ -183,13 +183,12 @@ namespace AZ::IO::Internal
|
||||
return IsAbsolute(pathView.begin(), pathView.end(), preferredSeparator);
|
||||
}
|
||||
|
||||
// Compares path segments using either Posix or Windows path rules based on the path separator in use
|
||||
// Posix paths perform a case-sensitive comparison, while Windows paths perform a case-insensitive comparison
|
||||
static int ComparePathSegment(AZStd::string_view left, AZStd::string_view right, char pathSeparator)
|
||||
// Compares path segments using either Posix or Windows path rules based on the exactCaseCompare option
|
||||
static int ComparePathSegment(AZStd::string_view left, AZStd::string_view right, bool exactCaseCompare)
|
||||
{
|
||||
const size_t maxCharsToCompare = (AZStd::min)(left.size(), right.size());
|
||||
|
||||
int charCompareResult = pathSeparator == PosixPathSeparator
|
||||
int charCompareResult = exactCaseCompare
|
||||
? maxCharsToCompare ? strncmp(left.data(), right.data(), maxCharsToCompare) : 0
|
||||
: maxCharsToCompare ? azstrnicmp(left.data(), right.data(), maxCharsToCompare) : 0;
|
||||
return charCompareResult == 0
|
||||
@@ -594,7 +593,10 @@ namespace AZ::IO::parser
|
||||
{
|
||||
return pathParser->InRootName() ? **pathParser : "";
|
||||
};
|
||||
int res = Internal::ComparePathSegment(GetRootName(lhsPathParser), GetRootName(rhsPathParser), lhsPathParser->m_preferred_separator);
|
||||
|
||||
const bool exactCaseCompare = lhsPathParser->m_preferred_separator == PosixPathSeparator
|
||||
|| rhsPathParser->m_preferred_separator == PosixPathSeparator;
|
||||
int res = Internal::ComparePathSegment(GetRootName(lhsPathParser), GetRootName(rhsPathParser), exactCaseCompare);
|
||||
ConsumeRootName(lhsPathParser);
|
||||
ConsumeRootName(rhsPathParser);
|
||||
return res;
|
||||
@@ -621,9 +623,11 @@ namespace AZ::IO::parser
|
||||
auto& lhsPathParser = *lhsPathParserPtr;
|
||||
auto& rhsPathParser = *rhsPathParserPtr;
|
||||
|
||||
const bool exactCaseCompare = lhsPathParser.m_preferred_separator == PosixPathSeparator
|
||||
|| rhsPathParser.m_preferred_separator == PosixPathSeparator;
|
||||
while (lhsPathParser && rhsPathParser)
|
||||
{
|
||||
if (int res = Internal::ComparePathSegment(*lhsPathParser, *rhsPathParser, lhsPathParser.m_preferred_separator);
|
||||
if (int res = Internal::ComparePathSegment(*lhsPathParser, *rhsPathParser, exactCaseCompare);
|
||||
res != 0)
|
||||
{
|
||||
return res;
|
||||
@@ -646,6 +650,46 @@ namespace AZ::IO::parser
|
||||
return 0;
|
||||
}
|
||||
|
||||
//path.hash
|
||||
/// Path is using FNV-1a algorithm 64 bit version.
|
||||
inline size_t HashSegment(AZStd::string_view pathSegment, bool hashExactPath)
|
||||
{
|
||||
size_t hash = 14695981039346656037ULL;
|
||||
constexpr size_t fnvPrime = 1099511628211ULL;
|
||||
|
||||
for (const char first : pathSegment)
|
||||
{
|
||||
hash ^= static_cast<size_t>(hashExactPath ? first : tolower(first));
|
||||
hash *= fnvPrime;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
constexpr size_t HashPath(PathParser& pathParser)
|
||||
{
|
||||
size_t hash_value = 0;
|
||||
const bool hashExactPath = pathParser.m_preferred_separator == AZ::IO::PosixPathSeparator;
|
||||
while (pathParser)
|
||||
{
|
||||
switch (pathParser.m_parser_state)
|
||||
{
|
||||
case PS_InRootName:
|
||||
case PS_InFilenames:
|
||||
AZStd::hash_combine(hash_value, HashSegment(*pathParser, hashExactPath));
|
||||
break;
|
||||
case PS_InRootDir:
|
||||
// Only hash the PosixPathSeparator when a root directory is seen
|
||||
// This makes the hash consistent for root directories path of C:\ and C:/
|
||||
AZStd::hash_combine(hash_value, HashSegment("/", hashExactPath));
|
||||
break;
|
||||
default:
|
||||
// The BeforeBegin and AtEnd states contain no segments to hash
|
||||
break;
|
||||
}
|
||||
++pathParser;
|
||||
}
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
constexpr int DetermineLexicalElementCount(PathParser pathParser)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
@@ -216,6 +216,11 @@ namespace AZ
|
||||
return m_source->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
auto AllocatorOverrideShim::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_source->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
IAllocatorAllocate* AllocatorOverrideShim::GetSubAllocator()
|
||||
{
|
||||
return m_source->GetSubAllocator();
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace AZ
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -188,6 +188,11 @@ BestFitExternalMapAllocator::GetMaxAllocationSize() const
|
||||
return m_schema->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
auto BestFitExternalMapAllocator::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_schema->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetSubAllocator
|
||||
// [1/28/2011]
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace AZ
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -136,6 +136,12 @@ BestFitExternalMapSchema::GetMaxAllocationSize() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto BestFitExternalMapSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
// Return the maximum size of any single allocation
|
||||
return AZ_CORE_MAX_ALLOCATOR_SIZE;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GarbageCollect
|
||||
// [1/28/2011]
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace AZ
|
||||
AZ_FORCE_INLINE size_type NumAllocatedBytes() const { return m_used; }
|
||||
AZ_FORCE_INLINE size_type Capacity() const { return m_desc.m_memoryBlockByteSize; }
|
||||
size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const;
|
||||
AZ_FORCE_INLINE IAllocatorAllocate* GetSubAllocator() const { return m_desc.m_mapAllocator; }
|
||||
|
||||
/**
|
||||
|
||||
@@ -244,6 +244,11 @@ namespace AZ
|
||||
return maxChunk;
|
||||
}
|
||||
|
||||
auto HeapSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return MAX_REQUEST;
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE HeapSchema::size_type
|
||||
HeapSchema::ChunckSize(pointer_type ptr)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace AZ
|
||||
virtual size_type NumAllocatedBytes() const { return m_used; }
|
||||
virtual size_type Capacity() const { return m_capacity; }
|
||||
virtual size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() { return m_subAllocator; }
|
||||
virtual void GarbageCollect() {}
|
||||
|
||||
|
||||
@@ -1069,6 +1069,7 @@ namespace AZ {
|
||||
/// returns allocation size for the pointer if it belongs to the allocator. result is undefined if the pointer doesn't belong to the allocator.
|
||||
size_t AllocationSize(void* ptr);
|
||||
size_t GetMaxAllocationSize() const;
|
||||
size_t GetMaxContiguousAllocationSize() const;
|
||||
size_t GetUnAllocatedMemory(bool isPrint) const;
|
||||
|
||||
void* SystemAlloc(size_t size, size_t align);
|
||||
@@ -2301,6 +2302,11 @@ namespace AZ {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
size_t HpAllocator::GetMaxContiguousAllocationSize() const
|
||||
{
|
||||
return AZ_CORE_MAX_ALLOCATOR_SIZE;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetUnAllocatedMemory
|
||||
// [9/30/2013]
|
||||
@@ -2677,6 +2683,11 @@ namespace AZ {
|
||||
return m_allocator->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
auto HphaSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_allocator->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetUnAllocatedMemory
|
||||
// [9/30/2013]
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace AZ
|
||||
virtual size_type NumAllocatedBytes() const;
|
||||
virtual size_type Capacity() const;
|
||||
virtual size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual size_type GetUnAllocatedMemory(bool isPrint = false) const;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() { return m_desc.m_subAllocator; }
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace AZ
|
||||
virtual size_type Capacity() const = 0;
|
||||
/// Returns max allocation size if possible. If not returned value is 0
|
||||
virtual size_type GetMaxAllocationSize() const { return 0; }
|
||||
/// Returns the maximum contiguous allocation size of a single allocation
|
||||
virtual size_type GetMaxContiguousAllocationSize() const { return 0; }
|
||||
/**
|
||||
* Returns memory allocated by the allocator and available to the user for allocations.
|
||||
* IMPORTANT: this is not the overhead memory this is just the memory that is allocated, but not used. Example: the pool allocators
|
||||
|
||||
@@ -144,6 +144,11 @@ AZ::MallocSchema::size_type AZ::MallocSchema::GetMaxAllocationSize() const
|
||||
return 0xFFFFFFFFull;
|
||||
}
|
||||
|
||||
AZ::MallocSchema::size_type AZ::MallocSchema::GetMaxContiguousAllocationSize() const
|
||||
{
|
||||
return AZ_CORE_MAX_ALLOCATOR_SIZE;
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* AZ::MallocSchema::GetSubAllocator()
|
||||
{
|
||||
return nullptr;
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace AZ
|
||||
virtual size_type NumAllocatedBytes() const override;
|
||||
virtual size_type Capacity() const override;
|
||||
virtual size_type GetMaxAllocationSize() const override;
|
||||
virtual size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() override;
|
||||
virtual void GarbageCollect() override;
|
||||
|
||||
|
||||
@@ -839,6 +839,11 @@ namespace AZ
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
size_type GetMaxContiguousAllocationSize() const override
|
||||
{
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override
|
||||
{
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetUnAllocatedMemory(isPrint);
|
||||
@@ -896,7 +901,7 @@ namespace AZ
|
||||
}
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
size_type get_max_size() const { return AllocatorInstance<Allocator>::Get().GetMaxAllocationSize(); }
|
||||
size_type max_size() const { return AllocatorInstance<Allocator>::Get().GetMaxContiguousAllocationSize(); }
|
||||
size_type get_allocated_size() const { return AllocatorInstance<Allocator>::Get().NumAllocatedBytes(); }
|
||||
|
||||
AZ_FORCE_INLINE bool is_lock_free() { return AllocatorInstance<Allocator>::Get().is_lock_free(); }
|
||||
@@ -954,7 +959,7 @@ namespace AZ
|
||||
}
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
size_type get_max_size() const { return m_allocator->GetMaxAllocationSize(); }
|
||||
size_type max_size() const { return m_allocator->GetMaxContiguousAllocationSize(); }
|
||||
size_type get_allocated_size() const { return m_allocator->NumAllocatedBytes(); }
|
||||
|
||||
AZ_FORCE_INLINE bool operator==(const AZStdIAllocator& rhs) const { return m_allocator == rhs.m_allocator; }
|
||||
@@ -1006,7 +1011,7 @@ namespace AZ
|
||||
}
|
||||
constexpr const char* get_name() const { return m_name; }
|
||||
void set_name(const char* name) { m_name = name; }
|
||||
size_type get_max_size() const { return m_allocatorFunctor().GetMaxAllocationSize(); }
|
||||
size_type max_size() const { return m_allocatorFunctor().GetMaxContiguousAllocationSize(); }
|
||||
size_type get_allocated_size() const { return m_allocatorFunctor().NumAllocatedBytes(); }
|
||||
|
||||
constexpr bool operator==(const AZStdFunctorAllocator& rhs) const { return m_allocatorFunctor == rhs.m_allocatorFunctor; }
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace AZ
|
||||
size_type NumAllocatedBytes() const override { return m_custom ? m_custom->NumAllocatedBytes() : m_numAllocatedBytes; }
|
||||
size_type Capacity() const override { return m_custom ? m_custom->Capacity() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
size_type GetMaxAllocationSize() const override { return m_custom ? m_custom->GetMaxAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
size_type GetMaxContiguousAllocationSize() const override { return m_custom ? m_custom->GetMaxContiguousAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_custom ? m_custom : NULL; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -232,6 +232,7 @@ namespace AZ
|
||||
size_type NumAllocatedBytes() const;
|
||||
size_type Capacity() const;
|
||||
size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const;
|
||||
IAllocatorAllocate* GetSubAllocator();
|
||||
void GarbageCollect();
|
||||
|
||||
@@ -674,6 +675,11 @@ AZ::OverrunDetectionSchema::size_type AZ::OverrunDetectionSchemaImpl::GetMaxAllo
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto AZ::OverrunDetectionSchemaImpl::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchemaImpl::GetSubAllocator()
|
||||
{
|
||||
return nullptr;
|
||||
@@ -799,6 +805,11 @@ AZ::OverrunDetectionSchema::size_type AZ::OverrunDetectionSchema::GetMaxAllocati
|
||||
return m_impl->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
auto AZ::OverrunDetectionSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_impl->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchema::GetSubAllocator()
|
||||
{
|
||||
return m_impl->GetSubAllocator();
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace AZ
|
||||
virtual size_type NumAllocatedBytes() const override;
|
||||
virtual size_type Capacity() const override;
|
||||
virtual size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() override;
|
||||
virtual void GarbageCollect() override;
|
||||
|
||||
|
||||
@@ -707,6 +707,11 @@ PoolSchema::GarbageCollect()
|
||||
//m_impl->GarbageCollect();
|
||||
}
|
||||
|
||||
auto PoolSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_impl->m_allocator.m_maxAllocationSize;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// NumAllocatedBytes
|
||||
// [11/1/2010]
|
||||
@@ -1052,6 +1057,11 @@ ThreadPoolSchema::GarbageCollect()
|
||||
m_impl->GarbageCollect();
|
||||
}
|
||||
|
||||
auto ThreadPoolSchema::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_impl->m_maxAllocationSize;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// NumAllocatedBytes
|
||||
// [11/1/2010]
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace AZ
|
||||
/// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations.
|
||||
void GarbageCollect() override;
|
||||
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
@@ -115,6 +116,7 @@ namespace AZ
|
||||
/// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations.
|
||||
void GarbageCollect() override;
|
||||
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
|
||||
@@ -179,6 +179,11 @@ namespace AZ
|
||||
return m_schema->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
size_type GetMaxContiguousAllocationSize() const override
|
||||
{
|
||||
return m_schema->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override
|
||||
{
|
||||
return m_schema->GetUnAllocatedMemory(isPrint);
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace AZ
|
||||
size_type Capacity() const override { return m_allocator->Capacity(); }
|
||||
/// Keep in mind this operation will execute GarbageCollect to make sure it returns, max allocation. This function WILL be slow.
|
||||
size_type GetMaxAllocationSize() const override { return m_allocator->GetMaxAllocationSize(); }
|
||||
size_type GetMaxContiguousAllocationSize() const override { return m_allocator->GetMaxContiguousAllocationSize(); }
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override { return m_allocator->GetUnAllocatedMemory(isPrint); }
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_isCustom ? m_allocator : m_allocator->GetSubAllocator(); }
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace AZ
|
||||
|
||||
const char* get_name() const { return m_name; }
|
||||
void set_name(const char* name) { m_name = name; }
|
||||
size_type get_max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
|
||||
constexpr size_type max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
|
||||
size_type get_allocated_size() const { return 0; }
|
||||
|
||||
bool is_lock_free() { return false; }
|
||||
|
||||
@@ -2306,7 +2306,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else // even references are stored by value as we need to convert from lua native type, i.e. there is not real reference for NativeTypes (numbers, strings, etc.)
|
||||
{
|
||||
bool usedBackupAlloc = false;
|
||||
if (backupAllocator != nullptr && sizeof(T) > tempAllocator.get_max_size())
|
||||
if (backupAllocator != nullptr && sizeof(T) > AZStd::allocator_traits<decltype(tempAllocator)>::max_size(tempAllocator))
|
||||
{
|
||||
value.m_value = backupAllocator->allocate(sizeof(T), AZStd::alignment_of<T>::value, 0);
|
||||
usedBackupAlloc = true;
|
||||
@@ -2340,7 +2340,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else // it's a value type
|
||||
{
|
||||
bool usedBackupAlloc = false;
|
||||
if (backupAllocator != nullptr && valueClass->m_size > tempAllocator.get_max_size())
|
||||
if (backupAllocator != nullptr && valueClass->m_size > AZStd::allocator_traits<decltype(tempAllocator)>::max_size(tempAllocator))
|
||||
{
|
||||
value.m_value = backupAllocator->allocate(valueClass->m_size, valueClass->m_alignment, 0);
|
||||
usedBackupAlloc = true;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace UnitTest
|
||||
|
||||
virtual ~AllocatorsBase() = default;
|
||||
|
||||
void SetupAllocator()
|
||||
void SetupAllocator(const AZ::SystemAllocator::Descriptor& allocatorDesc = {})
|
||||
{
|
||||
m_drillerManager = AZ::Debug::DrillerManager::Create();
|
||||
m_drillerManager->Register(aznew AZ::Debug::MemoryDriller);
|
||||
@@ -54,7 +54,7 @@ namespace UnitTest
|
||||
// Only create the SystemAllocator if it s not ready
|
||||
if (!AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady())
|
||||
{
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create(allocatorDesc);
|
||||
m_ownsAllocator = true;
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,7 @@ namespace UnitTest
|
||||
{
|
||||
public:
|
||||
ScopedAllocatorSetupFixture() { SetupAllocator(); }
|
||||
explicit ScopedAllocatorSetupFixture(const AZ::SystemAllocator::Descriptor& allocatorDesc) { SetupAllocator(allocatorDesc); }
|
||||
~ScopedAllocatorSetupFixture() { TeardownAllocator(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -40,15 +40,11 @@ namespace AZStd
|
||||
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().Resize(ptr, newSize);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// get_max_size
|
||||
// [1/1/2008]
|
||||
//=========================================================================
|
||||
allocator::size_type
|
||||
allocator::get_max_size() const
|
||||
auto allocator::max_size() const -> size_type
|
||||
{
|
||||
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().GetMaxAllocationSize();
|
||||
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// get_allocated_size
|
||||
// [1/1/2008]
|
||||
|
||||
@@ -49,8 +49,8 @@ namespace AZStd
|
||||
* const char* get_name() const;
|
||||
* void set_name(const char* name);
|
||||
*
|
||||
* // Returns maximum size we can allocate from this allocator.
|
||||
* size_type get_max_size() const;
|
||||
* // Returns theoretical maximum size of a single contiguous allocation from this allocator.
|
||||
* size_type max_size() const;
|
||||
* <optional> size_type get_allocated_size() const;
|
||||
* };
|
||||
*
|
||||
@@ -100,7 +100,8 @@ namespace AZStd
|
||||
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0);
|
||||
void deallocate(pointer_type ptr, size_type byteSize, size_type alignment);
|
||||
size_type resize(pointer_type ptr, size_type newSize);
|
||||
size_type get_max_size() const;
|
||||
// max_size actually returns the true maximum size of a single allocation
|
||||
size_type max_size() const;
|
||||
size_type get_allocated_size() const;
|
||||
|
||||
AZ_FORCE_INLINE bool is_lock_free() { return false; }
|
||||
@@ -157,7 +158,7 @@ namespace AZStd
|
||||
AZ_FORCE_INLINE const char* get_name() const;
|
||||
AZ_FORCE_INLINE void set_name(const char* name);
|
||||
|
||||
AZ_FORCE_INLINE size_type get_max_size() const;
|
||||
AZ_FORCE_INLINE size_type max_size() const;
|
||||
|
||||
AZ_FORCE_INLINE bool is_lock_free();
|
||||
AZ_FORCE_INLINE bool is_stale_read_allowed();
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace AZStd
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
|
||||
AZ_FORCE_INLINE size_type get_max_size() const { return m_allocator->get_max_size(); }
|
||||
constexpr size_type max_size() const { return m_allocator->max_size(); }
|
||||
|
||||
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_allocator->get_allocated_size(); }
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace AZStd
|
||||
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
AZ_FORCE_INLINE size_type get_max_size() const { return m_size - (m_freeData - m_data); }
|
||||
constexpr size_type max_size() const { return m_size; }
|
||||
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - m_data; }
|
||||
|
||||
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0)
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace AZStd
|
||||
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
AZ_FORCE_INLINE size_type get_max_size() const { return Size - (m_freeData - reinterpret_cast<const char*>(&m_data)); }
|
||||
constexpr size_type max_size() const { return Size; }
|
||||
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - reinterpret_cast<const char*>(&m_data); }
|
||||
|
||||
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0)
|
||||
@@ -190,7 +190,7 @@ namespace AZStd
|
||||
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
AZ_FORCE_INLINE size_type get_max_size() const { return (NumNodes - m_numOfAllocatedNodes) * sizeof(Node); }
|
||||
constexpr size_type max_size() const { return NumNodes * sizeof(Node); }
|
||||
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes * sizeof(Node); }
|
||||
|
||||
inline Node* allocate()
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef AZSTD_DEQUE_H
|
||||
#define AZSTD_DEQUE_H 1
|
||||
|
||||
|
||||
#include <AzCore/std/allocator.h>
|
||||
#include <AzCore/std/allocator_traits.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/createdestroy.h>
|
||||
#include <AzCore/std/typetraits/aligned_storage.h>
|
||||
@@ -350,7 +349,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE size_type size() const { return m_size; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.get_max_size() / sizeof(block_node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(block_node_type); }
|
||||
AZ_FORCE_INLINE bool empty() const { return m_size == 0; }
|
||||
|
||||
AZ_FORCE_INLINE const_reference at(size_type offset) const { return *const_iterator(AZSTD_CHECKED_ITERATOR_2(const_iterator_impl, m_firstOffset + offset, this)); }
|
||||
@@ -1243,5 +1242,3 @@ namespace AZStd
|
||||
return removedCount;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // AZSTD_DEQUE_H
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE size_type size() const { return m_numElements; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); }
|
||||
|
||||
AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); }
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZSTD_LIST_H
|
||||
#define AZSTD_LIST_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/allocator.h>
|
||||
#include <AzCore/std/allocator_traits.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/createdestroy.h>
|
||||
#include <AzCore/std/typetraits/alignment_of.h>
|
||||
@@ -316,7 +316,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE size_type size() const { return m_numElements; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); }
|
||||
|
||||
AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); }
|
||||
@@ -1346,5 +1346,3 @@ namespace AZStd
|
||||
return container.remove_if(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // AZSTD_LIST_H
|
||||
|
||||
@@ -484,7 +484,7 @@ namespace AZStd
|
||||
|
||||
AZ_FORCE_INLINE bool empty() const { return m_numElements == 0; }
|
||||
AZ_FORCE_INLINE size_type size() const { return m_numElements; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
|
||||
|
||||
rbtree(this_type&& rhs)
|
||||
: m_numElements(0) // it will be set during swap
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZSTD_RINGBUFFER_H
|
||||
#define AZSTD_RINGBUFFER_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/allocator.h>
|
||||
#include <AzCore/std/allocator_traits.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/createdestroy.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
@@ -416,7 +417,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE size_type size() const { return m_size; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE bool empty() const { return m_size == 0; }
|
||||
AZ_FORCE_INLINE bool full() const { return size_type(m_end - m_buff) == m_size; }
|
||||
AZ_FORCE_INLINE size_type free() const { return size_type(m_end - m_buff) - m_size; }
|
||||
@@ -1240,6 +1241,3 @@ namespace AZStd
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // AZSTD_RINGBUFFER_H
|
||||
#pragma once
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzCore/std/allocator.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/allocator_traits.h>
|
||||
#include <AzCore/std/createdestroy.h>
|
||||
#include <AzCore/std/typetraits/alignment_of.h>
|
||||
#include <AzCore/std/typetraits/is_integral.h>
|
||||
@@ -431,7 +432,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE size_type size() const { return m_last - m_start; }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.get_max_size() / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
|
||||
AZ_FORCE_INLINE bool empty() const { return m_start == m_last; }
|
||||
|
||||
void reserve(size_type numElements)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace AZStd
|
||||
* Internally the buffer is allocated using aligned_storage.
|
||||
* \note only allocate/deallocate are thread safe.
|
||||
* reset, leak_before_destroy and comparison operators are not thread safe.
|
||||
* get_max_size and get_allocated_size are thread safe but the returned value is not perfectly in
|
||||
* get_allocated_size is thread safe but the returned value is not perfectly in
|
||||
* sync on the actual number of allocations (the number of allocations is incremented before the
|
||||
* allocation happens and decremented after the allocation happens, trying to give a conservative
|
||||
* number)
|
||||
@@ -71,7 +71,7 @@ namespace AZStd
|
||||
|
||||
AZ_FORCE_INLINE const char* get_name() const { return m_name; }
|
||||
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
|
||||
AZ_FORCE_INLINE size_type get_max_size() const { return (NumNodes - m_numOfAllocatedNodes.load(AZStd::memory_order_relaxed)) * sizeof(Node); }
|
||||
constexpr size_type max_size() const { return NumNodes * sizeof(Node); }
|
||||
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes.load(AZStd::memory_order_relaxed) * sizeof(Node); }
|
||||
|
||||
inline Node* allocate()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/std/base.h>
|
||||
#include <AzCore/std/iterator.h>
|
||||
#include <AzCore/std/allocator.h>
|
||||
#include <AzCore/std/allocator_traits.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/typetraits/alignment_of.h>
|
||||
#include <AzCore/std/typetraits/is_integral.h>
|
||||
@@ -862,8 +863,7 @@ namespace AZStd
|
||||
inline size_type max_size() const
|
||||
{
|
||||
// return maximum possible length of sequence
|
||||
size_type num = m_allocator.get_max_size();
|
||||
return (num <= 1 ? 1 : num - 1);
|
||||
return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(value_type);
|
||||
}
|
||||
|
||||
inline void resize(size_type newSize)
|
||||
|
||||
@@ -122,8 +122,15 @@ namespace UnitTest
|
||||
|
||||
TEST_F(AllocatorDefaultTest, AllocatorTraitsMaxSizeCompilesWithoutErrors)
|
||||
{
|
||||
using AZStdAllocatorTraits = AZStd::allocator_traits<AZStd::allocator>;
|
||||
AZStd::allocator testAllocator("trait allocator");
|
||||
struct AllocatorWithGetMaxSize
|
||||
: AZStd::allocator
|
||||
{
|
||||
using AZStd::allocator::allocator;
|
||||
size_t get_max_size() { return max_size(); }
|
||||
};
|
||||
|
||||
using AZStdAllocatorTraits = AZStd::allocator_traits<AllocatorWithGetMaxSize>;
|
||||
AllocatorWithGetMaxSize testAllocator("trait allocator");
|
||||
typename AZStdAllocatorTraits::size_type maxSize = AZStdAllocatorTraits::max_size(testAllocator);
|
||||
EXPECT_EQ(testAllocator.get_max_size(), maxSize);
|
||||
}
|
||||
@@ -149,32 +156,32 @@ namespace UnitTest
|
||||
myalloc.set_name(newName);
|
||||
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
|
||||
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize));
|
||||
EXPECT_EQ(bufferSize, myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
buffer_alloc_type::pointer_type data = myalloc.allocate(100, 1);
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100);
|
||||
EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
|
||||
|
||||
myalloc.deallocate(data, 100, 1); // we can free the last allocation only
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize);
|
||||
EXPECT_EQ(bufferSize, myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
data = myalloc.allocate(100, 1);
|
||||
myalloc.allocate(3, 1);
|
||||
myalloc.deallocate(data); // can't free allocation which is not the last.
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 103);
|
||||
EXPECT_EQ(bufferSize - 103, myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 103);
|
||||
|
||||
myalloc.reset();
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize));
|
||||
EXPECT_EQ(bufferSize, myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
data = myalloc.allocate(50, 64);
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() <= bufferSize - 50);
|
||||
EXPECT_LE(myalloc.max_size() - myalloc.get_allocated_size(), bufferSize - 50);
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50);
|
||||
|
||||
buffer_alloc_type myalloc2;
|
||||
@@ -194,28 +201,28 @@ namespace UnitTest
|
||||
myalloc.set_name(newName);
|
||||
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
|
||||
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == sizeof(int) * numNodes);
|
||||
EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
int* data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1));
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == (numNodes - 1) * sizeof(int));
|
||||
EXPECT_EQ((numNodes - 1) * sizeof(int), myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == sizeof(int));
|
||||
|
||||
myalloc.deallocate(data, sizeof(int), 1);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == sizeof(int) * numNodes);
|
||||
EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
for (int i = 0; i < numNodes; ++i)
|
||||
{
|
||||
data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1));
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == (numNodes - (i + 1)) * sizeof(int));
|
||||
EXPECT_EQ((numNodes - (i + 1)) * sizeof(int), myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == (i + 1) * sizeof(int));
|
||||
}
|
||||
|
||||
myalloc.reset();
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == numNodes * sizeof(int));
|
||||
EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
AZ_TEST_ASSERT(myalloc == myalloc);
|
||||
@@ -233,7 +240,7 @@ namespace UnitTest
|
||||
|
||||
AZ_TEST_ASSERT(aligned_data != nullptr);
|
||||
AZ_TEST_ASSERT(((AZStd::size_t)aligned_data & (dataAlignment - 1)) == 0);
|
||||
AZ_TEST_ASSERT(myaligned_pool.get_max_size() == (numNodes - 1) * sizeof(aligned_int_type));
|
||||
EXPECT_EQ((numNodes - 1) * sizeof(aligned_int_type), myaligned_pool.max_size() - myaligned_pool.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myaligned_pool.get_allocated_size() == sizeof(aligned_int_type));
|
||||
|
||||
myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated.
|
||||
@@ -268,32 +275,32 @@ namespace UnitTest
|
||||
|
||||
ref_allocator_type::pointer_type data1 = ref_allocator1.allocate(10, 1);
|
||||
AZ_TEST_ASSERT(data1 != nullptr);
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_max_size() == bufferSize - 10);
|
||||
EXPECT_EQ(bufferSize - 10, ref_allocator1.max_size() - ref_allocator1.get_allocated_size());
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() == 10);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_max_size() == bufferSize - 10);
|
||||
EXPECT_EQ(bufferSize - 10, shared_allocator.max_size() - shared_allocator.get_allocated_size());
|
||||
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() == 10);
|
||||
|
||||
ref_allocator_type::pointer_type data2 = ref_allocator2.allocate(10, 1);
|
||||
AZ_TEST_ASSERT(data2 != nullptr);
|
||||
AZ_TEST_ASSERT(ref_allocator2.get_max_size() <= bufferSize - 20);
|
||||
EXPECT_LE(ref_allocator2.max_size() - ref_allocator2.get_allocated_size(), bufferSize - 20);
|
||||
AZ_TEST_ASSERT(ref_allocator2.get_allocated_size() >= 20);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 20);
|
||||
EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 20);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20);
|
||||
|
||||
shared_allocator.reset();
|
||||
|
||||
data1 = ref_allocator1.allocate(10, 32);
|
||||
AZ_TEST_ASSERT(data1 != nullptr);
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_max_size() <= bufferSize - 10);
|
||||
EXPECT_LE(ref_allocator1.max_size() - ref_allocator1.get_allocated_size(), bufferSize - 10);
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 10);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 10);
|
||||
EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 10);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 10);
|
||||
|
||||
data2 = ref_allocator2.allocate(10, 32);
|
||||
AZ_TEST_ASSERT(data2 != nullptr);
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_max_size() <= bufferSize - 20);
|
||||
EXPECT_LE(ref_allocator1.max_size() - ref_allocator1.get_allocated_size(), bufferSize - 20);
|
||||
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 20);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 20);
|
||||
EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 20);
|
||||
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20);
|
||||
|
||||
AZ_TEST_ASSERT(ref_allocator1 == ref_allocator2);
|
||||
@@ -312,31 +319,31 @@ namespace UnitTest
|
||||
myalloc.set_name(newName);
|
||||
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
|
||||
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize));
|
||||
EXPECT_EQ(bufferSize, myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
stack_allocator::pointer_type data = myalloc.allocate(100, 1);
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100);
|
||||
EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
|
||||
|
||||
myalloc.deallocate(data, 100, 1); // this allocator doesn't free data
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100);
|
||||
EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
|
||||
|
||||
myalloc.reset();
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize));
|
||||
EXPECT_EQ(bufferSize, myalloc.max_size());
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
|
||||
|
||||
data = myalloc.allocate(50, 64);
|
||||
AZ_TEST_ASSERT(data != nullptr);
|
||||
AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0);
|
||||
AZ_TEST_ASSERT(myalloc.get_max_size() <= bufferSize - 50);
|
||||
EXPECT_LE(myalloc.max_size() - myalloc.get_allocated_size(), bufferSize - 50);
|
||||
AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50);
|
||||
|
||||
AZ_STACK_ALLOCATOR(myalloc2, 200); // test the macro declaration
|
||||
|
||||
AZ_TEST_ASSERT(myalloc2.get_max_size() == 200);
|
||||
EXPECT_EQ(200, myalloc2.max_size() );
|
||||
|
||||
AZ_TEST_ASSERT(myalloc == myalloc);
|
||||
AZ_TEST_ASSERT((myalloc2 != myalloc));
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace UnitTest
|
||||
const char newName[] = "My new test allocator";
|
||||
myalloc.set_name(newName);
|
||||
EXPECT_EQ(0, strcmp(myalloc.get_name(), newName));
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.get_max_size());
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.max_size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,10 +61,10 @@ namespace UnitTest
|
||||
typename TestFixture::allocator_type::pointer_type data = myalloc.allocate();
|
||||
EXPECT_NE(nullptr, data);
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_allocated_size());
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (s_allocatorCapacity - 1), myalloc.get_max_size());
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (s_allocatorCapacity - 1), myalloc.max_size() - myalloc.get_allocated_size());
|
||||
myalloc.deallocate(data);
|
||||
EXPECT_EQ(0, myalloc.get_allocated_size());
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.get_max_size());
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.max_size());
|
||||
}
|
||||
|
||||
TYPED_TEST(ConcurrentAllocatorTestFixture, MultipleAllocateDeallocate)
|
||||
@@ -84,19 +84,19 @@ namespace UnitTest
|
||||
EXPECT_EQ(dataSize, dataSet.size());
|
||||
dataSet.clear();
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * dataSize, myalloc.get_allocated_size());
|
||||
EXPECT_EQ((s_allocatorCapacity - dataSize) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size());
|
||||
EXPECT_EQ((s_allocatorCapacity - dataSize) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size() - myalloc.get_allocated_size());
|
||||
for (size_t i = 0; i < dataSize; i += 2)
|
||||
{
|
||||
myalloc.deallocate(data[i]);
|
||||
}
|
||||
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (dataSize / 2), myalloc.get_allocated_size());
|
||||
EXPECT_EQ((s_allocatorCapacity - dataSize / 2) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size());
|
||||
EXPECT_EQ((s_allocatorCapacity - dataSize / 2) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size() - myalloc.get_allocated_size());
|
||||
for (size_t i = 1; i < dataSize; i += 2)
|
||||
{
|
||||
myalloc.deallocate(data[i]);
|
||||
}
|
||||
EXPECT_EQ(0, myalloc.get_allocated_size());
|
||||
EXPECT_EQ(s_allocatorCapacity * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size());
|
||||
EXPECT_EQ(s_allocatorCapacity * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size());
|
||||
}
|
||||
|
||||
TYPED_TEST(ConcurrentAllocatorTestFixture, ConcurrentAllocateoDeallocate)
|
||||
@@ -159,7 +159,7 @@ namespace UnitTest
|
||||
|
||||
EXPECT_NE(nullptr, aligned_data);
|
||||
EXPECT_EQ(0, ((AZStd::size_t)aligned_data & (dataAlignment - 1)));
|
||||
EXPECT_EQ((s_allocatorCapacity - 1) * sizeof(aligned_int_type), myaligned_pool.get_max_size());
|
||||
EXPECT_EQ((s_allocatorCapacity - 1) * sizeof(aligned_int_type), myaligned_pool.max_size() - myaligned_pool.get_allocated_size());
|
||||
EXPECT_EQ(sizeof(aligned_int_type), myaligned_pool.get_allocated_size());
|
||||
|
||||
myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated.
|
||||
|
||||
@@ -213,6 +213,82 @@ namespace UnitTest
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>(R"(foO/Bar)", "foo/bar")
|
||||
));
|
||||
|
||||
|
||||
struct PathHashCompareParams
|
||||
{
|
||||
AZ::IO::PathView m_testPath{};
|
||||
::testing::Matcher<AZ::IO::PathView> m_compareMatcher;
|
||||
::testing::Matcher<size_t> m_hashMatcher;
|
||||
};
|
||||
|
||||
class PathHashCompareFixture
|
||||
: public ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<PathHashCompareParams>
|
||||
{};
|
||||
|
||||
// Verifies that two paths that compare equal has their hash value compare equal
|
||||
TEST_P(PathHashCompareFixture, PathsWhichCompareEqual_HashesToSameValue_Succeeds)
|
||||
{
|
||||
auto&& [testPath1, compareMatcher, hashMatcher] = GetParam();
|
||||
|
||||
// Compare path using parameterized Matcher
|
||||
EXPECT_THAT(testPath1, compareMatcher);
|
||||
// Compare hash using parameterized Matcher
|
||||
const size_t testPath1Hash = AZStd::hash<AZ::IO::PathView>{}(testPath1);
|
||||
AZ_PUSH_DISABLE_WARNING(4296, "-Wunknown-warning-option")
|
||||
EXPECT_THAT(testPath1Hash, hashMatcher);
|
||||
AZ_POP_DISABLE_WARNING
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HashPathCompareValidation,
|
||||
PathHashCompareFixture,
|
||||
::testing::Values(
|
||||
PathHashCompareParams{ AZ::IO::PathView("C:/test/foo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Eq(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/foo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Eq(AZ::IO::PathView(R"(/test/FOO)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/FOO)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("C:/test/foo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Eq(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("C:/test/foo", AZ::IO::PosixPathSeparator),
|
||||
testing::Ne(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(c:\test/foo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView(R"(C:\test\foo)", AZ::IO::WindowsPathSeparator),
|
||||
testing::Ne(AZ::IO::PathView(R"(c:/test/foo)", AZ::IO::PosixPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(c:/test/foo)", AZ::IO::PosixPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/aoo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Eq(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/aoo", AZ::IO::PosixPathSeparator),
|
||||
testing::Gt(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/aoo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Gt(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::PosixPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/AOO)", AZ::IO::PosixPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/AOO", AZ::IO::PosixPathSeparator),
|
||||
testing::Lt(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/AOO", AZ::IO::WindowsPathSeparator),
|
||||
testing::Lt(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::PosixPathSeparator)),
|
||||
testing::Eq(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::PosixPathSeparator))) },
|
||||
// Paths with different character values, comparison based on path separator
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/BOO", AZ::IO::PosixPathSeparator),
|
||||
testing::Le(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/BOO", AZ::IO::WindowsPathSeparator),
|
||||
testing::Ge(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/aoo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/aoo", AZ::IO::WindowsPathSeparator),
|
||||
testing::Le(AZ::IO::PathView(R"(/test/Boo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/Boo)", AZ::IO::WindowsPathSeparator))) },
|
||||
PathHashCompareParams{ AZ::IO::PathView("/test/aoo", AZ::IO::PosixPathSeparator),
|
||||
testing::Ge(AZ::IO::PathView(R"(/test/Boo)", AZ::IO::WindowsPathSeparator)),
|
||||
testing::Ne(AZStd::hash<AZ::IO::PathView>{}(AZ::IO::PathView(R"(/test/Boo)", AZ::IO::WindowsPathSeparator))) }
|
||||
));
|
||||
|
||||
class PathSingleParamFixture
|
||||
: public ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<AZStd::tuple<AZStd::string_view>>
|
||||
|
||||
@@ -1179,6 +1179,8 @@ namespace UnitTest
|
||||
size_type Capacity() const override { return 1 * 1024 * 1024 * 1024; }
|
||||
/// Returns max allocation size if possible. If not returned value is 0
|
||||
size_type GetMaxAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
|
||||
/// Returns max allocation size of a single contiguous allocation
|
||||
size_type GetMaxContiguousAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
|
||||
/// Returns a pointer to a sub-allocator or NULL.
|
||||
IAllocatorAllocate* GetSubAllocator() override { return NULL; }
|
||||
};
|
||||
|
||||
@@ -2185,7 +2185,7 @@ namespace AZ::IO
|
||||
AZStd::unique_lock lock(m_archiveMutex);
|
||||
if (pArchive)
|
||||
{
|
||||
AZ_TracePrintf("Archive", "Closing Archive file: %s", pArchive->GetFullPath());
|
||||
AZ_TracePrintf("Archive", "Closing Archive file: %s\n", pArchive->GetFullPath());
|
||||
}
|
||||
ArchiveArray::iterator it;
|
||||
if (m_arrArchives.size() < 16)
|
||||
|
||||
@@ -51,7 +51,8 @@ namespace AzFramework
|
||||
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormal)
|
||||
->Event("GetNormalFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormalFromFloats)
|
||||
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
|
||||
->Event("GetTerrainGridResolution", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainGridResolution)
|
||||
->Event("GetTerrainHeightQueryResolution",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
@@ -59,8 +59,11 @@ namespace AzFramework
|
||||
static AZ::Vector3 GetDefaultTerrainNormal() { return AZ::Vector3::CreateAxisZ(); }
|
||||
|
||||
// System-level queries to understand world size and resolution
|
||||
virtual AZ::Vector2 GetTerrainGridResolution() const = 0;
|
||||
virtual AZ::Vector2 GetTerrainHeightQueryResolution() const = 0;
|
||||
virtual void SetTerrainHeightQueryResolution(AZ::Vector2 queryResolution) = 0;
|
||||
|
||||
virtual AZ::Aabb GetTerrainAabb() const = 0;
|
||||
virtual void SetTerrainAabb(const AZ::Aabb& worldBounds) = 0;
|
||||
|
||||
//! Returns terrains height in meters at location x,y.
|
||||
//! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will become false,
|
||||
|
||||
+18
-19
@@ -263,21 +263,29 @@ namespace AzFramework
|
||||
}
|
||||
commandAndArgs[commandTokens.size()] = nullptr;
|
||||
|
||||
AZStd::vector<AZStd::unique_ptr<char[]>> environmentVariablesManaged;
|
||||
AZStd::vector<char*> environmentVariablesVector;
|
||||
char** environmentVariables = nullptr;
|
||||
int numEnvironmentVars = 0;
|
||||
if (processLaunchInfo.m_environmentVariables)
|
||||
{
|
||||
numEnvironmentVars = processLaunchInfo.m_environmentVariables->size();
|
||||
// Adding one more as exec expects the array to have a nullptr as the last element
|
||||
environmentVariables = new char*[numEnvironmentVars + 1];
|
||||
for (int i = 0; i < numEnvironmentVars; i++)
|
||||
for (const auto& envVarString : *processLaunchInfo.m_environmentVariables)
|
||||
{
|
||||
const AZStd::string& envVarString = processLaunchInfo.m_environmentVariables->at(i);
|
||||
environmentVariables[i] = new char[envVarString.size() + 1];
|
||||
environmentVariables[i][0] = '\0';
|
||||
azstrcat(environmentVariables[i], envVarString.size(), envVarString.c_str());
|
||||
auto& environmentVariable = environmentVariablesManaged.emplace_back(AZStd::make_unique<char[]>(envVarString.size() + 1));
|
||||
environmentVariable[0] = '\0';
|
||||
azstrcat(environmentVariable.get(), envVarString.size() + 1, envVarString.c_str());
|
||||
environmentVariablesVector.emplace_back(environmentVariable.get());
|
||||
}
|
||||
environmentVariables[numEnvironmentVars] = nullptr;
|
||||
// Adding one more as exec expects the array to have a nullptr as the last element
|
||||
environmentVariablesVector.emplace_back(nullptr);
|
||||
environmentVariables = environmentVariablesVector.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no environment variables were specified, then use the current process's environment variables
|
||||
// and pass it along for the execute .
|
||||
extern char **environ; // Defined in unistd.h
|
||||
environmentVariables = ::environ;
|
||||
AZ_Assert(environmentVariables, "Environment variables for current process not available\n");
|
||||
}
|
||||
|
||||
pid_t child_pid = fork();
|
||||
@@ -290,15 +298,6 @@ namespace AzFramework
|
||||
// Close these handles as they are only to be used by the child process
|
||||
processData.m_startupInfo.CloseAllHandles();
|
||||
|
||||
if (processLaunchInfo.m_environmentVariables)
|
||||
{
|
||||
for (int i = 0; i < numEnvironmentVars; i++)
|
||||
{
|
||||
delete [] environmentVariables[i];
|
||||
}
|
||||
delete [] environmentVariables;
|
||||
}
|
||||
|
||||
for (int i = 0; i < commandTokens.size(); i++)
|
||||
{
|
||||
delete [] commandAndArgs[i];
|
||||
|
||||
+13
-2
@@ -39,6 +39,8 @@ namespace AzManipulatorTestFramework
|
||||
DerivedDispatcherT* MouseLButtonDown();
|
||||
//! Set the left mouse button up.
|
||||
DerivedDispatcherT* MouseLButtonUp();
|
||||
//! Send a double click event.
|
||||
DerivedDispatcherT* MouseLButtonDoubleClick();
|
||||
//! Set the keyboard modifier button down.
|
||||
DerivedDispatcherT* KeyboardModifierDown(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier);
|
||||
//! Set the keyboard modifier button up.
|
||||
@@ -71,6 +73,7 @@ namespace AzManipulatorTestFramework
|
||||
virtual void CameraStateImpl(const AzFramework::CameraState& cameraState) = 0;
|
||||
virtual void MouseLButtonDownImpl() = 0;
|
||||
virtual void MouseLButtonUpImpl() = 0;
|
||||
virtual void MouseLButtonDoubleClickImpl() = 0;
|
||||
virtual void MousePositionImpl(const AzFramework::ScreenPoint& position) = 0;
|
||||
virtual void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0;
|
||||
virtual void KeyboardModifierUpImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0;
|
||||
@@ -167,7 +170,7 @@ namespace AzManipulatorTestFramework
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonDown()
|
||||
{
|
||||
Log("%s", "Mouse left button down");
|
||||
Log("Mouse left button down");
|
||||
MouseLButtonDownImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
@@ -175,11 +178,19 @@ namespace AzManipulatorTestFramework
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonUp()
|
||||
{
|
||||
Log("%s", "Mouse left button up");
|
||||
Log("Mouse left button up");
|
||||
MouseLButtonUpImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonDoubleClick()
|
||||
{
|
||||
Log("Mouse left button double click");
|
||||
MouseLButtonDoubleClickImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
|
||||
template<typename DerivedDispatcherT>
|
||||
const char* ActionDispatcher<DerivedDispatcherT>::KeyboardModifierString(
|
||||
const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier)
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ namespace AzManipulatorTestFramework
|
||||
void CameraStateImpl(const AzFramework::CameraState& cameraState) override;
|
||||
void MouseLButtonDownImpl() override;
|
||||
void MouseLButtonUpImpl() override;
|
||||
void MouseLButtonDoubleClickImpl() override;
|
||||
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
|
||||
void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override;
|
||||
void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override;
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include <AzManipulatorTestFramework/ActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzCore/std/containers/list.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
//! Buffers actions to be dispatched upon a call to Execute().
|
||||
class RetainedModeActionDispatcher
|
||||
: public ActionDispatcher<RetainedModeActionDispatcher>
|
||||
{
|
||||
public:
|
||||
explicit RetainedModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction);
|
||||
//! Execute the sequence of actions and lock the dispatcher from adding further actions.
|
||||
RetainedModeActionDispatcher* Execute();
|
||||
//! Reset the sequence of actions and unlock the dispatcher from adding further actions.
|
||||
RetainedModeActionDispatcher* ResetSequence();
|
||||
|
||||
protected:
|
||||
// ActionDispatcher ...
|
||||
void EnableSnapToGridImpl() override;
|
||||
void DisableSnapToGridImpl() override;
|
||||
void GridSizeImpl(float size) override;
|
||||
void CameraStateImpl(const AzFramework::CameraState& cameraState) override;
|
||||
void MouseLButtonDownImpl() override;
|
||||
void MouseLButtonUpImpl() override;
|
||||
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
|
||||
void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) override;
|
||||
void KeyboardModifierUpImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) override;
|
||||
void ExpectManipulatorBeingInteractedImpl() override;
|
||||
void ExpectManipulatorNotBeingInteractedImpl() override;
|
||||
void SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform) override;
|
||||
void SetSelectedEntityImpl(AZ::EntityId entity) override;
|
||||
void SetSelectedEntitiesImpl(const AzToolsFramework::EntityIdList& entities) override;
|
||||
void EnterComponentModeImpl(const AZ::Uuid& uuid) override;
|
||||
|
||||
private:
|
||||
using Action = AZStd::function<void()>;
|
||||
void AddActionToSequence(Action&& action);
|
||||
ImmediateModeActionDispatcher m_dispatcher;
|
||||
AZStd::list<Action> m_actions;
|
||||
bool m_locked = false;
|
||||
};
|
||||
} // namespace AzManipulatorTestFramework
|
||||
@@ -83,7 +83,17 @@ namespace AzManipulatorTestFramework
|
||||
void ImmediateModeActionDispatcher::MouseLButtonUpImpl()
|
||||
{
|
||||
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*GetMouseInteractionEvent());
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
|
||||
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
// the mouse position will be the same as the previous event, thus the delta will be 0
|
||||
MouseMoveAfterButton();
|
||||
}
|
||||
|
||||
void ImmediateModeActionDispatcher::MouseLButtonDoubleClickImpl()
|
||||
{
|
||||
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick;
|
||||
ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
|
||||
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
// the mouse position will be the same as the previous event, thus the delta will be 0
|
||||
MouseMoveAfterButton();
|
||||
|
||||
@@ -1,129 +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 <AzManipulatorTestFramework/RetainedModeActionDispatcher.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier;
|
||||
|
||||
RetainedModeActionDispatcher::RetainedModeActionDispatcher(
|
||||
ManipulatorViewportInteraction& viewportManipulatorInteraction)
|
||||
: m_dispatcher(viewportManipulatorInteraction)
|
||||
{
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::AddActionToSequence(Action&& action)
|
||||
{
|
||||
if (m_locked)
|
||||
{
|
||||
const char* error = "Couldn't add action to sequence, dispatcher is locked (you must call ResetSequence() \
|
||||
before adding actions to this dispatcher)";
|
||||
Log("%s", error);
|
||||
AZ_Assert(false, "Error: %s", error);
|
||||
}
|
||||
|
||||
m_actions.emplace_back(action);
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::EnableSnapToGridImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.EnableSnapToGrid(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::DisableSnapToGridImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.DisableSnapToGrid(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::GridSizeImpl(float size)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.GridSize(size); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::CameraStateImpl(const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.CameraState(cameraState); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MouseLButtonDownImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MouseLButtonDown(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MouseLButtonUpImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MouseLButtonUp(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MousePosition(position); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::KeyboardModifierDownImpl(const KeyboardModifier& keyModifier)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.KeyboardModifierDown(keyModifier); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::KeyboardModifierUpImpl(const KeyboardModifier& keyModifier)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.KeyboardModifierUp(keyModifier); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::ExpectManipulatorBeingInteractedImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.ExpectManipulatorBeingInteracted(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::ExpectManipulatorNotBeingInteractedImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.ExpectManipulatorNotBeingInteracted(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetEntityWorldTransform(entityId, transform); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetSelectedEntityImpl(AZ::EntityId entity)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetSelectedEntity(entity); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetSelectedEntitiesImpl(const AzToolsFramework::EntityIdList& entities)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetSelectedEntities(entities); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::EnterComponentModeImpl(const AZ::Uuid& uuid)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.EnterComponentMode(uuid); });
|
||||
}
|
||||
|
||||
RetainedModeActionDispatcher* RetainedModeActionDispatcher::ResetSequence()
|
||||
{
|
||||
Log("%s", "Resetting the action sequence");
|
||||
m_actions.clear();
|
||||
m_dispatcher.ResetEvent();
|
||||
m_locked = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
RetainedModeActionDispatcher* RetainedModeActionDispatcher::Execute()
|
||||
{
|
||||
Log("Executing %u actions", m_actions.size());
|
||||
for (auto& action : m_actions)
|
||||
{
|
||||
action();
|
||||
}
|
||||
m_dispatcher.ResetEvent();
|
||||
m_locked = true;
|
||||
return this;
|
||||
}
|
||||
} // namespace AzManipulatorTestFramework
|
||||
@@ -14,12 +14,10 @@ set(FILES
|
||||
Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h
|
||||
Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h
|
||||
Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h
|
||||
Include/AzManipulatorTestFramework/RetainedModeActionDispatcher.h
|
||||
Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h
|
||||
Source/ViewportInteraction.cpp
|
||||
Source/DirectManipulatorViewportInteraction.cpp
|
||||
Source/IndirectManipulatorViewportInteraction.cpp
|
||||
Source/ImmediateModeActionDispatcher.cpp
|
||||
Source/RetainedModeActionDispatcher.cpp
|
||||
Source/AzManipulatorTestFrameworkUtils.cpp
|
||||
)
|
||||
|
||||
@@ -2461,6 +2461,18 @@ namespace AzQtComponents
|
||||
placeholderRect.translate(0, -margins.bottom());
|
||||
}
|
||||
|
||||
// Also adjust the placeholderRect by the relative dpi change from the original screen, since setGeometry uses the screen's
|
||||
// virtualGeometry!
|
||||
QScreen* fromScreen = dock->screen();
|
||||
QScreen* toScreen = Utilities::ScreenAtPoint(placeholderRect.topLeft());
|
||||
|
||||
if (fromScreen != toScreen)
|
||||
{
|
||||
qreal factorRatio = QHighDpiScaling::factor(fromScreen) / QHighDpiScaling::factor(toScreen);
|
||||
placeholderRect.setWidth(aznumeric_cast<int>(aznumeric_cast<qreal>(placeholderRect.width()) * factorRatio));
|
||||
placeholderRect.setHeight(aznumeric_cast<int>(aznumeric_cast<qreal>(placeholderRect.height()) * factorRatio));
|
||||
}
|
||||
|
||||
// Place the floating dock widget
|
||||
makeDockWidgetFloating(dock, placeholderRect);
|
||||
clearDraggingState();
|
||||
|
||||
@@ -169,6 +169,10 @@ namespace AzQtComponents
|
||||
initializeSearchPaths(application, engineRootPath);
|
||||
initializeFonts();
|
||||
|
||||
QFont defaultFont("Open Sans");
|
||||
defaultFont.setPixelSize(12);
|
||||
QApplication::setFont(defaultFont);
|
||||
|
||||
m_titleBarOverdrawHandler = TitleBarOverdrawHandler::createHandler(application, this);
|
||||
|
||||
// The window decoration wrappers require the titlebar overdraw handler
|
||||
|
||||
@@ -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/Casting/numeric_cast.h>
|
||||
#include <AzQtComponents/Utilities/PixmapScaleUtilities.h>
|
||||
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
|
||||
namespace AzQtComponents
|
||||
{
|
||||
QPixmap ScalePixmapForScreenDpi(
|
||||
QPixmap pixmap, QScreen* screen, QSize size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode)
|
||||
{
|
||||
qreal screenDpiFactor = QHighDpiScaling::factor(screen);
|
||||
pixmap.setDevicePixelRatio(screenDpiFactor);
|
||||
|
||||
QPixmap scaledPixmap;
|
||||
|
||||
size.setWidth(aznumeric_cast<int>(aznumeric_cast<qreal>(size.width()) * screenDpiFactor));
|
||||
size.setHeight(aznumeric_cast<int>(aznumeric_cast<qreal>(size.height()) * screenDpiFactor));
|
||||
|
||||
scaledPixmap = pixmap.scaled(size, aspectRatioMode, transformationMode);
|
||||
|
||||
return scaledPixmap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 <AzQtComponents/AzQtComponentsAPI.h>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QScreen>
|
||||
|
||||
namespace AzQtComponents
|
||||
{
|
||||
AZ_QT_COMPONENTS_API QPixmap ScalePixmapForScreenDpi(QPixmap pixmap, QScreen* screen, QSize size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode);
|
||||
}; // namespace AzQtComponents
|
||||
@@ -276,6 +276,8 @@ set(FILES
|
||||
Utilities/HandleDpiAwareness.cpp
|
||||
Utilities/HandleDpiAwareness.h
|
||||
Utilities/MouseHider.h
|
||||
Utilities/PixmapScaleUtilities.cpp
|
||||
Utilities/PixmapScaleUtilities.h
|
||||
Utilities/QtPluginPaths.cpp
|
||||
Utilities/QtPluginPaths.h
|
||||
Utilities/QtWindowUtilities.cpp
|
||||
|
||||
+2
-2
@@ -47,9 +47,9 @@ namespace AzToolsFramework
|
||||
return QString();
|
||||
}
|
||||
|
||||
QPixmap EditorEntityUiHandlerBase::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
QIcon EditorEntityUiHandlerBase::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return QPixmap();
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
bool EditorEntityUiHandlerBase::CanToggleLockVisibility(AZ::EntityId /*entityId*/) const
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ namespace AzToolsFramework
|
||||
//! Returns the item tooltip text to display in the Outliner.
|
||||
virtual QString GenerateItemTooltip(AZ::EntityId entityId) const;
|
||||
//! Returns the item icon pixmap to display in the Outliner.
|
||||
virtual QPixmap GenerateItemIcon(AZ::EntityId entityId) const;
|
||||
virtual QIcon GenerateItemIcon(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's lock and visibility state should be accessible in the Outliner
|
||||
virtual bool CanToggleLockVisibility(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's name should be editable
|
||||
|
||||
@@ -66,9 +66,9 @@ namespace AzToolsFramework
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap LayerUiHandler::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
QIcon LayerUiHandler::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return QPixmap(m_layerIconPath);
|
||||
return QIcon(m_layerIconPath);
|
||||
}
|
||||
|
||||
void LayerUiHandler::PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace AzToolsFramework
|
||||
|
||||
// EditorEntityUiHandler...
|
||||
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
|
||||
QPixmap GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
QIcon GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
void PaintDescendantBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
|
||||
const QModelIndex& descendantIndex) const override;
|
||||
|
||||
+7
-7
@@ -280,17 +280,17 @@ namespace AzToolsFramework
|
||||
QVariant EntityOutlinerListModel::GetEntityIcon(const AZ::EntityId& id) const
|
||||
{
|
||||
auto entityUiHandler = m_editorEntityFrameworkInterface->GetHandler(id);
|
||||
QPixmap pixmap;
|
||||
QIcon icon;
|
||||
|
||||
// Retrieve the icon from the handler
|
||||
if (entityUiHandler != nullptr)
|
||||
{
|
||||
pixmap = entityUiHandler->GenerateItemIcon(id);
|
||||
icon = entityUiHandler->GenerateItemIcon(id);
|
||||
}
|
||||
|
||||
if (!pixmap.isNull())
|
||||
if (!icon.isNull())
|
||||
{
|
||||
return QIcon(pixmap);
|
||||
return icon;
|
||||
}
|
||||
|
||||
// If no icon was returned by the handler, use the default one.
|
||||
@@ -299,7 +299,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (isEditorOnly)
|
||||
{
|
||||
return QIcon(QPixmap(QString(":/Icons/Entity_Editor_Only.svg")));
|
||||
return QIcon(QString(":/Icons/Entity_Editor_Only.svg"));
|
||||
}
|
||||
|
||||
AZ::Entity* entity = nullptr;
|
||||
@@ -308,10 +308,10 @@ namespace AzToolsFramework
|
||||
|
||||
if (!isInitiallyActive)
|
||||
{
|
||||
return QIcon(QPixmap(QString(":/Icons/Entity_Not_Active.svg")));
|
||||
return QIcon(QString(":/Icons/Entity_Not_Active.svg"));
|
||||
}
|
||||
|
||||
return QIcon(QPixmap(QString(":/Icons/Entity.svg")));
|
||||
return QIcon(QString(":/Icons/Entity.svg"));
|
||||
}
|
||||
|
||||
QVariant EntityOutlinerListModel::GetEntityTooltip(const AZ::EntityId& id) const
|
||||
|
||||
@@ -41,9 +41,9 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap LevelRootUiHandler::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
QIcon LevelRootUiHandler::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return QPixmap(m_levelRootIconPath);
|
||||
return QIcon(m_levelRootIconPath);
|
||||
}
|
||||
|
||||
QString LevelRootUiHandler::GenerateItemInfoString(AZ::EntityId entityId) const
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AzToolsFramework
|
||||
~LevelRootUiHandler() override = default;
|
||||
|
||||
// EditorEntityUiHandler...
|
||||
QPixmap GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
QIcon GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
|
||||
bool CanToggleLockVisibility(AZ::EntityId entityId) const override;
|
||||
bool CanRename(AZ::EntityId entityId) const override;
|
||||
|
||||
@@ -81,14 +81,14 @@ namespace AzToolsFramework
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
QPixmap PrefabUiHandler::GenerateItemIcon(AZ::EntityId entityId) const
|
||||
QIcon PrefabUiHandler::GenerateItemIcon(AZ::EntityId entityId) const
|
||||
{
|
||||
if (m_prefabEditInterface->IsOwningPrefabBeingEdited(entityId))
|
||||
{
|
||||
return QPixmap(m_prefabEditIconPath);
|
||||
return QIcon(m_prefabEditIconPath);
|
||||
}
|
||||
|
||||
return QPixmap(m_prefabIconPath);
|
||||
return QIcon(m_prefabIconPath);
|
||||
}
|
||||
|
||||
void PrefabUiHandler::PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace AzToolsFramework
|
||||
// EditorEntityUiHandler...
|
||||
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
|
||||
QString GenerateItemTooltip(AZ::EntityId entityId) const override;
|
||||
QPixmap GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
QIcon GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
void PaintDescendantBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
|
||||
const QModelIndex& descendantIndex) const override;
|
||||
|
||||
@@ -221,24 +221,6 @@ namespace AzToolsFramework
|
||||
|
||||
using ViewportSettingsNotificationBus = AZ::EBus<ViewportSettingNotifications, ViewportEBusTraits>;
|
||||
|
||||
//! Requests to freeze the Viewport Input
|
||||
//! Added to prevent a bug with the legacy CryEngine Viewport code that would
|
||||
//! keep doing raycast tests even when no level is loaded, causing a crash.
|
||||
class ViewportFreezeRequests
|
||||
{
|
||||
public:
|
||||
//! Return if Viewport Input is frozen
|
||||
virtual bool IsViewportInputFrozen() = 0;
|
||||
//! Sets the Viewport Input freeze state
|
||||
virtual void FreezeViewportInput(bool freeze) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportFreezeRequests() = default;
|
||||
};
|
||||
|
||||
//! Type to inherit to implement ViewportFreezeRequests.
|
||||
using ViewportFreezeRequestBus = AZ::EBus<ViewportFreezeRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Viewport requests that are only guaranteed to be serviced by the Main Editor viewport.
|
||||
class MainEditorViewportInteractionRequests
|
||||
{
|
||||
|
||||
+336
-285
File diff suppressed because it is too large
Load Diff
+6
@@ -207,6 +207,7 @@ namespace AzToolsFramework
|
||||
void SetSelectedEntities(const EntityIdList& entityIds);
|
||||
void DeselectEntities();
|
||||
bool SelectDeselect(AZ::EntityId entityId);
|
||||
void ChangeSelectedEntity(AZ::EntityId entityId);
|
||||
|
||||
void RefreshSelectedEntityIds();
|
||||
void RefreshSelectedEntityIds(const EntityIdList& selectedEntityIds);
|
||||
@@ -298,6 +299,11 @@ namespace AzToolsFramework
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Quaternion& localRotation);
|
||||
|
||||
bool PerformGroupDitto(AZ::EntityId entityId);
|
||||
bool PerformIndividualDitto(AZ::EntityId entityId);
|
||||
void PerformManipulatorDitto(AZ::EntityId entityId);
|
||||
void PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
|
||||
|
||||
//! Responsible for keeping the space cluster in sync with the current reference frame.
|
||||
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
|
||||
|
||||
|
||||
@@ -614,7 +614,7 @@ namespace UnitTest
|
||||
using EditorTransformComponentSelectionViewportPickingManipulatorTestFixture =
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorTransformComponentSelectionViewportPickingFixture>;
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, SingleClickWithNoSelectionWillSelectEntity)
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, StickySingleClickWithNoSelectionWillSelectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -637,19 +637,44 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, SingleClickOffEntityWithSelectionWillNotDeselectEntity)
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, UnstickySingleClickWithNoSelectionWillSelectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
using ::testing::Eq;
|
||||
auto selectedEntitiesBefore = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesBefore.empty());
|
||||
|
||||
// calculate the position in screen space of the initial entity position
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(m_entity1WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity1ScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity is selected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter.size(), Eq(1));
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickySingleClickOffEntityWithSelectionWillNotDeselectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
// position in space above the entity
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the initial position of the entity
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// click the empty space in the viewport
|
||||
@@ -662,9 +687,32 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, UnstickySingleClickOffEntityWithSelectionWillDeselectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// click the empty space in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(clickOffPositionScreen)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity was deselected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
SingleClickOnNewEntityWithSelectionWillNotChangeSelectedEntity)
|
||||
StickySingleClickOnNewEntityWithSelectionWillNotChangeSelectedEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -688,7 +736,31 @@ namespace UnitTest
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
CtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
UnstickySingleClickOnNewEntityWithSelectionWillChangeSelectedEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity2ScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed
|
||||
using ::testing::Eq;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter.size(), Eq(1));
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId2));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickyCtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -715,7 +787,34 @@ namespace UnitTest
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
CtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
UnstickyCtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(entity2ScreenPosition)
|
||||
->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control)
|
||||
->MouseLButtonDown()
|
||||
->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed (one entity selected to two)
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1, m_entityId2));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickyCtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -740,6 +839,33 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
UnstickyCtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2 });
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(entity2ScreenPosition)
|
||||
->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control)
|
||||
->MouseLButtonDown()
|
||||
->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed (entity2 was deselected)
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, BoxSelectWithNoInitialSelectionAddsEntitiesToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
@@ -835,6 +961,56 @@ namespace UnitTest
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, StickyDoubleClickWithSelectionWillDeselectEntities)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2, m_entityId3 });
|
||||
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesBefore = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesBefore, UnorderedElementsAre(m_entityId1, m_entityId2, m_entityId3));
|
||||
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// double click to deselect entities
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(clickOffPositionScreen)->MouseLButtonDoubleClick();
|
||||
|
||||
// no entities are selected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, UnstickyUndoOperationForChangeInSelectionIsAtomic)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// single click select entity2
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity2ScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// undo action
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequestBus::Events::UndoPressed);
|
||||
|
||||
// entity1 is selected after undo
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
|
||||
}
|
||||
|
||||
using EditorTransformComponentSelectionManipulatorTestFixture =
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorTransformComponentSelectionFixture>;
|
||||
|
||||
|
||||
@@ -232,13 +232,17 @@ namespace
|
||||
// our frame time to be managed by AzGameFramework::GameApplication
|
||||
// instead, which probably isn't going to happen anytime soon given
|
||||
// how many things depend on the ITimer interface).
|
||||
bool continueRunning = true;
|
||||
ISystem* system = gEnv ? gEnv->pSystem : nullptr;
|
||||
while (continueRunning)
|
||||
while (!gameApplication.WasExitMainLoopRequested())
|
||||
{
|
||||
// Pump the system event loop
|
||||
gameApplication.PumpSystemEventLoopUntilEmpty();
|
||||
|
||||
if (gameApplication.WasExitMainLoopRequested())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the AzFramework system tick bus
|
||||
gameApplication.TickSystem();
|
||||
|
||||
@@ -256,9 +260,6 @@ namespace
|
||||
{
|
||||
system->UpdatePostTickBus();
|
||||
}
|
||||
|
||||
// Check for quit requests
|
||||
continueRunning = !gameApplication.WasExitMainLoopRequested() && continueRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ class AZCoreLogSink
|
||||
: public AZ::Debug::TraceMessageBus::Handler
|
||||
{
|
||||
public:
|
||||
~AZCoreLogSink()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
inline static void Connect()
|
||||
{
|
||||
GetInstance().m_ignoredAsserts = new IgnoredAssertMap();
|
||||
|
||||
@@ -233,6 +233,7 @@ CLevelSystem::CLevelSystem(ISystem* pSystem, const char* levelsFolder)
|
||||
//------------------------------------------------------------------------
|
||||
CLevelSystem::~CLevelSystem()
|
||||
{
|
||||
UnloadLevel();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@@ -548,29 +548,6 @@ void CSystem::Quit()
|
||||
logger->Flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This call to _exit, _Exit, TerminateProcess etc. needs to
|
||||
* eventually be removed. This causes an extremely early exit before we
|
||||
* actually perform cleanup. When this gets called most managers are
|
||||
* simply never deleted and we leave it to the OS to clean up our mess
|
||||
* which is just really bad practice. However there are LOTS of issues
|
||||
* with shutdown at the moment. Removing this will simply cause
|
||||
* a crash when either the Editor or Launcher initiate shutdown. Both
|
||||
* applications crash differently too. Bugs will be logged about those
|
||||
* issues.
|
||||
*/
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_4
|
||||
#include AZ_RESTRICTED_FILE(System_cpp)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(WIN32) || defined(WIN64)
|
||||
TerminateProcess(GetCurrentProcess(), m_env.retCode);
|
||||
#else
|
||||
exit(m_env.retCode);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
//Post a WM_QUIT message to the Win32 api which causes the message loop to END
|
||||
//This is not the same as handling a WM_DESTROY event which destroys a window
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user