Merge branch 'development' into Atom/guthadam/atomtools_refactor_document_system
This commit is contained in:
@@ -8,7 +8,7 @@ INTRODUCTION
|
||||
------------
|
||||
|
||||
EditorPythonBindings is a Python project that contains a collection of editor testing tools
|
||||
developed by the Lumberyard feature teams. The project contains tools for system level
|
||||
developed by the O3DE feature teams. The project contains tools for system level
|
||||
editor tests.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ installed on your system.
|
||||
|
||||
INSTALL
|
||||
-----------
|
||||
It is recommended to set up these these tools with Lumberyard's CMake build commands.
|
||||
It is recommended to set up these these tools with O3DE's CMake build commands.
|
||||
Assuming CMake is already setup on your operating system, below are some sample build commands:
|
||||
cd /path/to/od3e/
|
||||
mkdir windows_vs2019
|
||||
|
||||
+2
-2
@@ -206,8 +206,8 @@ def run():
|
||||
# PostFX Layer Component
|
||||
ComponentTests("PostFX Layer")
|
||||
|
||||
# Radius Weight Modifier Component
|
||||
ComponentTests("Radius Weight Modifier")
|
||||
# PostFX Radius Weight Modifier Component
|
||||
ComponentTests("PostFX Radius Weight Modifier")
|
||||
|
||||
# Light Component
|
||||
ComponentTests("Light")
|
||||
|
||||
+5
-6
@@ -23,8 +23,7 @@ import azlmbr.legacy.general as general
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils import screenshot_utils
|
||||
from atom_renderer.atom_utils import atom_component_helper
|
||||
from atom_renderer.atom_utils import atom_component_helper, atom_constants, screenshot_utils
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
@@ -92,7 +91,7 @@ def area_light_test():
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_component_helper.LIGHT_TYPES['capsule']
|
||||
atom_constants.LIGHT_TYPES['capsule']
|
||||
)
|
||||
|
||||
# Update color and take screenshot in game mode
|
||||
@@ -118,7 +117,7 @@ def area_light_test():
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_component_helper.LIGHT_TYPES['spot_disk']
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation)
|
||||
@@ -131,7 +130,7 @@ def area_light_test():
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_component_helper.LIGHT_TYPES['sphere']
|
||||
atom_constants.LIGHT_TYPES['sphere']
|
||||
)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name)
|
||||
@@ -210,7 +209,7 @@ def spot_light_test():
|
||||
'SetComponentProperty',
|
||||
light_component_type,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_component_helper.LIGHT_TYPES['spot_disk']
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
|
||||
general.idle_wait(1.0)
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestAtomEditorComponentsMain(object):
|
||||
Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
|
||||
1. Display Mapper
|
||||
2. Light
|
||||
3. Radius Weight Modifier
|
||||
3. PostFX Radius Weight Modifier
|
||||
4. PostFX Layer
|
||||
5. Physical Sky
|
||||
6. Global Skylight (IBL)
|
||||
@@ -126,18 +126,18 @@ class TestAtomEditorComponentsMain(object):
|
||||
"PostFX Layer_test: Entity deleted: True",
|
||||
"PostFX Layer_test: UNDO entity deletion works: True",
|
||||
"PostFX Layer_test: REDO entity deletion works: True",
|
||||
# Radius Weight Modifier Component
|
||||
"Radius Weight Modifier Entity successfully created",
|
||||
"Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"Radius Weight Modifier_test: Entered game mode: True",
|
||||
"Radius Weight Modifier_test: Exit game mode: True",
|
||||
"Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"Radius Weight Modifier_test: Entity is shown: True",
|
||||
"Radius Weight Modifier_test: Entity deleted: True",
|
||||
"Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# PostFX Radius Weight Modifier Component
|
||||
"PostFX Radius Weight Modifier Entity successfully created",
|
||||
"PostFX Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"PostFX Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Entered game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Exit game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is shown: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity deleted: True",
|
||||
"PostFX Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"PostFX Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# Light Component
|
||||
"Light Entity successfully created",
|
||||
"Light_test: Component added to the entity: True",
|
||||
|
||||
@@ -61,7 +61,7 @@ class AssetPickerUIUXTest(EditorTestHelper):
|
||||
5) Verify if Mesh Asset is assigned via both OK/Enter options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ class TestBasicEditorWorkflows(EditorTestHelper):
|
||||
async def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
Open Lumberyard editor and check if basic Editor workflows are completable.
|
||||
Open O3DE editor and check if basic Editor workflows are completable.
|
||||
|
||||
Expected Behavior:
|
||||
- A new level can be created
|
||||
@@ -48,7 +48,7 @@ class TestBasicEditorWorkflows(EditorTestHelper):
|
||||
- Level can be exported
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestEditMenuOptions(EditorTestHelper):
|
||||
2) Interact with Edit Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestFileMenuOptions(EditorTestHelper):
|
||||
2) Interact with File Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestViewMenuOptions(EditorTestHelper):
|
||||
2) Interact with View Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ def Pane_PropertiesChanged_RetainsOnRestart():
|
||||
from utils import TestHelper as helper
|
||||
import pyside_utils
|
||||
|
||||
# Lumberyard Imports
|
||||
# O3DE Imports
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
# Pyside imports
|
||||
|
||||
@@ -73,5 +73,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LoadLevelCPU
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_RemoteConsole_CPULoadLevel_Works.py
|
||||
TIMEOUT 100
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -53,7 +53,7 @@ def Editor_NewExistingLevels_Works():
|
||||
10) Save, Load and Export an existing level and close editor
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ from ly_remote_console.remote_console_commands import (
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows"])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("level", ["Simple"])
|
||||
@pytest.mark.SUITE_smoke
|
||||
@pytest.mark.SUITE_sandbox
|
||||
class TestRemoteConsoleLoadLevelWorks(object):
|
||||
@pytest.fixture
|
||||
def remote_console_instance(self, request):
|
||||
|
||||
+1
-31
@@ -1,17 +1,5 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "iPhoneNotificationIcon40x40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "iPhoneNotificationIcon60x60.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
@@ -48,18 +36,6 @@
|
||||
"filename" : "iPhoneAppIcon180x180.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadNotificationIcon20x20.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadNotificationIcon40x40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
@@ -101,16 +77,10 @@
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadProAppIcon167x167.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "iOSAppStoreIcon1024x1024.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-31
@@ -1,17 +1,5 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "iPhoneNotificationIcon40x40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "iPhoneNotificationIcon60x60.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
@@ -48,18 +36,6 @@
|
||||
"filename" : "iPhoneAppIcon180x180.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadNotificationIcon20x20.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadNotificationIcon40x40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
@@ -101,16 +77,10 @@
|
||||
"idiom" : "ipad",
|
||||
"filename" : "iPadProAppIcon167x167.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "iOSAppStoreIcon1024x1024.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-46
@@ -1,50 +1,5 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"extent" : "full-screen",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "2436h",
|
||||
"filename" : "iPhoneLaunchImage1125x2436.png",
|
||||
"minimum-system-version" : "11.0",
|
||||
"orientation" : "portrait",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"extent" : "full-screen",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "2436h",
|
||||
"filename" : "iPhoneLaunchImage2436x1125.png",
|
||||
"minimum-system-version" : "11.0",
|
||||
"orientation" : "landscape",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"extent" : "full-screen",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "736h",
|
||||
"filename" : "iPhoneLaunchImage1242x2208.png",
|
||||
"minimum-system-version" : "8.0",
|
||||
"orientation" : "portrait",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"extent" : "full-screen",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "736h",
|
||||
"filename" : "iPhoneLaunchImage2208x1242.png",
|
||||
"minimum-system-version" : "8.0",
|
||||
"orientation" : "landscape",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"extent" : "full-screen",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "667h",
|
||||
"filename" : "iPhoneLaunchImage750x1334.png",
|
||||
"minimum-system-version" : "8.0",
|
||||
"orientation" : "portrait",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
@@ -166,4 +121,4 @@
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// Editor
|
||||
#include "PropertyCtrl.h"
|
||||
#include "PropertyAnimationCtrl.h"
|
||||
#include "PropertyResourceCtrl.h"
|
||||
#include "PropertyGenericCtrl.h"
|
||||
#include "PropertyMiscCtrl.h"
|
||||
@@ -22,9 +21,7 @@ void RegisterReflectedVarHandlers()
|
||||
if (!registered)
|
||||
{
|
||||
registered = true;
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew AnimationPropertyWidgetHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew FileResourceSelectorWidgetHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew ReverbPresetPropertyHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequencePropertyHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequenceIdPropertyHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew LocalStringPropertyHandler());
|
||||
|
||||
@@ -73,16 +73,6 @@ void GenericPopupPropertyEditor::SetPropertyType(PropertyType type)
|
||||
m_propertyType = type;
|
||||
}
|
||||
|
||||
void ReverbPresetPropertyEditor::onEditClicked()
|
||||
{
|
||||
CSelectEAXPresetDlg PresetDlg(this);
|
||||
PresetDlg.SetCurrPreset(GetValue());
|
||||
if (PresetDlg.exec() == QDialog::Accepted)
|
||||
{
|
||||
SetValue(PresetDlg.GetCurrPreset());
|
||||
}
|
||||
}
|
||||
|
||||
void SequencePropertyEditor::onEditClicked()
|
||||
{
|
||||
CSelectSequenceDialog gtDlg(this);
|
||||
|
||||
@@ -96,15 +96,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ReverbPresetPropertyEditor
|
||||
: public GenericPopupPropertyEditor
|
||||
{
|
||||
public:
|
||||
ReverbPresetPropertyEditor(QWidget* pParent = nullptr)
|
||||
: GenericPopupPropertyEditor(pParent){}
|
||||
void onEditClicked() override;
|
||||
};
|
||||
|
||||
class MissionObjPropertyEditor
|
||||
: public GenericPopupPropertyEditor
|
||||
{
|
||||
@@ -155,7 +146,6 @@ public:
|
||||
// So we use our own
|
||||
#define CONST_AZ_CRC(name, value) AZ::u32(value)
|
||||
|
||||
using ReverbPresetPropertyHandler = GenericPopupWidgetHandler<ReverbPresetPropertyEditor, CONST_AZ_CRC("ePropertyReverbPreset", 0x51469f38)>;
|
||||
using MissionObjPropertyHandler = GenericPopupWidgetHandler<MissionObjPropertyEditor, CONST_AZ_CRC("ePropertyMissionObj", 0x4a2d0dc8)>;
|
||||
using SequencePropertyHandler = GenericPopupWidgetHandler<SequencePropertyEditor, CONST_AZ_CRC("ePropertySequence", 0xdd1c7d44)>;
|
||||
using SequenceIdPropertyHandler = GenericPopupWidgetHandler<SequenceIdPropertyEditor, CONST_AZ_CRC("ePropertySequenceId", 0x05983dcc)>;
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyAudioCtrl.h>
|
||||
|
||||
// Editor
|
||||
#include "IResourceSelectorHost.h"
|
||||
#include "Controls/QToolTipWidget.h"
|
||||
#include "Controls/BitmapToolTip.h"
|
||||
|
||||
@@ -35,8 +35,8 @@ BrowseButton::BrowseButton(PropertyType type, QWidget* parent /*= nullptr*/)
|
||||
|
||||
void BrowseButton::SetPathAndEmit(const QString& path)
|
||||
{
|
||||
//only emit if path changes, except for ePropertyGeomCache. Old property control
|
||||
if (path != m_path || m_propertyType == ePropertyGeomCache)
|
||||
//only emit if path changes. Old property control
|
||||
if (path != m_path)
|
||||
{
|
||||
m_path = path;
|
||||
emit PathChanged(m_path);
|
||||
@@ -78,21 +78,6 @@ private:
|
||||
// Filters for texture.
|
||||
selection = AssetSelectionModel::AssetGroupSelection("Texture");
|
||||
}
|
||||
else if (m_propertyType == ePropertyModel)
|
||||
{
|
||||
// Filters for models.
|
||||
selection = AssetSelectionModel::AssetGroupSelection("Geometry");
|
||||
}
|
||||
else if (m_propertyType == ePropertyGeomCache)
|
||||
{
|
||||
// Filters for geom caches.
|
||||
selection = AssetSelectionModel::AssetTypeSelection("Geom Cache");
|
||||
}
|
||||
else if (m_propertyType == ePropertyFile)
|
||||
{
|
||||
// Filters for files.
|
||||
selection = AssetSelectionModel::AssetTypeSelection("File");
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
@@ -106,14 +91,7 @@ private:
|
||||
switch (m_propertyType)
|
||||
{
|
||||
case ePropertyTexture:
|
||||
case ePropertyModel:
|
||||
newPath.replace("\\\\", "/");
|
||||
}
|
||||
switch (m_propertyType)
|
||||
{
|
||||
case ePropertyTexture:
|
||||
case ePropertyModel:
|
||||
case ePropertyFile:
|
||||
if (newPath.size() > MAX_PATH)
|
||||
{
|
||||
newPath.resize(MAX_PATH);
|
||||
@@ -125,26 +103,51 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class ResourceSelectorButton
|
||||
class AudioControlSelectorButton
|
||||
: public BrowseButton
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ResourceSelectorButton, AZ::SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR(AudioControlSelectorButton, AZ::SystemAllocator, 0);
|
||||
|
||||
ResourceSelectorButton(PropertyType type, QWidget* pParent = nullptr)
|
||||
AudioControlSelectorButton(PropertyType type, QWidget* pParent = nullptr)
|
||||
: BrowseButton(type, pParent)
|
||||
{
|
||||
setToolTip(tr("Select resource"));
|
||||
setToolTip(tr("Select Audio Control"));
|
||||
}
|
||||
|
||||
private:
|
||||
void OnClicked() override
|
||||
{
|
||||
SResourceSelectorContext x;
|
||||
x.parentWidget = this;
|
||||
x.typeName = Prop::GetPropertyTypeToResourceType(m_propertyType);
|
||||
QString newPath = GetIEditor()->GetResourceSelectorHost()->SelectResource(x, m_path);
|
||||
SetPathAndEmit(newPath);
|
||||
AZStd::string resourceResult;
|
||||
auto ConvertLegacyAudioPropertyType = [](const PropertyType type) -> AzToolsFramework::AudioPropertyType
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ePropertyAudioTrigger:
|
||||
return AzToolsFramework::AudioPropertyType::Trigger;
|
||||
case ePropertyAudioRTPC:
|
||||
return AzToolsFramework::AudioPropertyType::Rtpc;
|
||||
case ePropertyAudioSwitch:
|
||||
return AzToolsFramework::AudioPropertyType::Switch;
|
||||
case ePropertyAudioSwitchState:
|
||||
return AzToolsFramework::AudioPropertyType::SwitchState;
|
||||
case ePropertyAudioEnvironment:
|
||||
return AzToolsFramework::AudioPropertyType::Environment;
|
||||
case ePropertyAudioPreloadRequest:
|
||||
return AzToolsFramework::AudioPropertyType::Preload;
|
||||
default:
|
||||
return AzToolsFramework::AudioPropertyType::NumTypes;
|
||||
}
|
||||
};
|
||||
|
||||
auto propType = ConvertLegacyAudioPropertyType(m_propertyType);
|
||||
if (propType != AzToolsFramework::AudioPropertyType::NumTypes)
|
||||
{
|
||||
AzToolsFramework::AudioControlSelectorRequestBus::EventResult(
|
||||
resourceResult, propType, &AzToolsFramework::AudioControlSelectorRequestBus::Events::SelectResource,
|
||||
AZStd::string_view{ m_path.toUtf8().constData() });
|
||||
SetPathAndEmit(QString{ resourceResult.c_str() });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -235,18 +238,13 @@ void FileResourceSelectorWidget::SetPropertyType(PropertyType type)
|
||||
AddButton(new TextureEditButton);
|
||||
m_previewToolTip.reset(new CBitmapToolTip);
|
||||
break;
|
||||
case ePropertyModel:
|
||||
case ePropertyGeomCache:
|
||||
case ePropertyAudioTrigger:
|
||||
case ePropertyAudioSwitch:
|
||||
case ePropertyAudioSwitchState:
|
||||
case ePropertyAudioRTPC:
|
||||
case ePropertyAudioEnvironment:
|
||||
case ePropertyAudioPreloadRequest:
|
||||
AddButton(new ResourceSelectorButton(type));
|
||||
break;
|
||||
case ePropertyFile:
|
||||
AddButton(new FileBrowseButton(type));
|
||||
AddButton(new AudioControlSelectorButton(type));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -1,93 +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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : implementation file
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "ReflectedPropertiesPanel.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ReflectedPropertiesPanel dialog
|
||||
|
||||
|
||||
ReflectedPropertiesPanel::ReflectedPropertiesPanel(QWidget* pParent)
|
||||
: ReflectedPropertyControl(pParent)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void ReflectedPropertiesPanel::DeleteVars()
|
||||
{
|
||||
ClearVarBlock();
|
||||
m_updateCallbacks.clear();
|
||||
m_varBlock = nullptr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void ReflectedPropertiesPanel::SetVarBlock(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* updCallback, const char* category)
|
||||
{
|
||||
assert(vb);
|
||||
|
||||
m_varBlock = vb;
|
||||
|
||||
RemoveAllItems();
|
||||
m_varBlock = vb;
|
||||
AddVarBlock(m_varBlock, category);
|
||||
|
||||
SetUpdateCallback(AZStd::bind(&ReflectedPropertiesPanel::OnPropertyChanged, this, AZStd::placeholders::_1));
|
||||
|
||||
// When new object set all previous callbacks freed.
|
||||
m_updateCallbacks.clear();
|
||||
if (updCallback)
|
||||
{
|
||||
stl::push_back_unique(m_updateCallbacks, updCallback);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void ReflectedPropertiesPanel::AddVars(CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* updCallback, const char* category)
|
||||
{
|
||||
assert(vb);
|
||||
|
||||
bool bNewBlock = false;
|
||||
// Make a clone of properties.
|
||||
if (!m_varBlock)
|
||||
{
|
||||
RemoveAllItems();
|
||||
m_varBlock = vb->Clone(true);
|
||||
AddVarBlock(m_varBlock, category);
|
||||
bNewBlock = true;
|
||||
}
|
||||
m_varBlock->Wire(vb);
|
||||
|
||||
if (bNewBlock)
|
||||
{
|
||||
SetUpdateCallback(AZStd::bind(&ReflectedPropertiesPanel::OnPropertyChanged, this, AZStd::placeholders::_1));
|
||||
|
||||
// When new object set all previous callbacks freed.
|
||||
m_updateCallbacks.clear();
|
||||
}
|
||||
|
||||
if (updCallback)
|
||||
{
|
||||
stl::push_back_unique(m_updateCallbacks, updCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void ReflectedPropertiesPanel::OnPropertyChanged(IVariable* pVar)
|
||||
{
|
||||
std::list<ReflectedPropertyControl::UpdateVarCallback*>::iterator iter;
|
||||
for (iter = m_updateCallbacks.begin(); iter != m_updateCallbacks.end(); ++iter)
|
||||
{
|
||||
(*iter)->operator()(pVar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
||||
#define CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.h"
|
||||
#include "Util/Variable.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ReflectedPropertiesPanel dialog
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
//This class is a port of ReflectedPropertiesPanel to use the ReflectedPropertyControl
|
||||
class SANDBOX_API ReflectedPropertiesPanel
|
||||
: public ReflectedPropertyControl
|
||||
{
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
public:
|
||||
ReflectedPropertiesPanel(QWidget* pParent = nullptr); // standard constructor
|
||||
|
||||
void DeleteVars();
|
||||
void AddVars(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* func = nullptr, const char* category = nullptr);
|
||||
|
||||
void SetVarBlock(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* func = nullptr, const char* category = nullptr);
|
||||
|
||||
protected:
|
||||
void OnPropertyChanged(IVariable* pVar);
|
||||
|
||||
protected:
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
TSmartPtr<CVarBlock> m_varBlock;
|
||||
|
||||
std::list<ReflectedPropertyControl::UpdateVarCallback*> m_updateCallbacks;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
||||
@@ -255,9 +255,6 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
|
||||
case ePropertySelection:
|
||||
m_reflectedVarAdapter = new ReflectedVarEnumAdapter;
|
||||
break;
|
||||
case ePropertyAnimation:
|
||||
m_reflectedVarAdapter = new ReflectedVarAnimationAdapter;
|
||||
break;
|
||||
case ePropertyColor:
|
||||
m_reflectedVarAdapter = new ReflectedVarColorAdapter;
|
||||
break;
|
||||
@@ -265,7 +262,6 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
|
||||
m_reflectedVarAdapter = new ReflectedVarUserAdapter;
|
||||
break;
|
||||
case ePropertyEquip:
|
||||
case ePropertyReverbPreset:
|
||||
case ePropertyGameToken:
|
||||
case ePropertyMissionObj:
|
||||
case ePropertySequence:
|
||||
@@ -276,15 +272,12 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
|
||||
m_reflectedVarAdapter = new ReflectedVarGenericPropertyAdapter(desc.m_type);
|
||||
break;
|
||||
case ePropertyTexture:
|
||||
case ePropertyModel:
|
||||
case ePropertyGeomCache:
|
||||
case ePropertyAudioTrigger:
|
||||
case ePropertyAudioSwitch:
|
||||
case ePropertyAudioSwitchState:
|
||||
case ePropertyAudioRTPC:
|
||||
case ePropertyAudioEnvironment:
|
||||
case ePropertyAudioPreloadRequest:
|
||||
case ePropertyFile:
|
||||
m_reflectedVarAdapter = new ReflectedVarResourceAdapter;
|
||||
break;
|
||||
case ePropertyFloatCurve:
|
||||
@@ -569,7 +562,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
|
||||
break;
|
||||
|
||||
case ePropertyTexture:
|
||||
case ePropertyModel:
|
||||
value.replace('\\', '/');
|
||||
break;
|
||||
}
|
||||
@@ -578,8 +570,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
|
||||
switch (m_type)
|
||||
{
|
||||
case ePropertyTexture:
|
||||
case ePropertyModel:
|
||||
case ePropertyFile:
|
||||
if (value.length() >= MAX_PATH)
|
||||
{
|
||||
value = value.left(MAX_PATH);
|
||||
|
||||
@@ -31,12 +31,6 @@ void ReflectedVarInit::setupReflection(AZ::SerializeContext* serializeContext)
|
||||
->Field("description", &CReflectedVar::m_description)
|
||||
->Field("varName", &CReflectedVar::m_varName);
|
||||
|
||||
serializeContext->Class <CReflectedVarAnimation, CReflectedVar >()
|
||||
->Version(1)
|
||||
->Field("animation", &CReflectedVarAnimation::m_animation)
|
||||
->Field("entityID", &CReflectedVarAnimation::m_entityID)
|
||||
;
|
||||
|
||||
serializeContext->Class <CReflectedVarResource, CReflectedVar >()
|
||||
->Version(1)
|
||||
->Field("path", &CReflectedVarResource::m_path)
|
||||
@@ -76,12 +70,6 @@ void ReflectedVarInit::setupReflection(AZ::SerializeContext* serializeContext)
|
||||
AZ::EditContext* ec = serializeContext->GetEditContext();
|
||||
if (ec)
|
||||
{
|
||||
ec->Class< CReflectedVarAnimation >("VarAnimation", "Animation")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CReflectedVarAnimation::varName)
|
||||
->Attribute(AZ::Edit::Attributes::DescriptionTextOverride, &CReflectedVarAnimation::description)
|
||||
;
|
||||
|
||||
ec->Class< CReflectedVarResource >("VarResource", "Resource")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CReflectedVarResource::varName)
|
||||
@@ -284,8 +272,6 @@ AZ::u32 CReflectedVarGenericProperty::handler()
|
||||
return AZ_CRC("ePropertyShader", 0xc40932f1);
|
||||
case ePropertyEquip:
|
||||
return AZ_CRC("ePropertyEquip", 0x66ffd290);
|
||||
case ePropertyReverbPreset:
|
||||
return AZ_CRC("ePropertyReverbPreset", 0x51469f38);
|
||||
case ePropertyDeprecated0:
|
||||
return AZ_CRC("ePropertyCustomAction", 0x4ffa5ba5);
|
||||
case ePropertyGameToken:
|
||||
|
||||
@@ -265,32 +265,8 @@ public:
|
||||
AZ::Vector3 m_color;
|
||||
};
|
||||
|
||||
//Class to hold ePropertyAnimation (IVariable::DT_ANIMATION )
|
||||
class CReflectedVarAnimation
|
||||
: public CReflectedVar
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(CReflectedVarAnimation, "{635D982E-23EC-463F-8F33-4FC2C19D5673}", CReflectedVar)
|
||||
|
||||
CReflectedVarAnimation(const AZStd::string& name)
|
||||
: CReflectedVar(name)
|
||||
, m_entityID(0)
|
||||
{}
|
||||
CReflectedVarAnimation()
|
||||
: m_entityID(0){}
|
||||
|
||||
AZStd::string varName() const { return m_varName; }
|
||||
AZStd::string description() const { return m_description; }
|
||||
|
||||
AZStd::string m_animation;
|
||||
AZ::EntityId m_entityID;
|
||||
};
|
||||
|
||||
//Class to hold:
|
||||
// ePropertyTexture (IVariable::DT_TEXTURE)
|
||||
// ePropertyMaterial (IVariable::DT_MATERIAL)
|
||||
// ePropertyModel (IVariable::DT_OBJECT)
|
||||
// ePropertyGeomCache (IVariable::DT_GEOM_CACHE)
|
||||
// ePropertyAudioTrigger (IVariable::DT_AUDIO_TRIGGER)
|
||||
// ePropertyAudioSwitch (IVariable::DT_AUDIO_SWITCH )
|
||||
// ePropertyAudioSwitchState (IVariable::DT_AUDIO_SWITCH_STATE)
|
||||
@@ -344,7 +320,6 @@ public:
|
||||
AZStd::vector<AZStd::string> m_itemDescriptions;
|
||||
};
|
||||
|
||||
//Class to hold ePropertyAnimation (IVariable::DT_ANIMATION )
|
||||
class CReflectedVarSpline
|
||||
: public CReflectedVar
|
||||
{
|
||||
|
||||
@@ -392,25 +392,6 @@ void ReflectedVarColorAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
|
||||
|
||||
|
||||
void ReflectedVarAnimationAdapter::SetVariable(IVariable *pVariable)
|
||||
{
|
||||
m_reflectedVar.reset(new CReflectedVarAnimation(pVariable->GetHumanName().toUtf8().data()));
|
||||
m_reflectedVar->m_description = pVariable->GetDescription().toUtf8().data();
|
||||
}
|
||||
|
||||
void ReflectedVarAnimationAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
|
||||
{
|
||||
m_reflectedVar->m_entityID = static_cast<AZ::EntityId>(pVariable->GetUserData().value<AZ::u64>());
|
||||
m_reflectedVar->m_animation = pVariable->GetDisplayValue().toUtf8().data();
|
||||
}
|
||||
|
||||
void ReflectedVarAnimationAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
{
|
||||
pVariable->SetUserData(static_cast<AZ::u64>(m_reflectedVar->m_entityID));
|
||||
pVariable->SetDisplayValue(m_reflectedVar->m_animation.c_str());
|
||||
|
||||
}
|
||||
|
||||
void ReflectedVarResourceAdapter::SetVariable(IVariable *pVariable)
|
||||
{
|
||||
m_reflectedVar.reset(new CReflectedVarResource(pVariable->GetHumanName().toUtf8().data()));
|
||||
@@ -429,7 +410,7 @@ void ReflectedVarResourceAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
|
||||
|
||||
void ReflectedVarResourceAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
{
|
||||
const bool bForceModified = (m_reflectedVar->m_propertyType == ePropertyGeomCache);
|
||||
const bool bForceModified = false;
|
||||
pVariable->SetForceModified(bForceModified);
|
||||
pVariable->SetDisplayValue(m_reflectedVar->m_path.c_str());
|
||||
|
||||
|
||||
@@ -218,20 +218,6 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
class EDITOR_CORE_API ReflectedVarAnimationAdapter
|
||||
: public ReflectedVarAdapter
|
||||
{
|
||||
public:
|
||||
void SetVariable(IVariable* pVariable) override;
|
||||
void SyncReflectedVarToIVar(IVariable* pVariable) override;
|
||||
void SyncIVarToReflectedVar(IVariable* pVariable) override;
|
||||
CReflectedVar* GetReflectedVar() override { return m_reflectedVar.data(); }
|
||||
private:
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QScopedPointer<CReflectedVarAnimation > m_reflectedVar;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
class EDITOR_CORE_API ReflectedVarResourceAdapter
|
||||
: public ReflectedVarAdapter
|
||||
{
|
||||
|
||||
+8
-11
@@ -891,8 +891,7 @@ CCrySingleDocTemplate::Confidence CCrySingleDocTemplate::MatchDocType(const char
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
CryMutex g_splashScreenStateLock;
|
||||
CryConditionVariable g_splashScreenStateChange;
|
||||
AZStd::mutex g_splashScreenStateLock;
|
||||
enum ESplashScreenState
|
||||
{
|
||||
eSplashScreenState_Init, eSplashScreenState_Started, eSplashScreenState_Destroy
|
||||
@@ -923,7 +922,7 @@ QString FormatRichTextCopyrightNotice()
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::ShowSplashScreen(CCryEditApp* app)
|
||||
{
|
||||
g_splashScreenStateLock.Lock();
|
||||
g_splashScreenStateLock.lock();
|
||||
|
||||
CStartupLogoDialog* splashScreen = new CStartupLogoDialog(FormatVersion(app->m_pEditor->GetFileVersion()), FormatRichTextCopyrightNotice());
|
||||
|
||||
@@ -931,8 +930,7 @@ void CCryEditApp::ShowSplashScreen(CCryEditApp* app)
|
||||
g_splashScreen = splashScreen;
|
||||
g_splashScreenState = eSplashScreenState_Started;
|
||||
|
||||
g_splashScreenStateLock.Unlock();
|
||||
g_splashScreenStateChange.Notify();
|
||||
g_splashScreenStateLock.unlock();
|
||||
|
||||
splashScreen->show();
|
||||
// Make sure the initial paint of the splash screen occurs so we dont get stuck with a blank window
|
||||
@@ -940,10 +938,9 @@ void CCryEditApp::ShowSplashScreen(CCryEditApp* app)
|
||||
|
||||
QObject::connect(splashScreen, &QObject::destroyed, splashScreen, [=]
|
||||
{
|
||||
g_splashScreenStateLock.Lock();
|
||||
AZStd::scoped_lock lock(g_splashScreenStateLock);
|
||||
g_pInitializeUIInfo = nullptr;
|
||||
g_splashScreen = nullptr;
|
||||
g_splashScreenStateLock.Unlock();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -973,9 +970,9 @@ void CCryEditApp::CloseSplashScreen()
|
||||
if (CStartupLogoDialog::instance())
|
||||
{
|
||||
delete CStartupLogoDialog::instance();
|
||||
g_splashScreenStateLock.Lock();
|
||||
g_splashScreenStateLock.lock();
|
||||
g_splashScreenState = eSplashScreenState_Destroy;
|
||||
g_splashScreenStateLock.Unlock();
|
||||
g_splashScreenStateLock.unlock();
|
||||
}
|
||||
|
||||
GetIEditor()->Notify(eNotify_OnSplashScreenDestroyed);
|
||||
@@ -984,12 +981,12 @@ void CCryEditApp::CloseSplashScreen()
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OutputStartupMessage(QString str)
|
||||
{
|
||||
g_splashScreenStateLock.Lock();
|
||||
g_splashScreenStateLock.lock();
|
||||
if (g_pInitializeUIInfo)
|
||||
{
|
||||
g_pInitializeUIInfo->SetInfoText(str.toUtf8().data());
|
||||
}
|
||||
g_splashScreenStateLock.Unlock();
|
||||
g_splashScreenStateLock.unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
HotKey_BuildDefaults();
|
||||
for (QPair<QString, QString> key : keys)
|
||||
{
|
||||
for (unsigned int j = 0; j < hotkeys.count(); j++)
|
||||
for (int j = 0; j < hotkeys.count(); j++)
|
||||
{
|
||||
if (hotkeys[j].path.compare(key.first, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
@@ -256,7 +256,7 @@ public:
|
||||
hotkey.second = settings.value("keySequence").toString();
|
||||
if (!hotkey.first.isEmpty())
|
||||
{
|
||||
for (unsigned int j = 0; j < hotkeys.count(); j++)
|
||||
for (int j = 0; j < hotkeys.count(); j++)
|
||||
{
|
||||
if (hotkeys[j].path.compare(hotkey.first, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "LogFile.h"
|
||||
#include "CryListenerSet.h"
|
||||
#include "Util/ModalWindowDismisser.h"
|
||||
#include <CryCommon/CryThread.h>
|
||||
#endif
|
||||
|
||||
class CStartupLogoDialog;
|
||||
@@ -117,11 +116,11 @@ public:
|
||||
|
||||
//! mutex used by other threads to lock up the PAK modification,
|
||||
//! so only one thread can modify the PAK at once
|
||||
static CryMutex& GetPakModifyMutex()
|
||||
static AZStd::recursive_mutex& GetPakModifyMutex()
|
||||
{
|
||||
//! mutex used to halt copy process while the export to game
|
||||
//! or other pak operation is done in the main thread
|
||||
static CryMutex s_pakModifyMutex;
|
||||
static AZStd::recursive_mutex s_pakModifyMutex;
|
||||
return s_pakModifyMutex;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
|
||||
m_settings.SetHiQuality();
|
||||
}
|
||||
|
||||
CryAutoLock<CryMutex> autoLock(CGameEngine::GetPakModifyMutex());
|
||||
AZStd::scoped_lock autoLock(CGameEngine::GetPakModifyMutex());
|
||||
|
||||
// Close this pak file.
|
||||
if (!CloseLevelPack(m_levelPak, true))
|
||||
|
||||
@@ -68,7 +68,6 @@ class CDisplaySettings;
|
||||
struct SGizmoParameters;
|
||||
class CLevelIndependentFileMan;
|
||||
class CSelectionTreeManager;
|
||||
struct IResourceSelectorHost;
|
||||
struct SEditorSettings;
|
||||
class CGameExporter;
|
||||
class IAWSResourceManager;
|
||||
@@ -714,7 +713,6 @@ struct IEditor
|
||||
virtual ESystemConfigSpec GetEditorConfigSpec() const = 0;
|
||||
virtual ESystemConfigPlatform GetEditorConfigPlatform() const = 0;
|
||||
virtual void ReloadTemplates() = 0;
|
||||
virtual IResourceSelectorHost* GetResourceSelectorHost() = 0;
|
||||
virtual void ShowStatusText(bool bEnable) = 0;
|
||||
|
||||
// Provides a way to extend the context menu of an object. The function gets called every time the menu is opened.
|
||||
|
||||
@@ -67,7 +67,6 @@ AZ_POP_DISABLE_WARNING
|
||||
#include "EditorFileMonitor.h"
|
||||
#include "MainStatusBar.h"
|
||||
|
||||
#include "ResourceSelectorHost.h"
|
||||
#include "Util/FileUtil_impl.h"
|
||||
#include "Util/ImageUtil_impl.h"
|
||||
#include "LogFileImpl.h"
|
||||
@@ -187,7 +186,6 @@ CEditorImpl::CEditorImpl()
|
||||
m_pAnimationContext = new CAnimationContext;
|
||||
|
||||
m_pImageUtil = new CImageUtil_impl();
|
||||
m_pResourceSelectorHost.reset(CreateResourceSelectorHost());
|
||||
m_selectedRegion.min = Vec3(0, 0, 0);
|
||||
m_selectedRegion.max = Vec3(0, 0, 0);
|
||||
DetectVersion();
|
||||
@@ -252,7 +250,7 @@ void CEditorImpl::Uninitialize()
|
||||
|
||||
void CEditorImpl::UnloadPlugins()
|
||||
{
|
||||
CryAutoLock<CryMutex> lock(m_pluginMutex);
|
||||
AZStd::scoped_lock lock(m_pluginMutex);
|
||||
|
||||
// Flush core buses. We're about to unload DLLs and need to ensure we don't have module-owned functions left behind.
|
||||
AZ::Data::AssetBus::ExecuteQueuedEvents();
|
||||
@@ -273,7 +271,7 @@ void CEditorImpl::UnloadPlugins()
|
||||
|
||||
void CEditorImpl::LoadPlugins()
|
||||
{
|
||||
CryAutoLock<CryMutex> lock(m_pluginMutex);
|
||||
AZStd::scoped_lock lock(m_pluginMutex);
|
||||
|
||||
static const QString editor_plugins_folder("EditorPlugins");
|
||||
|
||||
@@ -1460,7 +1458,7 @@ void CEditorImpl::UnregisterNotifyListener(IEditorNotifyListener* listener)
|
||||
|
||||
ISourceControl* CEditorImpl::GetSourceControl()
|
||||
{
|
||||
CryAutoLock<CryMutex> lock(m_pluginMutex);
|
||||
AZStd::scoped_lock lock(m_pluginMutex);
|
||||
|
||||
if (m_pSourceControl)
|
||||
{
|
||||
|
||||
@@ -290,7 +290,6 @@ public:
|
||||
ESystemConfigPlatform GetEditorConfigPlatform() const;
|
||||
void ReloadTemplates();
|
||||
void AddErrorMessage(const QString& text, const QString& caption);
|
||||
IResourceSelectorHost* GetResourceSelectorHost() { return m_pResourceSelectorHost.get(); }
|
||||
virtual void ShowStatusText(bool bEnable);
|
||||
|
||||
void OnObjectContextMenuOpened(QMenu* pMenu, const CBaseObject* pObject);
|
||||
@@ -374,7 +373,6 @@ protected:
|
||||
//! Export manager for exporting objects and a terrain from the game to DCC tools
|
||||
CExportManager* m_pExportManager;
|
||||
std::unique_ptr<CEditorFileMonitor> m_pEditorFileMonitor;
|
||||
std::unique_ptr<IResourceSelectorHost> m_pResourceSelectorHost;
|
||||
QString m_selectFileBuffer;
|
||||
QString m_levelNameBuffer;
|
||||
|
||||
@@ -401,7 +399,7 @@ protected:
|
||||
IImageUtil* m_pImageUtil; // Vladimir@conffx
|
||||
ILogFile* m_pLogFile; // Vladimir@conffx
|
||||
|
||||
CryMutex m_pluginMutex; // protect any pointers that come from plugins, such as the source control cached pointer.
|
||||
AZStd::mutex m_pluginMutex; // protect any pointers that come from plugins, such as the source control cached pointer.
|
||||
static const char* m_crashLogFileName;
|
||||
};
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ struct HotKey
|
||||
int size = (m_catSize < o_catSize) ? m_catSize : o_catSize;
|
||||
|
||||
//sort categories to keep them together
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (m_categories[i] < o_categories[i])
|
||||
{
|
||||
|
||||
@@ -1,135 +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
|
||||
// The aim of IResourceSelectorHost is to unify resource selection dialogs in a one
|
||||
// API that can be reused with plugins. It also makes possible to register new
|
||||
// resource selectors dynamically, e.g. inside plugins.
|
||||
//
|
||||
// Here is how new selectors are created. In your implementation file you add handler function:
|
||||
//
|
||||
// #include "IResourceSelectorHost.h"
|
||||
//
|
||||
// QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue)
|
||||
// {
|
||||
// CMyModalDialog dialog(CWnd::FromHandle(x.parentWindow));
|
||||
// ...
|
||||
// return previousValue;
|
||||
// }
|
||||
// REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "Icons/sound_16x16.png")
|
||||
//
|
||||
// Here is how it can be invoked directly:
|
||||
//
|
||||
// SResourceSelectorContext x;
|
||||
// x.parentWindow = parent.GetSafeHwnd();
|
||||
// x.typeName = "Sound";
|
||||
// string newValue = GetIEditor()->GetResourceSelector()->SelectResource(x, previousValue).c_str();
|
||||
//
|
||||
// If you have your own resource selectors in the plugin you will need to run
|
||||
//
|
||||
// RegisterModuleResourceSelectors(GetIEditor()->GetResourceSelector())
|
||||
//
|
||||
// during plugin initialization.
|
||||
//
|
||||
// If you want to be able to pass some custom context to the selector (e.g. source of the information for the
|
||||
// list of items or something similar) then you can add a poitner argument to your selector function, i.e.:
|
||||
//
|
||||
// QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue,
|
||||
// SoundFileList* list) // your context argument
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QWidget;
|
||||
|
||||
struct SResourceSelectorContext
|
||||
{
|
||||
const char* typeName;
|
||||
|
||||
// use either parentWidget or parentWindow (not both) until everything porting to QWidget.
|
||||
QWidget* parentWidget;
|
||||
|
||||
unsigned int entityId;
|
||||
void* contextObject;
|
||||
|
||||
SResourceSelectorContext()
|
||||
: parentWidget(0)
|
||||
, typeName(0)
|
||||
, entityId(0)
|
||||
, contextObject()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// TResourceSelecitonFunction is used to declare handlers for specific types.
|
||||
//
|
||||
// For canceled dialogs previousValue should be returned.
|
||||
typedef QString (* TResourceSelectionFunction)(const SResourceSelectorContext& selectorContext, const QString& previousValue);
|
||||
typedef QString (* TResourceSelectionFunctionWithContext)(const SResourceSelectorContext& selectorContext, const QString& previousValue, void* contextObject);
|
||||
|
||||
struct SStaticResourceSelectorEntry;
|
||||
|
||||
// See note at the beginning of the file.
|
||||
struct IResourceSelectorHost
|
||||
{
|
||||
virtual ~IResourceSelectorHost() = default;
|
||||
virtual QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) = 0;
|
||||
virtual const char* ResourceIconPath(const char* typeName) const = 0;
|
||||
|
||||
virtual void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) = 0;
|
||||
|
||||
// secondary responsibility of this class is to store global selections
|
||||
virtual void SetGlobalSelection(const char* resourceType, const char* value) = 0;
|
||||
virtual const char* GetGlobalSelection(const char* resourceType) const = 0;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
#define INTERNAL_RSH_COMBINE_UTIL(A, B) A##B
|
||||
#define INTERNAL_RSH_COMBINE(A, B) INTERNAL_RSH_COMBINE_UTIL(A, B)
|
||||
#define REGISTER_RESOURCE_SELECTOR(name, function, icon) \
|
||||
static SStaticResourceSelectorEntry INTERNAL_RSH_COMBINE(selector_##function, __LINE__)((name), (function), (icon));
|
||||
|
||||
struct SStaticResourceSelectorEntry
|
||||
{
|
||||
const char* typeName;
|
||||
TResourceSelectionFunction function;
|
||||
TResourceSelectionFunctionWithContext functionWithContext;
|
||||
const char* iconPath;
|
||||
|
||||
static SStaticResourceSelectorEntry*& GetFirst() { static SStaticResourceSelectorEntry* first; return first; }
|
||||
SStaticResourceSelectorEntry* next;
|
||||
|
||||
SStaticResourceSelectorEntry(const char* typeName, TResourceSelectionFunction function, const char* icon)
|
||||
: typeName(typeName)
|
||||
, function(function)
|
||||
, functionWithContext()
|
||||
, iconPath(icon)
|
||||
{
|
||||
next = GetFirst();
|
||||
GetFirst() = this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
SStaticResourceSelectorEntry(const char* typeName, QString (*function)(const SResourceSelectorContext&, const QString& previousValue, T * context), const char* icon)
|
||||
: typeName(typeName)
|
||||
, function()
|
||||
, functionWithContext(TResourceSelectionFunctionWithContext(function))
|
||||
, iconPath(icon)
|
||||
{
|
||||
next = GetFirst();
|
||||
GetFirst() = this;
|
||||
}
|
||||
};
|
||||
|
||||
inline void RegisterModuleResourceSelectors(IResourceSelectorHost* editorResourceSelector)
|
||||
{
|
||||
for (SStaticResourceSelectorEntry* current = SStaticResourceSelectorEntry::GetFirst(); current != 0; current = current->next)
|
||||
{
|
||||
editorResourceSelector->RegisterResourceSelector(current);
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,6 @@ public:
|
||||
MOCK_CONST_METHOD0(GetEditorConfigSpec, ESystemConfigSpec());
|
||||
MOCK_CONST_METHOD0(GetEditorConfigPlatform, ESystemConfigPlatform());
|
||||
MOCK_METHOD0(ReloadTemplates, void());
|
||||
MOCK_METHOD0(GetResourceSelectorHost, IResourceSelectorHost* ());
|
||||
MOCK_METHOD1(ShowStatusText, void(bool ));
|
||||
MOCK_METHOD1(RegisterObjectContextMenuExtension, void(TContextMenuExtensionFunc ));
|
||||
MOCK_METHOD0(GetEnv, SSystemGlobalEnvironment* ());
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "ComponentEntityEditorPlugin.h"
|
||||
|
||||
#include <LyViewPaneNames.h>
|
||||
#include "IResourceSelectorHost.h"
|
||||
|
||||
#include "UI/QComponentEntityEditorMainWindow.h"
|
||||
#include "UI/QComponentEntityEditorOutlinerWindow.h"
|
||||
@@ -180,8 +179,6 @@ ComponentEntityEditorPlugin::ComponentEntityEditorPlugin([[maybe_unused]] IEdito
|
||||
RegisterViewPane<SliceRelationshipWidget>(LyViewPane::SliceRelationships, LyViewPane::CategoryTools, options);
|
||||
}
|
||||
|
||||
RegisterModuleResourceSelectors(GetIEditor()->GetResourceSelectorHost());
|
||||
|
||||
ComponentEntityEditorPluginInternal::RegisterSandboxObjects();
|
||||
|
||||
// Check for common mistakes in component declarations
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
#include <Editor/QtViewPaneManager.h>
|
||||
#include <Editor/EditorViewportSettings.h>
|
||||
#include <Editor/Util/PathUtil.h>
|
||||
#include <IResourceSelectorHost.h>
|
||||
#include "CryEdit.h"
|
||||
#include "Undo/Undo.h"
|
||||
|
||||
@@ -1387,16 +1386,6 @@ AZStd::string SandboxIntegrationManager::GetLevelName()
|
||||
return AZStd::string(GetIEditor()->GetGameEngine()->GetLevelName().toUtf8().constData());
|
||||
}
|
||||
|
||||
AZStd::string SandboxIntegrationManager::SelectResource(const AZStd::string& resourceType, const AZStd::string& previousValue)
|
||||
{
|
||||
SResourceSelectorContext context;
|
||||
context.parentWidget = GetMainWindow();
|
||||
context.typeName = resourceType.c_str();
|
||||
|
||||
QString resource = GetEditor()->GetResourceSelectorHost()->SelectResource(context, previousValue.c_str());
|
||||
return AZStd::string(resource.toUtf8().constData());
|
||||
}
|
||||
|
||||
void SandboxIntegrationManager::OnContextReset()
|
||||
{
|
||||
// Deselect everything.
|
||||
|
||||
@@ -158,7 +158,6 @@ private:
|
||||
void LaunchLuaEditor(const char* files) override;
|
||||
bool IsLevelDocumentOpen() override;
|
||||
AZStd::string GetLevelName() override;
|
||||
AZStd::string SelectResource(const AZStd::string& resourceType, const AZStd::string& previousValue) override;
|
||||
void OpenPinnedInspector(const AzToolsFramework::EntityIdSet& entities) override;
|
||||
void ClosePinnedInspector(AzToolsFramework::EntityPropertyEditor* editor) override;
|
||||
void GoToSelectedOrHighlightedEntitiesInViewports() override;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "CryFile.h"
|
||||
#include "PerforceSourceControl.h"
|
||||
#include "PasswordDlg.h"
|
||||
#include <CryCommon/CryThread.h>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDir>
|
||||
@@ -23,7 +22,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
CryCriticalSection g_cPerforceValues;
|
||||
AZStd::mutex g_cPerforceValues;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -31,9 +30,9 @@ ULONG STDMETHODCALLTYPE CPerforceSourceControl::Release()
|
||||
{
|
||||
if ((--m_ref) == 0)
|
||||
{
|
||||
g_cPerforceValues.Lock();
|
||||
g_cPerforceValues.lock();
|
||||
delete this;
|
||||
g_cPerforceValues.Unlock();
|
||||
g_cPerforceValues.unlock();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -57,7 +56,7 @@ void CPerforceSourceControl::ShowSettings()
|
||||
|
||||
void CPerforceSourceControl::SetSourceControlState(SourceControlState state)
|
||||
{
|
||||
CryAutoLock<CryCriticalSection> lock(g_cPerforceValues);
|
||||
AZStd::scoped_lock lock(g_cPerforceValues);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
||||
@@ -1,163 +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 "EditorDefs.h"
|
||||
|
||||
#include "ResourceSelectorHost.h"
|
||||
|
||||
// Qt
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
||||
|
||||
|
||||
class CResourceSelectorHost
|
||||
: public IResourceSelectorHost
|
||||
{
|
||||
public:
|
||||
CResourceSelectorHost()
|
||||
{
|
||||
RegisterModuleResourceSelectors(this);
|
||||
}
|
||||
|
||||
QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) override
|
||||
{
|
||||
if (!context.typeName)
|
||||
{
|
||||
assert(false && "SResourceSelectorContext::typeName is not specified");
|
||||
return QString();
|
||||
}
|
||||
|
||||
TTypeMap::iterator it = m_typeMap.find(context.typeName);
|
||||
if (it == m_typeMap.end())
|
||||
{
|
||||
QMessageBox::critical(QApplication::activeWindow(), QString(), QObject::tr("No Resource Selector is registered for resource type \"%1\"").arg(context.typeName));
|
||||
return previousValue;
|
||||
}
|
||||
|
||||
QString result = previousValue;
|
||||
if (it->second->function)
|
||||
{
|
||||
result = it->second->function(context, previousValue);
|
||||
}
|
||||
else if (it->second->functionWithContext)
|
||||
{
|
||||
result = it->second->functionWithContext(context, previousValue, context.contextObject);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ResourceIconPath(const char* typeName) const override
|
||||
{
|
||||
TTypeMap::const_iterator it = m_typeMap.find(typeName);
|
||||
if (it != m_typeMap.end())
|
||||
{
|
||||
return it->second->iconPath;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) override
|
||||
{
|
||||
m_typeMap[entry->typeName] = entry;
|
||||
}
|
||||
|
||||
void SetGlobalSelection(const char* resourceType, const char* value) override
|
||||
{
|
||||
if (!resourceType || !value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_globallySelectedResources[resourceType] = value;
|
||||
}
|
||||
|
||||
const char* GetGlobalSelection(const char* resourceType) const override
|
||||
{
|
||||
if (!resourceType)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
auto it = m_globallySelectedResources.find(resourceType);
|
||||
if (it != m_globallySelectedResources.end())
|
||||
{
|
||||
return it->second.c_str();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
using TTypeMap = std::map<AZStd::string, const SStaticResourceSelectorEntry *, stl::less_stricmp<AZStd::string>>;
|
||||
TTypeMap m_typeMap;
|
||||
|
||||
std::map<AZStd::string, AZStd::string> m_globallySelectedResources;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
IResourceSelectorHost* CreateResourceSelectorHost()
|
||||
{
|
||||
return new CResourceSelectorHost();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
QString SoundFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
||||
{
|
||||
AssetSelectionModel selection = AssetSelectionModel::AssetTypeSelection("Audio");
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
||||
if (selection.IsValid())
|
||||
{
|
||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path::FullPathToGamePath(previousValue);
|
||||
}
|
||||
}
|
||||
REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "")
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
QString ModelFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
||||
{
|
||||
AssetSelectionModel selection = AssetSelectionModel::AssetGroupSelection("Geometry");
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
||||
if (selection.IsValid())
|
||||
{
|
||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path::FullPathToGamePath(previousValue);
|
||||
}
|
||||
}
|
||||
REGISTER_RESOURCE_SELECTOR("Model", ModelFileSelector, "")
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
QString GeomCacheFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
||||
{
|
||||
AssetSelectionModel selection = AssetSelectionModel::AssetTypeSelection("Geom Cache");
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
||||
if (selection.IsValid())
|
||||
{
|
||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path::FullPathToGamePath(previousValue);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_RESOURCE_SELECTOR("GeomCache", GeomCacheFileSelector, "")
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
||||
#define CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
||||
#pragma once
|
||||
|
||||
#include "IResourceSelectorHost.h"
|
||||
|
||||
IResourceSelectorHost* CreateResourceSelectorHost();
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CryThread.h"
|
||||
#include "../Include/SandboxAPI.h"
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "StringHelpers.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
int StringHelpers::CompareIgnoreCase(const AZStd::string& str0, const AZStd::string& str1)
|
||||
{
|
||||
const size_t minLength = Util::getMin(str0.length(), str1.length());
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <vector>
|
||||
|
||||
namespace StringHelpers
|
||||
{
|
||||
|
||||
@@ -351,7 +351,7 @@ void CVarBlock::EnableUpdateCallbacks(bool boEnable)
|
||||
void CVarBlock::GatherUsedResourcesInVar(IVariable* pVar, CUsedResources& resources)
|
||||
{
|
||||
int type = pVar->GetDataType();
|
||||
if (type == IVariable::DT_FILE || type == IVariable::DT_OBJECT || type == IVariable::DT_TEXTURE)
|
||||
if (type == IVariable::DT_TEXTURE)
|
||||
{
|
||||
// this is file.
|
||||
QString filename;
|
||||
|
||||
@@ -22,6 +22,8 @@ AZ_PUSH_DISABLE_WARNING(4458, "-Wunknown-warning-option")
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#include <QVariant>
|
||||
|
||||
#include <StlUtils.h>
|
||||
|
||||
inline const char* to_c_str(const char* str) { return str; }
|
||||
#define MAX_VAR_STRING_LENGTH 4096
|
||||
|
||||
@@ -140,15 +142,10 @@ struct IVariable
|
||||
DT_PERCENT, //!< Percent data type, (Same as simple but value is from 0-1 and UI will be from 0-100).
|
||||
DT_COLOR,
|
||||
DT_ANGLE,
|
||||
DT_FILE,
|
||||
DT_TEXTURE,
|
||||
DT_ANIMATION,
|
||||
DT_OBJECT,
|
||||
DT_SHADER,
|
||||
DT_LOCAL_STRING,
|
||||
DT_EQUIP,
|
||||
DT_REVERBPRESET,
|
||||
DT_DEPRECATED0, // formerly DT_MATERIAL
|
||||
DT_MATERIALLOOKUP,
|
||||
DT_EXTARRAY, // Extendable Array
|
||||
DT_SEQUENCE, // Movie Sequence (DEPRECATED, use DT_SEQUENCE_ID, instead.)
|
||||
@@ -158,7 +155,6 @@ struct IVariable
|
||||
DT_SEQUENCE_ID, // Movie Sequence
|
||||
DT_LIGHT_ANIMATION, // Light Animation Node in the global Light Animation Set
|
||||
DT_PARTICLE_EFFECT,
|
||||
DT_GEOM_CACHE, // Geometry cache
|
||||
DT_DEPRECATED, // formerly DT_FLARE
|
||||
DT_AUDIO_TRIGGER,
|
||||
DT_AUDIO_SWITCH,
|
||||
|
||||
@@ -37,17 +37,12 @@ namespace Prop
|
||||
{ IVariable::DT_CURVE | IVariable::DT_PERCENT, "FloatCurve", ePropertyFloatCurve, 13 },
|
||||
{ IVariable::DT_CURVE | IVariable::DT_COLOR, "ColorCurve", ePropertyColorCurve, 1 },
|
||||
{ IVariable::DT_ANGLE, "Angle", ePropertyAngle, 0 },
|
||||
{ IVariable::DT_FILE, "File", ePropertyFile, 7 },
|
||||
{ IVariable::DT_TEXTURE, "Texture", ePropertyTexture, 4 },
|
||||
{ IVariable::DT_ANIMATION, "Animation", ePropertyAnimation, -1 },
|
||||
{ IVariable::DT_MOTION, "Motion", ePropertyMotion, -1 },
|
||||
{ IVariable::DT_OBJECT, "Model", ePropertyModel, 5 },
|
||||
{ IVariable::DT_SIMPLE, "Selection", ePropertySelection, -1 },
|
||||
{ IVariable::DT_SIMPLE, "List", ePropertyList, -1 },
|
||||
{ IVariable::DT_SHADER, "Shader", ePropertyShader, 9 },
|
||||
{ IVariable::DT_DEPRECATED0, "DEPRECATED", ePropertyDeprecated2, -1 },
|
||||
{ IVariable::DT_EQUIP, "Equip", ePropertyEquip, 11 },
|
||||
{ IVariable::DT_REVERBPRESET, "ReverbPreset", ePropertyReverbPreset, 11 },
|
||||
{ IVariable::DT_LOCAL_STRING, "LocalString", ePropertyLocalString, 3 },
|
||||
{ IVariable::DT_SEQUENCE, "Sequence", ePropertySequence, -1 },
|
||||
{ IVariable::DT_MISSIONOBJ, "Mission Objective", ePropertyMissionObj, -1 },
|
||||
@@ -55,7 +50,6 @@ namespace Prop
|
||||
{ IVariable::DT_SEQUENCE_ID, "SequenceId", ePropertySequenceId, -1 },
|
||||
{ IVariable::DT_LIGHT_ANIMATION, "LightAnimation", ePropertyLightAnimation, -1 },
|
||||
{ IVariable::DT_PARTICLE_EFFECT, "ParticleEffect", ePropertyParticleName, 3 },
|
||||
{ IVariable::DT_GEOM_CACHE, "Geometry Cache", ePropertyGeomCache, 5 },
|
||||
{ IVariable::DT_AUDIO_TRIGGER, "Audio Trigger", ePropertyAudioTrigger, 6 },
|
||||
{ IVariable::DT_AUDIO_SWITCH, "Audio Switch", ePropertyAudioSwitch, 6 },
|
||||
{ IVariable::DT_AUDIO_SWITCH_STATE, "Audio Switch", ePropertyAudioSwitchState, 6 },
|
||||
@@ -301,31 +295,4 @@ namespace Prop
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* GetPropertyTypeToResourceType(PropertyType type)
|
||||
{
|
||||
// The strings below are names used together with
|
||||
// REGISTER_RESOURCE_SELECTOR. See IResourceSelector.h.
|
||||
switch (type)
|
||||
{
|
||||
case ePropertyModel:
|
||||
return "Model";
|
||||
case ePropertyGeomCache:
|
||||
return "GeomCache";
|
||||
case ePropertyAudioTrigger:
|
||||
return "AudioTrigger";
|
||||
case ePropertyAudioSwitch:
|
||||
return "AudioSwitch";
|
||||
case ePropertyAudioSwitchState:
|
||||
return "AudioSwitchState";
|
||||
case ePropertyAudioRTPC:
|
||||
return "AudioRTPC";
|
||||
case ePropertyAudioEnvironment:
|
||||
return "AudioEnvironment";
|
||||
case ePropertyAudioPreloadRequest:
|
||||
return "AudioPreloadRequest";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,16 +28,11 @@ enum PropertyType
|
||||
ePropertyAngle,
|
||||
ePropertyFloatCurve,
|
||||
ePropertyColorCurve,
|
||||
ePropertyFile,
|
||||
ePropertyTexture,
|
||||
ePropertyAnimation,
|
||||
ePropertyModel,
|
||||
ePropertySelection,
|
||||
ePropertyList,
|
||||
ePropertyShader,
|
||||
ePropertyDeprecated2, // formerly ePropertyMaterial
|
||||
ePropertyEquip,
|
||||
ePropertyReverbPreset,
|
||||
ePropertyLocalString,
|
||||
ePropertyDeprecated0, // formerly ePropertyCustomAction
|
||||
ePropertyGameToken,
|
||||
@@ -48,7 +43,6 @@ enum PropertyType
|
||||
ePropertyLightAnimation,
|
||||
ePropertyDeprecated1, // formerly ePropertyFlare
|
||||
ePropertyParticleName,
|
||||
ePropertyGeomCache,
|
||||
ePropertyAudioTrigger,
|
||||
ePropertyAudioSwitch,
|
||||
ePropertyAudioSwitchState,
|
||||
|
||||
@@ -289,7 +289,6 @@ set(FILES
|
||||
Include/IPlugin.h
|
||||
Include/IPreferencesPage.h
|
||||
Include/IRenderListener.h
|
||||
Include/IResourceSelectorHost.h
|
||||
Include/ISourceControl.h
|
||||
Include/ISubObjectSelectionReferenceFrameCalculator.h
|
||||
Include/ITextureDatabaseUpdater.h
|
||||
@@ -360,8 +359,6 @@ set(FILES
|
||||
Controls/TimelineCtrl.cpp
|
||||
Controls/TimelineCtrl.h
|
||||
Controls/WndGridHelper.h
|
||||
Controls/ReflectedPropertyControl/PropertyAnimationCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyAnimationCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyGenericCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyMiscCtrl.cpp
|
||||
@@ -372,8 +369,6 @@ set(FILES
|
||||
Controls/ReflectedPropertyControl/PropertyResourceCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyCtrl.h
|
||||
Controls/ReflectedPropertyControl/ReflectedPropertiesPanel.cpp
|
||||
Controls/ReflectedPropertyControl/ReflectedPropertiesPanel.h
|
||||
MainStatusBar.cpp
|
||||
MainStatusBar.h
|
||||
MainStatusBarItems.h
|
||||
@@ -590,8 +585,6 @@ set(FILES
|
||||
FBXExporterDialog.ui
|
||||
FileTypeUtils.cpp
|
||||
LightmapCompiler/SimpleTriangleRasterizer.cpp
|
||||
ResourceSelectorHost.cpp
|
||||
ResourceSelectorHost.h
|
||||
ToolBox.cpp
|
||||
TrackViewNewSequenceDialog.cpp
|
||||
TrackViewNewSequenceDialog.ui
|
||||
@@ -668,7 +661,6 @@ set(FILES
|
||||
TrackView/2DBezierKeyUIControls.cpp
|
||||
TrackView/AssetBlendKeyUIControls.cpp
|
||||
TrackView/CaptureKeyUIControls.cpp
|
||||
TrackView/CharacterKeyUIControls.cpp
|
||||
TrackView/ConsoleKeyUIControls.cpp
|
||||
TrackView/EventKeyUIControls.cpp
|
||||
TrackView/GotoKeyUIControls.cpp
|
||||
|
||||
@@ -728,6 +728,7 @@ namespace AZ
|
||||
DestroyReflectionManager();
|
||||
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearNotifiers();
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearMergeEvents();
|
||||
|
||||
// Uninit and unload any dynamic modules.
|
||||
m_moduleManager->UnloadModules();
|
||||
|
||||
@@ -58,6 +58,12 @@ namespace AZ
|
||||
|
||||
Event& operator=(Event&& rhs);
|
||||
|
||||
//! Take the handlers registered with the other event
|
||||
//! and move them to this event. The other will event
|
||||
//! will be cleared after call
|
||||
//! @param other event to move handlers
|
||||
Event& ClaimHandlers(Event&& other);
|
||||
|
||||
//! Returns true if at least one handler is connected to this event.
|
||||
bool HasHandlerConnected() const;
|
||||
|
||||
|
||||
@@ -207,6 +207,32 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
template <typename... Params>
|
||||
auto Event<Params...>::ClaimHandlers(Event&& other) -> Event&
|
||||
{
|
||||
auto handlers = AZStd::move(other.m_handlers);
|
||||
auto addList = AZStd::move(other.m_addList);
|
||||
other.m_freeList = {};
|
||||
other.m_updating = false;
|
||||
|
||||
AZStd::array handlerContainers{ &handlers, &addList };
|
||||
for (AZStd::vector<Handler*>* handlerList : handlerContainers)
|
||||
{
|
||||
for (Handler* handler : *handlerList)
|
||||
{
|
||||
if (handler != nullptr)
|
||||
{
|
||||
handler->m_index = 0;
|
||||
handler->m_event = this;
|
||||
Connect(*handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <typename... Params>
|
||||
bool Event<Params...>::HasHandlerConnected() const
|
||||
{
|
||||
|
||||
@@ -123,6 +123,36 @@ namespace AZ
|
||||
using NotifyEvent = AZ::Event<AZStd::string_view, Type>;
|
||||
using NotifyEventHandler = typename NotifyEvent::Handler;
|
||||
|
||||
using PreMergeEventCallback = AZStd::function<void(AZStd::string_view path, AZStd::string_view rootKey)>;
|
||||
using PostMergeEventCallback = AZStd::function<void(AZStd::string_view path, AZStd::string_view rootKey)>;
|
||||
using PreMergeEvent = AZ::Event<AZStd::string_view, AZStd::string_view>;
|
||||
using PostMergeEvent = AZ::Event<AZStd::string_view, AZStd::string_view>;
|
||||
using PreMergeEventHandler = typename PreMergeEvent::Handler;
|
||||
using PostMergeEventHandler = typename PostMergeEvent::Handler;
|
||||
|
||||
struct ScopedMergeEvent
|
||||
{
|
||||
ScopedMergeEvent(
|
||||
PreMergeEvent& preMergeEvent, PostMergeEvent& postMergeEvent, AZStd::string_view filePath, AZStd::string_view rootKey)
|
||||
: m_preMergeEvent{ preMergeEvent }
|
||||
, m_postMergeEvent{ postMergeEvent }
|
||||
, m_filePath{ filePath }
|
||||
, m_rootKey{ rootKey }
|
||||
{
|
||||
preMergeEvent.Signal(m_filePath, m_rootKey);
|
||||
}
|
||||
|
||||
~ScopedMergeEvent()
|
||||
{
|
||||
m_postMergeEvent.Signal(m_filePath, m_rootKey);
|
||||
}
|
||||
|
||||
PreMergeEvent& m_preMergeEvent;
|
||||
PostMergeEvent& m_postMergeEvent;
|
||||
AZStd::string_view m_filePath;
|
||||
AZStd::string_view m_rootKey;
|
||||
};
|
||||
|
||||
using VisitorCallback =
|
||||
AZStd::function<VisitResponse(AZStd::string_view path, AZStd::string_view valueName, VisitAction action, Type type)>;
|
||||
//! Base class for the visitor class during traversal over the Settings Registry. The type-agnostic function is always
|
||||
@@ -169,6 +199,20 @@ namespace AZ
|
||||
//! @callback The function to call when an entry gets a new/updated value.
|
||||
[[nodiscard]] virtual NotifyEventHandler RegisterNotifier(NotifyCallback&& callback) = 0;
|
||||
|
||||
//! Register a function that will be called before a file is merged.
|
||||
//! @callback The function to call before a file is merged.
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called before a file is merged.
|
||||
//! @callback The function to call before a file is merged.
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent (PreMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent (PostMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Gets the boolean value at the provided path.
|
||||
//! @param result The target to write the result to.
|
||||
//! @param path The path to the value.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace AZ
|
||||
{
|
||||
template<typename T>
|
||||
bool SettingsRegistryImpl::SetValueInternal(AZStd::string_view path, T value, SettingsRegistryInterface::Type type)
|
||||
bool SettingsRegistryImpl::SetValueInternal(AZStd::string_view path, T value)
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
@@ -56,7 +56,6 @@ namespace AZ
|
||||
static_assert(!AZStd::is_same_v<T, T>, "SettingsRegistryImpl::SetValueInternal called with unsupported type.");
|
||||
}
|
||||
|
||||
m_notifiers.Signal(path, type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -157,11 +156,11 @@ namespace AZ
|
||||
// Setting to empty string to prevent assert
|
||||
path = "";
|
||||
}
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
|
||||
rapidjson::Pointer pointer(path.data(), path.length());
|
||||
if (pointer.IsValid())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
const rapidjson::Value* value = pointer.Get(m_settings);
|
||||
if (value)
|
||||
{
|
||||
@@ -207,7 +206,7 @@ namespace AZ
|
||||
{
|
||||
NotifyEventHandler notifyHandler{ callback };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
AZStd::scoped_lock lock(m_notifierMutex);
|
||||
notifyHandler.Connect(m_notifiers);
|
||||
}
|
||||
return notifyHandler;
|
||||
@@ -217,7 +216,7 @@ namespace AZ
|
||||
{
|
||||
NotifyEventHandler notifyHandler{ AZStd::move(callback) };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
AZStd::scoped_lock lock(m_notifierMutex);
|
||||
notifyHandler.Connect(m_notifiers);
|
||||
}
|
||||
return notifyHandler;
|
||||
@@ -225,10 +224,82 @@ namespace AZ
|
||||
|
||||
void SettingsRegistryImpl::ClearNotifiers()
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
AZStd::scoped_lock lock(m_notifierMutex);
|
||||
m_notifiers.DisconnectAllHandlers();
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPreMergeEvent(const PreMergeEventCallback& callback) -> PreMergeEventHandler
|
||||
{
|
||||
PreMergeEventHandler preMergeHandler{ callback };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
preMergeHandler.Connect(m_preMergeEvent);
|
||||
}
|
||||
return preMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPreMergeEvent(PreMergeEventCallback&& callback) -> PreMergeEventHandler
|
||||
{
|
||||
PreMergeEventHandler preMergeHandler{ AZStd::move(callback) };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
preMergeHandler.Connect(m_preMergeEvent);
|
||||
}
|
||||
return preMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPostMergeEvent(const PostMergeEventCallback& callback) -> PostMergeEventHandler
|
||||
{
|
||||
PostMergeEventHandler postMergeHandler{ callback };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
postMergeHandler.Connect(m_postMergeEvent);
|
||||
}
|
||||
return postMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPostMergeEvent(PostMergeEventCallback&& callback) -> PostMergeEventHandler
|
||||
{
|
||||
PostMergeEventHandler postMergeHandler{ AZStd::move(callback) };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
postMergeHandler.Connect(m_postMergeEvent);
|
||||
}
|
||||
return postMergeHandler;
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::ClearMergeEvents()
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
m_preMergeEvent.DisconnectAllHandlers();
|
||||
m_postMergeEvent.DisconnectAllHandlers();
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::SignalNotifier(AZStd::string_view jsonPath, Type type)
|
||||
{
|
||||
// Move the Notifier AZ::Event to a local AZ::Event in order to allow
|
||||
// the notifier handlers to be signaled outside of the notifier mutex
|
||||
// This allows other threads to register notifiers while this thread
|
||||
// is invoking the handlers
|
||||
decltype(m_notifiers) localNotifierEvent;
|
||||
{
|
||||
AZStd::scoped_lock lock(m_notifierMutex);
|
||||
localNotifierEvent = AZStd::move(m_notifiers);
|
||||
}
|
||||
|
||||
localNotifierEvent.Signal(jsonPath, type);
|
||||
|
||||
{
|
||||
// Swap the local handlers with the current m_notifiers which
|
||||
// will contain any handlers added during the signaling of the
|
||||
// local event
|
||||
AZStd::scoped_lock lock(m_notifierMutex);
|
||||
AZStd::swap(m_notifiers, localNotifierEvent);
|
||||
// Append any added handlers to the m_notifier structure
|
||||
m_notifiers.ClaimHandlers(AZStd::move(localNotifierEvent));
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRegistryInterface::Type SettingsRegistryImpl::GetType(AZStd::string_view path) const
|
||||
{
|
||||
if (path.empty())
|
||||
@@ -239,11 +310,11 @@ namespace AZ
|
||||
path = "";
|
||||
}
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
|
||||
rapidjson::Pointer pointer(path.data(), path.length());
|
||||
if (pointer.IsValid())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
const rapidjson::Value* value = pointer.Get(m_settings);
|
||||
if (value)
|
||||
{
|
||||
@@ -316,11 +387,11 @@ namespace AZ
|
||||
// Setting to empty string to prevent assert
|
||||
path = "";
|
||||
}
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
|
||||
rapidjson::Pointer pointer(path.data(), path.length());
|
||||
if (pointer.IsValid())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
const rapidjson::Value* value = pointer.Get(m_settings);
|
||||
if (value)
|
||||
{
|
||||
@@ -333,32 +404,52 @@ namespace AZ
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, bool value)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return SetValueInternal(path, value, Type::Boolean);
|
||||
if (AZStd::scoped_lock lock(m_settingMutex); !SetValueInternal(path, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalNotifier(path, Type::Boolean);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, s64 value)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return SetValueInternal(path, value, Type::Integer);
|
||||
if (AZStd::scoped_lock lock(m_settingMutex); !SetValueInternal(path, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalNotifier(path, Type::Integer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, u64 value)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return SetValueInternal(path, value, Type::Integer);
|
||||
if (AZStd::scoped_lock lock(m_settingMutex); !SetValueInternal(path, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalNotifier(path, Type::Integer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, double value)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return SetValueInternal(path, value, Type::FloatingPoint);
|
||||
if (AZStd::scoped_lock lock(m_settingMutex); !SetValueInternal(path, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalNotifier(path, Type::FloatingPoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, AZStd::string_view value)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return SetValueInternal(path, value, Type::String);
|
||||
if (AZStd::scoped_lock lock(m_settingMutex); !SetValueInternal(path, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalNotifier(path, Type::String);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::Set(AZStd::string_view path, const char* value)
|
||||
@@ -376,7 +467,6 @@ namespace AZ
|
||||
path = "";
|
||||
}
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
|
||||
rapidjson::Pointer pointer(path.data(), path.length());
|
||||
if (pointer.IsValid())
|
||||
@@ -386,9 +476,10 @@ namespace AZ
|
||||
value, nullptr, valueTypeID, m_serializationSettings);
|
||||
if (jsonResult.GetProcessing() != JsonSerializationResult::Processing::Halted)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
rapidjson::Value& setting = pointer.Create(m_settings, m_settings.GetAllocator());
|
||||
setting = AZStd::move(store);
|
||||
m_notifiers.Signal(path, Type::Object);
|
||||
SignalNotifier(path, Type::Object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -404,13 +495,13 @@ namespace AZ
|
||||
// Setting to empty string to prevent assert
|
||||
path = "";
|
||||
}
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
rapidjson::Pointer pointerPath(path.data(), path.size());
|
||||
if (!pointerPath.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
return pointerPath.Erase(m_settings);
|
||||
}
|
||||
|
||||
@@ -540,7 +631,7 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
m_notifiers.Signal("", Type::Object);
|
||||
SignalNotifier("", Type::Object);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -562,8 +653,6 @@ namespace AZ
|
||||
scratchBuffer = &buffer;
|
||||
}
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
|
||||
bool result = false;
|
||||
if (path[path.length()] == 0)
|
||||
{
|
||||
@@ -577,6 +666,8 @@ namespace AZ
|
||||
R"(Path "%.*s" is too long. Either make sure that the provided path is terminated or use a shorter path.)",
|
||||
static_cast<int>(path.length()), path.data());
|
||||
Pointer pointer(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/-");
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
Value pathValue(path.data(), aznumeric_caster(path.length()), m_settings.GetAllocator());
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Unable to read registry file."), m_settings.GetAllocator())
|
||||
@@ -622,6 +713,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Error("Settings Registry", false, "Folder path for the Setting Registry is too long: %.*s",
|
||||
static_cast<int>(path.size()), path.data());
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Folder path for the Setting Registry is too long."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(path.data(), aznumeric_caster(path.length()), m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
@@ -659,6 +751,7 @@ namespace AZ
|
||||
if (fileList.size() >= MaxRegistryFolderEntries)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, "Too many files in registry folder.");
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(folderPath.c_str(), aznumeric_caster(folderPath.size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
@@ -678,7 +771,6 @@ namespace AZ
|
||||
SystemFile::FindFiles(folderPath.c_str(), callback);
|
||||
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
if (!platform.empty())
|
||||
{
|
||||
// Move the folderPath prefix back to the supplied path before the wildcard
|
||||
@@ -696,6 +788,7 @@ namespace AZ
|
||||
if (fileList.size() >= MaxRegistryFolderEntries)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, "Too many files in registry folder.");
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(folderPath.c_str(), aznumeric_caster(folderPath.size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
@@ -923,6 +1016,8 @@ namespace AZ
|
||||
collisionFound = true;
|
||||
AZ_Error("Settings Registry", false, R"(Two registry files in "%.*s" point to the same specialization: "%s" and "%s")",
|
||||
AZ_STRING_ARG(folderPath), lhs.m_relativePath.c_str(), rhs.m_relativePath.c_str());
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
historyPointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"),
|
||||
@@ -1077,6 +1172,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Unable to parse registry file due to invalid json."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(path, m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
@@ -1102,6 +1198,7 @@ namespace AZ
|
||||
R"(To merge the supplied settings registry file, the settings within it must be placed within a JSON Object '{}')"
|
||||
R"( in order to allow moving of its fields using the root-key as an anchor.)", path);
|
||||
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Cannot merge registry file with a root which is not a JSON Object,"
|
||||
" an empty root key and a merge approach of JsonMergePatch. Otherwise the Settings Registry would be overridden."
|
||||
@@ -1115,9 +1212,12 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedMergeEvent scopedMergeEvent(m_preMergeEvent, m_postMergeEvent, path, rootKey);
|
||||
|
||||
JsonSerializationResult::ResultCode mergeResult(JsonSerializationResult::Tasks::Merge);
|
||||
if (rootKey.empty())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
mergeResult = JsonSerialization::ApplyPatch(m_settings, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings);
|
||||
}
|
||||
else
|
||||
@@ -1125,6 +1225,7 @@ namespace AZ
|
||||
Pointer root(rootKey.data(), rootKey.length());
|
||||
if (root.IsValid())
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
Value& rootValue = root.Create(m_settings, m_settings.GetAllocator());
|
||||
mergeResult = JsonSerialization::ApplyPatch(rootValue, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings);
|
||||
}
|
||||
@@ -1132,6 +1233,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Failed to root path "%.*s" is invalid.)",
|
||||
aznumeric_cast<int>(rootKey.length()), rootKey.data());
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Invalid root key."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(path, m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
@@ -1141,15 +1243,19 @@ namespace AZ
|
||||
if (mergeResult.GetProcessing() != JsonSerializationResult::Processing::Completed)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Failed to fully merge registry file "%s".)", path);
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Failed to fully merge registry file."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(path, m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
return false;
|
||||
}
|
||||
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetString(path, m_settings.GetAllocator());
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetString(path, m_settings.GetAllocator());
|
||||
}
|
||||
|
||||
m_notifiers.Signal("", Type::Object);
|
||||
SignalNotifier("", Type::Object);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,12 @@ namespace AZ
|
||||
[[nodiscard]] NotifyEventHandler RegisterNotifier(NotifyCallback&& callback) override;
|
||||
void ClearNotifiers();
|
||||
|
||||
[[nodiscard]] PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) override;
|
||||
[[nodiscard]] PreMergeEventHandler RegisterPreMergeEvent(PreMergeEventCallback&& callback) override;
|
||||
[[nodiscard]] PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) override;
|
||||
[[nodiscard]] PostMergeEventHandler RegisterPostMergeEvent(PostMergeEventCallback&& callback) override;
|
||||
void ClearMergeEvents();
|
||||
|
||||
bool Get(bool& result, AZStd::string_view path) const override;
|
||||
bool Get(s64& result, AZStd::string_view path) const override;
|
||||
bool Get(u64& result, AZStd::string_view path) const override;
|
||||
@@ -89,7 +95,7 @@ namespace AZ
|
||||
using RegistryFileList = AZStd::fixed_vector<RegistryFile, MaxRegistryFolderEntries>;
|
||||
|
||||
template<typename T>
|
||||
bool SetValueInternal(AZStd::string_view path, T value, SettingsRegistryInterface::Type type);
|
||||
bool SetValueInternal(AZStd::string_view path, T value);
|
||||
template<typename T>
|
||||
bool GetValueInternal(T& result, AZStd::string_view path) const;
|
||||
VisitResponse Visit(Visitor& visitor, StackedString& path, AZStd::string_view valueName,
|
||||
@@ -100,9 +106,15 @@ namespace AZ
|
||||
const rapidjson::Pointer& historyPointer, AZStd::string_view folderPath);
|
||||
bool ExtractFileDescription(RegistryFile& output, const char* filename, const Specializations& specializations);
|
||||
bool MergeSettingsFileInternal(const char* path, Format format, AZStd::string_view rootKey, AZStd::vector<char>& scratchBuffer);
|
||||
|
||||
void SignalNotifier(AZStd::string_view jsonPath, Type type);
|
||||
|
||||
mutable AZStd::recursive_mutex m_settingMutex;
|
||||
mutable AZStd::recursive_mutex m_notifierMutex;
|
||||
NotifyEvent m_notifiers;
|
||||
PreMergeEvent m_preMergeEvent;
|
||||
PostMergeEvent m_postMergeEvent;
|
||||
|
||||
rapidjson::Document m_settings;
|
||||
JsonSerializerSettings m_serializationSettings;
|
||||
JsonDeserializerSettings m_deserializationSettings;
|
||||
|
||||
@@ -25,6 +25,10 @@ namespace AZ
|
||||
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
|
||||
MOCK_METHOD1(RegisterPreMergeEvent, PreMergeEventHandler(const PreMergeEventCallback&));
|
||||
MOCK_METHOD1(RegisterPreMergeEvent, PreMergeEventHandler(PreMergeEventCallback&&));
|
||||
MOCK_METHOD1(RegisterPostMergeEvent, PostMergeEventHandler(const PostMergeEventCallback&));
|
||||
MOCK_METHOD1(RegisterPostMergeEvent, PostMergeEventHandler(PostMergeEventCallback&&));
|
||||
|
||||
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
|
||||
|
||||
@@ -240,6 +240,37 @@ namespace UnitTest
|
||||
static_assert(!AZStd::is_copy_assignable_v<AZ::Event<int32_t>>, "AZ Events should not be copy assignable");
|
||||
}
|
||||
|
||||
TEST_F(EventTests, TestClaimHandlers_TakesAllSourceHandlers)
|
||||
{
|
||||
AZ::Event<> testEvent1;
|
||||
AZ::Event<> testEvent2;
|
||||
|
||||
int32_t handlerInvokeCount{};
|
||||
auto handlerCallback = [&handlerInvokeCount]()
|
||||
{
|
||||
++handlerInvokeCount;
|
||||
};
|
||||
AZ::Event<>::Handler testHandler1(handlerCallback);
|
||||
AZ::Event<>::Handler testHandler2(handlerCallback);
|
||||
|
||||
testHandler1.Connect(testEvent1);
|
||||
testHandler2.Connect(testEvent2);
|
||||
|
||||
EXPECT_TRUE(testEvent1.HasHandlerConnected());
|
||||
EXPECT_TRUE(testEvent2.HasHandlerConnected());
|
||||
|
||||
testEvent1.ClaimHandlers(AZStd::move(testEvent2));
|
||||
EXPECT_TRUE(testEvent1.HasHandlerConnected());
|
||||
EXPECT_FALSE(testEvent2.HasHandlerConnected());
|
||||
|
||||
// testEvent1 should have both handlers
|
||||
testEvent1.Signal();
|
||||
EXPECT_EQ(2, handlerInvokeCount);
|
||||
// testEvent2 should have neither of the handlers
|
||||
testEvent2.Signal();
|
||||
EXPECT_EQ(2, handlerInvokeCount);
|
||||
}
|
||||
|
||||
TEST_F(EventTests, HandlerMoveAssignment_ProperlyDisconnectsFromOldEvent)
|
||||
{
|
||||
AZ::Event<> testEvent1;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace AzFramework
|
||||
bool GetFullScreenState() const override;
|
||||
void SetFullScreenState(bool fullScreenState) override;
|
||||
bool CanToggleFullScreenState() const override { return true; }
|
||||
uint32_t GetMainDisplayRefreshRate() const;
|
||||
uint32_t GetDisplayRefreshRate() const override;
|
||||
|
||||
private:
|
||||
static NSWindowStyleMask ConvertToNSWindowStyleMask(const WindowStyleMasks& styleMasks);
|
||||
@@ -142,7 +142,7 @@ namespace AzFramework
|
||||
return nativeMask ? nativeMask : defaultMask;
|
||||
}
|
||||
|
||||
uint32_t NativeWindowImpl_Darwin::GetMainDisplayRefreshRate() const
|
||||
uint32_t NativeWindowImpl_Darwin::GetDisplayRefreshRate() const
|
||||
{
|
||||
return m_mainDisplayRefreshRate;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace AzFramework
|
||||
const WindowGeometry& geometry,
|
||||
const WindowStyleMasks& styleMasks) override;
|
||||
NativeWindowHandle GetWindowHandle() const override;
|
||||
uint32_t GetMainDisplayRefreshRate() const;
|
||||
uint32_t GetDisplayRefreshRate() const override;
|
||||
|
||||
private:
|
||||
UIWindow* m_nativeWindow;
|
||||
@@ -66,7 +66,7 @@ namespace AzFramework
|
||||
return m_nativeWindow;
|
||||
}
|
||||
|
||||
uint32_t NativeWindowImpl_Ios::GetMainDisplayRefreshRate() const
|
||||
uint32_t NativeWindowImpl_Ios::GetDisplayRefreshRate() const
|
||||
{
|
||||
return m_mainDisplayRefreshRate;
|
||||
}
|
||||
|
||||
@@ -10,22 +10,9 @@
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
StringifySerializer::StringifySerializer(char delimeter, bool outputFieldNames, const AZStd::string& seperator)
|
||||
: m_delimeter(delimeter)
|
||||
, m_outputFieldNames(outputFieldNames)
|
||||
, m_separator(seperator)
|
||||
const StringifySerializer::ValueMap& StringifySerializer::GetValueMap() const
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
const AZStd::string& StringifySerializer::GetString() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
const StringifySerializer::StringMap& StringifySerializer::GetValueMap() const
|
||||
{
|
||||
return m_map;
|
||||
return m_valueMap;
|
||||
}
|
||||
|
||||
SerializerMode StringifySerializer::GetSerializerMode() const
|
||||
@@ -137,22 +124,9 @@ namespace AzNetworking
|
||||
template <typename T>
|
||||
bool StringifySerializer::ProcessData(const char* name, const T& value)
|
||||
{
|
||||
// Only add delimeters after we have processed at least one element
|
||||
if (!m_string.empty())
|
||||
{
|
||||
m_string += m_delimeter;
|
||||
}
|
||||
|
||||
if (m_outputFieldNames)
|
||||
{
|
||||
m_string += m_prefix;
|
||||
m_string += name;
|
||||
m_string += m_separator;
|
||||
}
|
||||
|
||||
AZ::CVarFixedString string = AZ::ConsoleTypeHelpers::ValueToString(value);
|
||||
m_string += string.c_str();
|
||||
m_map[m_prefix + name] = string.c_str();
|
||||
const AZStd::string keyString = m_prefix + name;
|
||||
AZ::CVarFixedString valueString = AZ::ConsoleTypeHelpers::ValueToString(value);
|
||||
m_valueMap[keyString] = valueString.c_str();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,12 @@ namespace AzNetworking
|
||||
{
|
||||
public:
|
||||
|
||||
using StringMap = AZStd::map<AZStd::string, AZStd::string>;
|
||||
using ValueMap = AZStd::map<AZStd::string, AZStd::string>;
|
||||
|
||||
StringifySerializer(char delimeter = ' ', bool outputFieldNames = true, const AZStd::string& seperator = "=");
|
||||
StringifySerializer() = default;
|
||||
|
||||
// GetString
|
||||
// After serializing objects, get the serialized values as a single string
|
||||
const AZStd::string& GetString() const;
|
||||
|
||||
// GetValueMap
|
||||
// After serializing objects, get the serialized values as key value pairs
|
||||
const StringMap& GetValueMap() const;
|
||||
//! After serializing objects, get the serialized values as a map of key/value pairs.
|
||||
const ValueMap& GetValueMap() const;
|
||||
|
||||
// ISerializer interfaces
|
||||
SerializerMode GetSerializerMode() const override;
|
||||
@@ -62,15 +57,8 @@ namespace AzNetworking
|
||||
template <typename T>
|
||||
bool ProcessData(const char* name, const T& value);
|
||||
|
||||
private:
|
||||
|
||||
char m_delimeter;
|
||||
bool m_outputFieldNames = true;
|
||||
|
||||
StringMap m_map;
|
||||
AZStd::string m_string;
|
||||
ValueMap m_valueMap;
|
||||
AZStd::string m_prefix;
|
||||
AZStd::string m_separator;
|
||||
AZStd::deque<AZStd::size_t> m_prefixSizeStack;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1882,7 +1882,10 @@ namespace AzQtComponents
|
||||
return;
|
||||
}
|
||||
|
||||
QApplication::setOverrideCursor(m_dragCursor);
|
||||
if (!QApplication::overrideCursor())
|
||||
{
|
||||
QApplication::setOverrideCursor(m_dragCursor);
|
||||
}
|
||||
|
||||
QPoint relativePressPos = pressPos;
|
||||
|
||||
|
||||
@@ -841,9 +841,6 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual AZStd::string GetComponentIconPath(const AZ::Uuid& /*componentType*/, AZ::Crc32 /*componentIconAttrib*/, AZ::Component* /*component*/) { return AZStd::string(); }
|
||||
|
||||
/// Resource Selector hook, returns a path for a resource.
|
||||
virtual AZStd::string SelectResource(const AZStd::string& /*resourceType*/, const AZStd::string& /*previousValue*/) { return AZStd::string(); }
|
||||
|
||||
/**
|
||||
* Calculate the navigation 2D radius in units of an agent given its Navigation Type Name
|
||||
* @param angentTypeName the name that identifies the agent navigation type
|
||||
|
||||
+40
-1
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : For listing available script commands with their descriptions
|
||||
|
||||
#include "ScriptHelpDialog.h"
|
||||
@@ -23,6 +22,7 @@
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/EditorPythonConsoleBus.h> // for EditorPythonConsoleInterface
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <AzToolsFramework/PythonTerminal/ui_ScriptHelpDialog.h>
|
||||
@@ -313,6 +313,45 @@ namespace AzToolsFramework
|
||||
connect(ui->tableView, &ScriptTableView::doubleClicked, this, &CScriptHelpDialog::OnDoubleClick);
|
||||
}
|
||||
|
||||
CScriptHelpDialog* CScriptHelpDialog::GetInstance()
|
||||
{
|
||||
static CScriptHelpDialog* pInstance = nullptr;
|
||||
if (!pInstance)
|
||||
{
|
||||
QMainWindow* mainWindow = GetMainWindowOfCurrentApplication();
|
||||
if (!mainWindow)
|
||||
{
|
||||
AZ_Assert(false, "Failed to find MainWindow.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget* parentWidget = mainWindow->window()
|
||||
? mainWindow->window()
|
||||
: mainWindow; // MainWindow might have a WindowDecorationWrapper parent. Makes a difference on macOS.
|
||||
pInstance = new CScriptHelpDialog(parentWidget);
|
||||
}
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
QMainWindow* CScriptHelpDialog::GetMainWindowOfCurrentApplication()
|
||||
{
|
||||
QWidget* mainWindowWidget = nullptr;
|
||||
EditorWindowRequestBus::BroadcastResult(mainWindowWidget, &EditorWindowRequests::GetAppMainWindow);
|
||||
if (QMainWindow* mainWindow = qobject_cast<QMainWindow*>(mainWindowWidget))
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
for (QWidget* topLevelWidget : qApp->topLevelWidgets())
|
||||
{
|
||||
if (QMainWindow* mainWindow = qobject_cast<QMainWindow*>(topLevelWidget))
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CScriptHelpDialog::OnDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
||||
@@ -132,43 +132,13 @@ namespace AzToolsFramework
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static CScriptHelpDialog* GetInstance()
|
||||
{
|
||||
static CScriptHelpDialog* pInstance = nullptr;
|
||||
if (!pInstance)
|
||||
{
|
||||
QMainWindow* mainWindow = GetMainWindowOfCurrentApplication();
|
||||
if (!mainWindow)
|
||||
{
|
||||
AZ_Assert(false, "Failed to find MainWindow.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget* parentWidget = mainWindow->window() ? mainWindow->window() : mainWindow; // MainWindow might have a WindowDecorationWrapper parent. Makes a difference on macOS.
|
||||
pInstance = new CScriptHelpDialog(parentWidget);
|
||||
}
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
static CScriptHelpDialog* GetInstance();
|
||||
private Q_SLOTS:
|
||||
void OnDoubleClick(const QModelIndex&);
|
||||
|
||||
private:
|
||||
static QMainWindow* GetMainWindowOfCurrentApplication()
|
||||
{
|
||||
QMainWindow* mainWindow = nullptr;
|
||||
for (QWidget* w : qApp->topLevelWidgets())
|
||||
{
|
||||
mainWindow = qobject_cast<QMainWindow*>(w);
|
||||
if (mainWindow)
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
explicit CScriptHelpDialog(QWidget* parent = nullptr);
|
||||
static QMainWindow* GetMainWindowOfCurrentApplication();
|
||||
QScopedPointer<Ui::ScriptDialog> ui;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+936
-181
File diff suppressed because it is too large
Load Diff
+68
-2
@@ -19,6 +19,7 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
#include <AzCore/Component/EntityBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzToolsFramework/Undo/UndoSystem.h>
|
||||
@@ -110,6 +111,7 @@ namespace AzToolsFramework
|
||||
, public EditorInspectorComponentNotificationBus::MultiHandler
|
||||
, private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
|
||||
, public AZ::EntitySystemBus::Handler
|
||||
, public AZ::TickBus::Handler
|
||||
, private EditorWindowUIRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT;
|
||||
@@ -117,6 +119,23 @@ namespace AzToolsFramework
|
||||
|
||||
AZ_CLASS_ALLOCATOR(EntityPropertyEditor, AZ::SystemAllocator, 0)
|
||||
|
||||
enum class ReorderState
|
||||
{
|
||||
Inactive, // No row widget reordering operation is in progress.
|
||||
DraggingComponent, // User is dragging a component editor.
|
||||
DraggingRowWidget, // User is dragging a row widget around.
|
||||
UsingMenu, // User has the context menu open and may hover over a move up/down operation.
|
||||
MenuOperationInProgress, // User has selected a move/up down menu item.
|
||||
WaitForRedraw, // Wait for rebuild of RPE.
|
||||
HighlightMovedRow // User has moved a row, highlight the new position.
|
||||
};
|
||||
|
||||
enum class DropArea
|
||||
{
|
||||
Above,
|
||||
Below
|
||||
};
|
||||
|
||||
EntityPropertyEditor(QWidget* pParent = NULL, Qt::WindowFlags flags = Qt::WindowFlags(), bool isLevelEntityEditor = false);
|
||||
virtual ~EntityPropertyEditor();
|
||||
|
||||
@@ -151,6 +170,16 @@ namespace AzToolsFramework
|
||||
bool IsLockedToSpecificEntities() const { return !m_overrideSelectedEntityIds.empty(); }
|
||||
|
||||
static bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components, const ComponentFilter& filter);
|
||||
|
||||
ReorderState GetReorderState() const;
|
||||
ComponentEditor* GetEditorForCurrentReorderRowWidget() const;
|
||||
PropertyRowWidget* GetReorderRowWidget() const;
|
||||
PropertyRowWidget* GetReorderDropTarget() const;
|
||||
DropArea GetReorderDropArea() const;
|
||||
QPixmap GetReorderRowWidgetImage() const;
|
||||
float GetMoveIndicatorAlpha() const;
|
||||
PropertyRowWidget* GetRowToHighlight();
|
||||
|
||||
Q_SIGNALS:
|
||||
void SelectedEntityNameChanged(const AZ::EntityId& entityId, const AZStd::string& name);
|
||||
|
||||
@@ -211,6 +240,9 @@ namespace AzToolsFramework
|
||||
void GetSelectedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void SetNewComponentId(AZ::ComponentId componentId) override;
|
||||
|
||||
// TickBus
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
// EditorWindowRequestBus overrides
|
||||
void SetEditorUiEnabled(bool enable) override;
|
||||
|
||||
@@ -253,6 +285,10 @@ namespace AzToolsFramework
|
||||
void ContextMenuActionPullFieldData(AZ::Component* parentComponent, InstanceDataNode* fieldNode);
|
||||
void ContextMenuActionSetDataFlag(InstanceDataNode* node, AZ::DataPatch::Flag flag, bool additive);
|
||||
|
||||
void GenerateRowWidgetIndexMapToChildIndex(PropertyRowWidget* parent, int destIndex);
|
||||
void ContextMenuActionMoveItemUp(ComponentEditor* componentEditor, PropertyRowWidget* rowWidget);
|
||||
void ContextMenuActionMoveItemDown(ComponentEditor* componentEditor, PropertyRowWidget* rowWidget);
|
||||
|
||||
/// Given an InstanceDataNode, calculate a DataPatch address relative to the entity.
|
||||
/// @return true if successful.
|
||||
bool GetEntityDataPatchAddress(const InstanceDataNode* componentFieldNode, AZ::DataPatch::AddressType& dataPatchAddressOut, AZ::EntityId* entityIdOut = nullptr) const;
|
||||
@@ -341,8 +377,6 @@ namespace AzToolsFramework
|
||||
QAction* m_actionToMoveComponentsBottom = nullptr;
|
||||
QAction* m_resetToSliceAction = nullptr;
|
||||
|
||||
bool m_isShowingContextMenu = false;
|
||||
|
||||
void CreateActions();
|
||||
void UpdateActions();
|
||||
|
||||
@@ -390,6 +424,10 @@ namespace AzToolsFramework
|
||||
void ResetToSlice();
|
||||
|
||||
bool DoesOwnFocus() const;
|
||||
AZ::u32 GetHeightOfRowAndVisibleChildren(const PropertyRowWidget* row) const;
|
||||
QRect GetWidgetAndVisibleChildrenGlobalRect(const PropertyRowWidget* widget) const;
|
||||
PropertyRowWidget* GetRowWidgetAtSameLevelAfter(PropertyRowWidget* widget) const;
|
||||
PropertyRowWidget* GetRowWidgetAtSameLevelBefore(PropertyRowWidget* widget) const;
|
||||
QRect GetWidgetGlobalRect(const QWidget* widget) const;
|
||||
bool DoesIntersectWidget(const QRect& globalRect, const QWidget* widget) const;
|
||||
bool DoesIntersectSelectedComponentEditor(const QRect& globalRect) const;
|
||||
@@ -445,6 +483,8 @@ namespace AzToolsFramework
|
||||
bool HandleSelectionEvents(QObject* object, QEvent* event);
|
||||
bool m_selectionEventAccepted;
|
||||
|
||||
bool HandleMenuEvent(QObject* object, QEvent* event);
|
||||
|
||||
// drag and drop events
|
||||
QRect GetInflatedRectFromPoint(const QPoint& point, int radius) const;
|
||||
bool GetComponentsAtDropEventPosition(QDropEvent* event, AZ::Entity::ComponentArrayType& targetComponents);
|
||||
@@ -458,8 +498,12 @@ namespace AzToolsFramework
|
||||
|
||||
ComponentEditor* GetReorderDropTarget(const QRect& globalRect) const;
|
||||
bool ResetDrag(QMouseEvent* event);
|
||||
bool FindAllowedRowWidgetReorderDropTarget(const QPoint& globalPos);
|
||||
bool UpdateRowWidgetDrag(const QPoint& localPos, Qt::MouseButtons mouseButtons, const QMimeData* mimeData);
|
||||
PropertyRowWidget* FindPropertyRowWidgetAt(QPoint globalPos);
|
||||
bool UpdateDrag(const QPoint& localPos, Qt::MouseButtons mouseButtons, const QMimeData* mimeData);
|
||||
bool StartDrag(QMouseEvent* event);
|
||||
void EndRowWidgetReorder();
|
||||
bool HandleDrop(QDropEvent* event);
|
||||
bool HandleDropForComponentTypes(QDropEvent* event);
|
||||
bool HandleDropForComponentAssets(QDropEvent* event);
|
||||
@@ -468,6 +512,8 @@ namespace AzToolsFramework
|
||||
bool CanDropForComponentTypes(const QMimeData* mimeData) const;
|
||||
bool CanDropForComponentAssets(const QMimeData* mimeData) const;
|
||||
bool CanDropForAssetBrowserEntries(const QMimeData* mimeData) const;
|
||||
void SetRowWidgetHighlighted(PropertyRowWidget* rowWidget);
|
||||
|
||||
AZStd::vector<AZ::s32> ExtractComponentEditorIndicesFromMimeData(const QMimeData* mimeData) const;
|
||||
ComponentEditorVector GetComponentEditorsFromIndices(const AZStd::vector<AZ::s32>& indices) const;
|
||||
ComponentEditor* GetComponentEditorsFromIndex(const AZ::s32 index) const;
|
||||
@@ -559,6 +605,8 @@ namespace AzToolsFramework
|
||||
|
||||
QIcon m_emptyIcon;
|
||||
QIcon m_clearIcon;
|
||||
QIcon m_dragIcon;
|
||||
QCursor m_dragCursor;
|
||||
|
||||
QStandardItem* m_comboItems[StatusItems];
|
||||
EntityIdSet m_overrideSelectedEntityIds;
|
||||
@@ -566,6 +614,19 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
bool m_prefabsAreEnabled = false;
|
||||
|
||||
// Reordering row widgets within the RPE.
|
||||
static constexpr float MoveFadeSeconds = 0.5f;
|
||||
|
||||
ReorderState m_currentReorderState = ReorderState::Inactive;
|
||||
ComponentEditor* m_reorderRowWidgetEditor = nullptr;
|
||||
InstanceDataNode* m_nodeToMove = nullptr;
|
||||
PropertyRowWidget* m_reorderRowWidget = nullptr;
|
||||
PropertyRowWidget* m_reorderDropTarget = nullptr;
|
||||
DropArea m_reorderDropArea = DropArea::Above;
|
||||
QPixmap m_reorderRowImage;
|
||||
float m_moveFadeSecondsRemaining;
|
||||
AZStd::vector<int> m_indexMapOfMovedRow;
|
||||
|
||||
// When m_initiatingPropertyChangeNotification is set to true, it means this EntityPropertyEditor is
|
||||
// broadcasting a change to all listeners about a property change for a given entity. This is needed
|
||||
// so that we don't update the values twice for this inspector
|
||||
@@ -573,6 +634,9 @@ namespace AzToolsFramework
|
||||
void ConnectToEntityBuses(const AZ::EntityId& entityId);
|
||||
void DisconnectFromEntityBuses(const AZ::EntityId& entityId);
|
||||
|
||||
void BeginMoveRowWidgetFade();
|
||||
void HighlightMovedRowWidget();
|
||||
|
||||
//! Stores a component id to be focused on next time the UI updates.
|
||||
AZStd::optional<AZ::ComponentId> m_newComponentId;
|
||||
|
||||
@@ -594,6 +658,8 @@ namespace AzToolsFramework
|
||||
|
||||
bool SelectedEntitiesAreFromSameSourceSliceEntity() const;
|
||||
|
||||
void DragStopped();
|
||||
|
||||
AZ::Entity* GetSelectedEntityById(AZ::EntityId& entityId) const;
|
||||
};
|
||||
|
||||
|
||||
+10
-9
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "PropertyAudioCtrl.h"
|
||||
#include "PropertyQTConstants.h"
|
||||
#include <UI/PropertyEditor/PropertyAudioCtrl.h>
|
||||
#include <UI/PropertyEditor/PropertyQTConstants.h>
|
||||
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
@@ -34,7 +34,7 @@ namespace AzToolsFramework
|
||||
: QWidget(parent)
|
||||
, m_browseEdit(nullptr)
|
||||
, m_mainLayout(nullptr)
|
||||
, m_propertyType(AudioPropertyType::Invalid)
|
||||
, m_propertyType(AudioPropertyType::NumTypes)
|
||||
{
|
||||
// create the gui
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
@@ -96,7 +96,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != AudioPropertyType::Invalid)
|
||||
if (type != AudioPropertyType::NumTypes)
|
||||
{
|
||||
m_propertyType = type;
|
||||
}
|
||||
@@ -136,10 +136,11 @@ namespace AzToolsFramework
|
||||
|
||||
void AudioControlSelectorWidget::OnOpenAudioControlSelector()
|
||||
{
|
||||
AZStd::string resourceResult;
|
||||
AZStd::string resourceType(GetResourceSelectorNameFromType(m_propertyType));
|
||||
AZStd::string currentValue(m_controlName.toStdString().c_str());
|
||||
EditorRequests::Bus::BroadcastResult(resourceResult, &EditorRequests::Bus::Events::SelectResource, resourceType, currentValue);
|
||||
AZStd::string resourceResult;
|
||||
AudioControlSelectorRequestBus::EventResult(
|
||||
resourceResult, m_propertyType,
|
||||
&AudioControlSelectorRequestBus::Events::SelectResource, currentValue);
|
||||
SetControlName(QString(resourceResult.c_str()));
|
||||
}
|
||||
|
||||
@@ -167,12 +168,12 @@ namespace AzToolsFramework
|
||||
{
|
||||
case AudioPropertyType::Trigger:
|
||||
return { "AudioTrigger" };
|
||||
case AudioPropertyType::Rtpc:
|
||||
return { "AudioRTPC" };
|
||||
case AudioPropertyType::Switch:
|
||||
return { "AudioSwitch" };
|
||||
case AudioPropertyType::SwitchState:
|
||||
return { "AudioSwitchState" };
|
||||
case AudioPropertyType::Rtpc:
|
||||
return { "AudioRTPC" };
|
||||
case AudioPropertyType::Environment:
|
||||
return { "AudioEnvironment" };
|
||||
case AudioPropertyType::Preload:
|
||||
|
||||
+21
@@ -29,6 +29,27 @@ class QMimeData;
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//=============================================================================
|
||||
// Audio Control Selector Request Bus
|
||||
// For connecting UI proper
|
||||
//=============================================================================
|
||||
class AudioControlSelectorRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// EBusTraits
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
using BusIdType = AudioPropertyType;
|
||||
|
||||
virtual AZStd::string SelectResource(AZStd::string_view previousValue)
|
||||
{
|
||||
return previousValue;
|
||||
}
|
||||
};
|
||||
|
||||
using AudioControlSelectorRequestBus = AZ::EBus<AudioControlSelectorRequests>;
|
||||
|
||||
//=============================================================================
|
||||
// Audio Control Selector Widget
|
||||
//=============================================================================
|
||||
|
||||
+5
-5
@@ -18,15 +18,15 @@
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//=========================================================================
|
||||
enum class AudioPropertyType
|
||||
enum class AudioPropertyType : AZ::u32
|
||||
{
|
||||
Invalid = 0,
|
||||
Trigger,
|
||||
Trigger = 0,
|
||||
Rtpc,
|
||||
Switch,
|
||||
SwitchState,
|
||||
Rtpc,
|
||||
Environment,
|
||||
Preload,
|
||||
NumTypes,
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
@@ -40,7 +40,7 @@ namespace AzToolsFramework
|
||||
virtual ~CReflectedVarAudioControl() = default;
|
||||
|
||||
AZStd::string m_controlName;
|
||||
AudioPropertyType m_propertyType = AudioPropertyType::Invalid;
|
||||
AudioPropertyType m_propertyType = AudioPropertyType::NumTypes;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
|
||||
+182
-1
@@ -368,10 +368,15 @@ namespace AzToolsFramework
|
||||
delete m_containerAddButton;
|
||||
}
|
||||
|
||||
this->unsetCursor();
|
||||
|
||||
if ((m_parentRow) && (m_parentRow->IsContainerEditable()))
|
||||
{
|
||||
if (!m_elementRemoveButton)
|
||||
{
|
||||
QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab_release.svg"));
|
||||
this->setCursor(QCursor(icon.pixmap(16), 5, 2));
|
||||
|
||||
static QIcon s_iconRemove(QStringLiteral(":/stylesheet/img/UI20/delete-16.svg"));
|
||||
m_elementRemoveButton = new QToolButton(this);
|
||||
m_elementRemoveButton->setAutoRaise(true);
|
||||
@@ -570,7 +575,12 @@ namespace AzToolsFramework
|
||||
AZ_Assert(m_selectionEnabled, "Property is not selectable");
|
||||
m_isSelected = selected;
|
||||
m_nameLabel->setProperty("selected", selected);
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowWidget::GetSelected()
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
void PropertyRowWidget::SetSelectionEnabled(bool selectionEnabled)
|
||||
{
|
||||
@@ -1395,6 +1405,21 @@ namespace AzToolsFramework
|
||||
return !m_childrenRows.empty();
|
||||
}
|
||||
|
||||
AZ::u32 PropertyRowWidget::GetChildRowCount() const
|
||||
{
|
||||
return static_cast<AZ::u32>(m_childrenRows.size());
|
||||
}
|
||||
|
||||
PropertyRowWidget* PropertyRowWidget::GetChildRowByIndex(AZ::u32 index) const
|
||||
{
|
||||
if (index >= m_childrenRows.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_childrenRows[index];
|
||||
}
|
||||
|
||||
bool PropertyRowWidget::ShouldPreValidatePropertyChange() const
|
||||
{
|
||||
return (m_changeValidators.size() > 0);
|
||||
@@ -1722,6 +1747,162 @@ namespace AzToolsFramework
|
||||
|
||||
return m_parentRow->CanChildrenBeReordered();
|
||||
}
|
||||
|
||||
int PropertyRowWidget::GetIndexInParent() const
|
||||
{
|
||||
if (!GetParentRow())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (AZ::u32 index = 0; index < GetParentRow()->GetChildRowCount(); index++)
|
||||
{
|
||||
if (GetParentRow()->GetChildrenRows()[index] == this)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool PropertyRowWidget::CanMoveUp() const
|
||||
{
|
||||
if (!CanBeReordered())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this != m_parentRow->GetChildRowByIndex(0);
|
||||
}
|
||||
|
||||
bool PropertyRowWidget::CanMoveDown() const
|
||||
{
|
||||
if (!CanBeReordered())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::u32 numChildrenOfParent = m_parentRow->GetChildRowCount();
|
||||
|
||||
return this != m_parentRow->GetChildRowByIndex(numChildrenOfParent - 1);
|
||||
}
|
||||
|
||||
int PropertyRowWidget::GetContainingEditorFrameWidth()
|
||||
{
|
||||
QWidget* parent = parentWidget();
|
||||
|
||||
// Find the first ancestor that can be cast to a QFrame, this will be the RPE.
|
||||
while (!qobject_cast<QFrame*>(parent))
|
||||
{
|
||||
parent = parent->parentWidget();
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The parent of the RPE is the size we want.
|
||||
parent = parent->parentWidget();
|
||||
|
||||
return parent->rect().width();
|
||||
}
|
||||
|
||||
int PropertyRowWidget::GetHeightOfRowAndVisibleChildren()
|
||||
{
|
||||
int height = rect().height();
|
||||
|
||||
if (!GetChildRowCount() || !IsExpanded())
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
for (auto childRow : GetChildrenRows())
|
||||
{
|
||||
height += childRow->GetHeightOfRowAndVisibleChildren();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
int PropertyRowWidget::DrawDragImageAndVisibleChildrenInto(QPainter& painter, int xpos, int ypos)
|
||||
{
|
||||
// Render our image into the given painter.
|
||||
int ystart = ypos;
|
||||
|
||||
render(&painter, QPoint(xpos, ypos));
|
||||
|
||||
if (!GetChildRowCount() || !IsExpanded())
|
||||
{
|
||||
return rect().height();
|
||||
}
|
||||
|
||||
ypos += rect().height();
|
||||
|
||||
// Recursively draw any children.
|
||||
for (auto childRow : GetChildrenRows())
|
||||
{
|
||||
ypos += childRow->DrawDragImageAndVisibleChildrenInto(painter, xpos, ypos);
|
||||
}
|
||||
|
||||
return ypos - ystart;
|
||||
}
|
||||
|
||||
QPixmap PropertyRowWidget::createDragImage(
|
||||
const QColor backgroundColor, const QColor borderColor, const float alpha, DragImageType imageType)
|
||||
{
|
||||
// Make the drag box as wide as the containing editor minus a gap each side for the border.
|
||||
static constexpr int ParentEditorBorderSize = 2;
|
||||
int width = GetContainingEditorFrameWidth() - ParentEditorBorderSize * 2;
|
||||
int height = 0;
|
||||
|
||||
if (imageType == DragImageType::IncludeVisibleChildren)
|
||||
{
|
||||
height = GetHeightOfRowAndVisibleChildren();
|
||||
}
|
||||
else
|
||||
{
|
||||
height = rect().height();
|
||||
}
|
||||
|
||||
const auto dpr = devicePixelRatioF();
|
||||
QPixmap dragImage(width * dpr, height * dpr);
|
||||
dragImage.setDevicePixelRatio(dpr);
|
||||
dragImage.fill(Qt::transparent);
|
||||
|
||||
QRect imageRect = QRect(0, 0, width, height);
|
||||
|
||||
QPainter dragPainter(&dragImage);
|
||||
dragPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
dragPainter.fillRect(imageRect, Qt::transparent);
|
||||
dragPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
dragPainter.setOpacity(alpha);
|
||||
dragPainter.fillRect(imageRect, backgroundColor);
|
||||
|
||||
dragPainter.setOpacity(1.0f);
|
||||
|
||||
int marginWidth = (imageRect.width() - rect().width()) / 2 + ParentEditorBorderSize - 1;
|
||||
|
||||
if (imageType == DragImageType::IncludeVisibleChildren)
|
||||
{
|
||||
DrawDragImageAndVisibleChildrenInto(dragPainter, marginWidth, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
render(&dragPainter, QPoint(marginWidth, 0));
|
||||
}
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(QColor(borderColor));
|
||||
pen.setWidth(1);
|
||||
dragPainter.setPen(pen);
|
||||
dragPainter.drawRect(0, 0, imageRect.width() - 1, imageRect.height() - 1);
|
||||
|
||||
dragPainter.end();
|
||||
|
||||
return dragImage;
|
||||
}
|
||||
}
|
||||
|
||||
#include "UI/PropertyEditor/moc_PropertyRowWidget.cpp"
|
||||
|
||||
+21
@@ -45,6 +45,13 @@ namespace AzToolsFramework
|
||||
Q_PROPERTY(bool appendDefaultLabelToName READ GetAppendDefaultLabelToName WRITE AppendDefaultLabelToName)
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(PropertyRowWidget, AZ::SystemAllocator, 0)
|
||||
|
||||
enum class DragImageType
|
||||
{
|
||||
SingleRow,
|
||||
IncludeVisibleChildren
|
||||
};
|
||||
|
||||
PropertyRowWidget(QWidget* pParent);
|
||||
virtual ~PropertyRowWidget();
|
||||
|
||||
@@ -86,6 +93,9 @@ namespace AzToolsFramework
|
||||
bool GetAppendDefaultLabelToName();
|
||||
void AppendDefaultLabelToName(bool doAppend);
|
||||
|
||||
AZ::u32 GetChildRowCount() const;
|
||||
PropertyRowWidget* GetChildRowByIndex(AZ::u32 index) const;
|
||||
|
||||
AZStd::vector<PropertyRowWidget*>& GetChildrenRows() { return m_childrenRows; }
|
||||
bool HasChildRows() const;
|
||||
|
||||
@@ -124,6 +134,7 @@ namespace AzToolsFramework
|
||||
|
||||
void SetSelectionEnabled(bool selectionEnabled);
|
||||
void SetSelected(bool selected);
|
||||
bool GetSelected();
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
|
||||
@@ -152,9 +163,18 @@ namespace AzToolsFramework
|
||||
bool CanChildrenBeReordered() const;
|
||||
bool CanBeReordered() const;
|
||||
|
||||
int GetIndexInParent() const;
|
||||
bool CanMoveUp() const;
|
||||
bool CanMoveDown() const;
|
||||
|
||||
int GetContainingEditorFrameWidth();
|
||||
QPixmap createDragImage(const QColor backgroundColor, const QColor borderColor, const float alpha, DragImageType imageType);
|
||||
protected:
|
||||
int CalculateLabelWidth() const;
|
||||
|
||||
int GetHeightOfRowAndVisibleChildren();
|
||||
int DrawDragImageAndVisibleChildrenInto(QPainter& painter, int xpos, int ypos);
|
||||
|
||||
bool IsHidden(InstanceDataNode* node) const;
|
||||
|
||||
struct ChangeNotification;
|
||||
@@ -216,6 +236,7 @@ namespace AzToolsFramework
|
||||
bool m_isMultiSizeContainer = false;
|
||||
bool m_isFixedSizeOrSmartPtrContainer = false;
|
||||
bool m_custom = false;
|
||||
bool m_canChildrenBeReordered = false;
|
||||
|
||||
bool m_isSelected = false;
|
||||
bool m_selectionEnabled = false;
|
||||
|
||||
+220
-4
@@ -19,6 +19,7 @@
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QScrollArea>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QPainter>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 'QTextFormat::d': class 'QSharedDataPointer<QTextFormatPrivate>' needs to have dll-interface to be used by clients of class 'QTextFormat'
|
||||
#include <QtWidgets/QInputDialog>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
@@ -1343,7 +1344,7 @@ namespace AzToolsFramework
|
||||
|
||||
// calculate the index/offset of the instance data node in the container
|
||||
// (useful for notifying which element in a vector was modified/removed)
|
||||
static size_t CalculateElementIndexInContainer(
|
||||
static int CalculateElementIndexInContainer(
|
||||
InstanceDataNode* node, void* parentInstanceNode,
|
||||
AZ::SerializeContext::IDataContainer* container, AZStd::vector<void*>& nodeInstancesOut)
|
||||
{
|
||||
@@ -1358,7 +1359,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
size_t elementIndex = 0;
|
||||
int elementIndex = 0;
|
||||
void* elementPtr = nodeInstancesOut.empty() ? nullptr : nodeInstancesOut.front();
|
||||
|
||||
// find the index of the element we are about to remove
|
||||
@@ -1429,7 +1430,7 @@ namespace AzToolsFramework
|
||||
|
||||
// if the element being modified exists in a container, calculate
|
||||
// the index to be passed through to PropertyNotify
|
||||
const auto calculateElementIndex = [](InstanceDataNode* node) -> size_t {
|
||||
const auto calculateElementIndex = [](InstanceDataNode* node) -> int {
|
||||
if (InstanceDataNode* parent = node->GetParent())
|
||||
{
|
||||
if (AZ::SerializeContext::IDataContainer* container = parent->GetClassMetadata()->m_container)
|
||||
@@ -1656,6 +1657,221 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Refresh_EntireTree);
|
||||
}
|
||||
|
||||
InstanceDataNode* ReflectedPropertyEditor::FindContainerNodeForNode(InstanceDataNode* node) const
|
||||
{
|
||||
// Locate the owning container. There may be a level of indirection due to wrappers, such as DynamicSerializableField.
|
||||
InstanceDataNode* pContainerNode = node->GetParent();
|
||||
if (!pContainerNode)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
while (pContainerNode && !pContainerNode->GetClassMetadata()->m_container)
|
||||
{
|
||||
pContainerNode = pContainerNode->GetParent();
|
||||
node = node->GetParent();
|
||||
}
|
||||
|
||||
// Check for pContainerNode again, can happen if a node is deleted during operation.
|
||||
if (!pContainerNode)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (IsParentAssociativeContainer(pContainerNode) && IsPairContainer(pContainerNode))
|
||||
{
|
||||
// Go up one more level to the associative container, we'll remove the pair from that container
|
||||
pContainerNode = pContainerNode->GetParent();
|
||||
node = node->GetParent();
|
||||
}
|
||||
|
||||
AZ_Assert(
|
||||
pContainerNode, "Failed to locate parent container for element \"%s\" of type %s.",
|
||||
node->GetElementMetadata() ? node->GetElementMetadata()->m_name : node->GetClassMetadata()->m_name,
|
||||
node->GetClassMetadata()->m_typeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
return pContainerNode;
|
||||
}
|
||||
|
||||
InstanceDataNode* ReflectedPropertyEditor::GetNodeAtIndex(int index)
|
||||
{
|
||||
if (index >= m_impl->m_widgetsInDisplayOrder.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetNodeFromWidget(m_impl->m_widgetsInDisplayOrder[index]);
|
||||
}
|
||||
|
||||
QSet<PropertyRowWidget*> ReflectedPropertyEditor::GetTopLevelWidgets()
|
||||
{
|
||||
return m_impl->getTopLevelWidgets();
|
||||
}
|
||||
|
||||
void ReflectedPropertyEditor::ChangeNodeIndex(InstanceDataNode* containerNode, InstanceDataNode* node, int fromIndex, int toIndex)
|
||||
{
|
||||
auto container = containerNode->GetElementMetadata()
|
||||
? containerNode->GetElementMetadata()->m_genericClassInfo->GetClassData()->m_container
|
||||
: nullptr;
|
||||
|
||||
if (fromIndex == toIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!container || container->GetAssociativeContainerInterface())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::Uuid typeId = node->GetClassMetadata()->m_typeId;
|
||||
|
||||
if (m_impl->m_ptrNotify)
|
||||
{
|
||||
m_impl->m_ptrNotify->BeforePropertyModified(containerNode);
|
||||
}
|
||||
|
||||
const AZ::SerializeContext::ClassElement* containerClassElement = container->GetElement(container->GetDefaultElementNameCrc());
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
|
||||
|
||||
// Backup the item we're moving.
|
||||
void* srcElement = nullptr;
|
||||
void* destElement = nullptr;
|
||||
|
||||
int destIndex = -1;
|
||||
int srcIndex = fromIndex;
|
||||
|
||||
srcElement = container->GetElementByIndex(containerNode->GetInstance(0), containerClassElement, srcIndex);
|
||||
|
||||
void* tmpBuffer = serializeContext->CloneObject(srcElement, typeId);
|
||||
|
||||
// Shuffle all intervening items up (or down).
|
||||
int indexOffset = (toIndex < fromIndex) ? -1 : 1;
|
||||
|
||||
while (destIndex != toIndex - indexOffset)
|
||||
{
|
||||
destIndex = srcIndex;
|
||||
srcIndex += indexOffset;
|
||||
|
||||
destElement = srcElement;
|
||||
|
||||
srcElement = container->GetElementByIndex(containerNode->GetInstance(0), containerClassElement, srcIndex);
|
||||
|
||||
serializeContext->CloneObjectInplace(destElement, srcElement, typeId);
|
||||
}
|
||||
|
||||
// Now replace the final element with the one backed up previously.
|
||||
destElement = srcElement;
|
||||
|
||||
serializeContext->CloneObjectInplace(destElement, tmpBuffer, typeId);
|
||||
|
||||
if (m_impl->m_ptrNotify)
|
||||
{
|
||||
m_impl->m_ptrNotify->AfterPropertyModified(containerNode);
|
||||
m_impl->m_ptrNotify->SealUndoStack();
|
||||
}
|
||||
|
||||
// Need to refresh any pinned inspectors as well to keep the container state in sync
|
||||
QueueInvalidation(Refresh_Values);
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
|
||||
}
|
||||
|
||||
void ReflectedPropertyEditor::MoveNodeToIndex(InstanceDataNode* node, int index)
|
||||
{
|
||||
InstanceDataNode* pContainerNode = FindContainerNodeForNode(node);
|
||||
|
||||
if (!pContainerNode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::SerializeContext::IDataContainer* container = pContainerNode->GetClassMetadata()->m_container;
|
||||
|
||||
AZStd::vector<void*> nodeInstancesOut;
|
||||
const int elementIndex = CalculateElementIndexInContainer(node, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
|
||||
ChangeNodeIndex(pContainerNode, node, elementIndex, index);
|
||||
}
|
||||
|
||||
void ReflectedPropertyEditor::MoveNodeBefore(InstanceDataNode* nodeToMove, InstanceDataNode* nodeToMoveBefore)
|
||||
{
|
||||
InstanceDataNode* pContainerNode = FindContainerNodeForNode(nodeToMove);
|
||||
InstanceDataNode* pContainerNodeTarget = FindContainerNodeForNode(nodeToMoveBefore);
|
||||
|
||||
if (nodeToMove == nodeToMoveBefore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Can only move nodes within the same parent.
|
||||
if (pContainerNode != pContainerNodeTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::SerializeContext::IDataContainer* container = pContainerNode->GetClassMetadata()->m_container;
|
||||
|
||||
AZStd::vector<void*> nodeInstancesOut;
|
||||
int elementIndex = CalculateElementIndexInContainer(nodeToMove, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
nodeInstancesOut.clear();
|
||||
int elementIndexTarget =
|
||||
CalculateElementIndexInContainer(nodeToMoveBefore, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
|
||||
if (elementIndex < elementIndexTarget)
|
||||
{
|
||||
elementIndexTarget -= 1;
|
||||
}
|
||||
|
||||
ChangeNodeIndex(pContainerNode, nodeToMove, elementIndex, elementIndexTarget);
|
||||
}
|
||||
|
||||
void ReflectedPropertyEditor::MoveNodeAfter(InstanceDataNode* nodeToMove, InstanceDataNode* nodeToMoveBefore)
|
||||
{
|
||||
InstanceDataNode* pContainerNode = FindContainerNodeForNode(nodeToMove);
|
||||
InstanceDataNode* pContainerNodeTarget = FindContainerNodeForNode(nodeToMoveBefore);
|
||||
|
||||
if (nodeToMove == nodeToMoveBefore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Can only move nodes within the same parent.
|
||||
if (pContainerNode != pContainerNodeTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::SerializeContext::IDataContainer* container = pContainerNode->GetClassMetadata()->m_container;
|
||||
|
||||
AZStd::vector<void*> nodeInstancesOut;
|
||||
int elementIndex = CalculateElementIndexInContainer(nodeToMove, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
nodeInstancesOut.clear();
|
||||
int elementIndexTarget =
|
||||
CalculateElementIndexInContainer(nodeToMoveBefore, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
|
||||
if (elementIndex > elementIndexTarget)
|
||||
{
|
||||
elementIndexTarget += 1;
|
||||
}
|
||||
|
||||
ChangeNodeIndex(pContainerNode, nodeToMove, elementIndex, elementIndexTarget);
|
||||
}
|
||||
|
||||
int ReflectedPropertyEditor::GetNodeIndexInContainer(InstanceDataNode* node)
|
||||
{
|
||||
InstanceDataNode* pContainerNode = FindContainerNodeForNode(node);
|
||||
|
||||
AZ::SerializeContext::IDataContainer* container = pContainerNode->GetClassMetadata()->m_container;
|
||||
|
||||
AZStd::vector<void*> nodeInstancesOut;
|
||||
int elementIndex = CalculateElementIndexInContainer(node, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
|
||||
return elementIndex;
|
||||
}
|
||||
|
||||
void ReflectedPropertyEditor::OnPropertyRowRequestContainerRemoveItem(PropertyRowWidget* widget, InstanceDataNode* node)
|
||||
{
|
||||
// Locate the owning container. There may be a level of indirection due to wrappers, such as DynamicSerializableField.
|
||||
@@ -1690,7 +1906,7 @@ namespace AzToolsFramework
|
||||
|
||||
// the index of the element being removed
|
||||
AZStd::vector<void*> nodeInstancesOut;
|
||||
const size_t elementIndex = CalculateElementIndexInContainer(
|
||||
const int elementIndex = CalculateElementIndexInContainer(
|
||||
node, pContainerNode->GetInstance(0), container, nodeInstancesOut);
|
||||
|
||||
// pass the context as the last parameter to actually delete the related data.
|
||||
|
||||
+10
@@ -155,9 +155,19 @@ namespace AzToolsFramework
|
||||
using VisibilityCallback = AZStd::function<void(InstanceDataNode* node, NodeDisplayVisibility& visibility, bool& checkChildVisibility)>;
|
||||
void SetVisibilityCallback(VisibilityCallback callback);
|
||||
|
||||
void MoveNodeToIndex(InstanceDataNode* node, int index);
|
||||
void MoveNodeBefore(InstanceDataNode* nodeToMove, InstanceDataNode* nodeToMoveBefore);
|
||||
void MoveNodeAfter(InstanceDataNode* nodeToMove, InstanceDataNode* nodeToMoveBefore);
|
||||
|
||||
int GetNodeIndexInContainer(InstanceDataNode* node);
|
||||
InstanceDataNode* GetNodeAtIndex(int index);
|
||||
QSet<PropertyRowWidget*> GetTopLevelWidgets();
|
||||
signals:
|
||||
void OnExpansionContractionDone();
|
||||
private:
|
||||
InstanceDataNode* FindContainerNodeForNode(InstanceDataNode* node) const;
|
||||
void ChangeNodeIndex(InstanceDataNode* containerNode, InstanceDataNode* node, int oldIndex, int newIndex);
|
||||
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> m_impl;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ bool CryAssert(const char* szCondition, const char* szFile, unsigned int line, b
|
||||
|
||||
static const int max_len = 4096;
|
||||
static char gs_command_str[4096];
|
||||
static CryLockT<CRYLOCK_RECURSIVE> lock;
|
||||
static AZStd::recursive_mutex lock;
|
||||
|
||||
gEnv->pSystem->OnAssert(szCondition, gs_szMessage, szFile, line);
|
||||
|
||||
@@ -80,7 +80,7 @@ bool CryAssert(const char* szCondition, const char* szFile, unsigned int line, b
|
||||
|
||||
if (!gEnv->bNoAssertDialog && !gEnv->bIgnoreAllAsserts)
|
||||
{
|
||||
CryAutoLock< CryLockT<CRYLOCK_RECURSIVE> > lk (lock);
|
||||
AZStd::scoped_lock lk(lock);
|
||||
snprintf(gs_command_str, max_len, "xterm -geometry 100x20 -n 'Assert Dialog [Linux Launcher]' -T 'Assert Dialog [Linux Launcher]' -e 'BinLinux/assert_term \"%s\" \"%s\" %d \"%s\"; echo \"$?\" > .assert_return'",
|
||||
szCondition, (file_len > 60) ? szFile + (file_len - 61) : szFile, line, gs_szMessage);
|
||||
int ret = system(gs_command_str);
|
||||
|
||||
@@ -70,8 +70,6 @@ bool CryAssert(const char* szCondition, const char* szFile, unsigned int line, b
|
||||
static const int max_len = 4096;
|
||||
static char gs_command_str[4096];
|
||||
|
||||
static CryLockT<CRYLOCK_RECURSIVE> lock;
|
||||
|
||||
gEnv->pSystem->OnAssert(szCondition, gs_szMessage, szFile, line);
|
||||
|
||||
size_t file_len = strlen(szFile);
|
||||
|
||||
@@ -1,186 +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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Public include file for the multi-threading API.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
// Include basic multithread primitives.
|
||||
#include "MultiThread.h"
|
||||
#include "BitFiddling.h"
|
||||
#include <AzCore/std/string/string.h>
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Lock types:
|
||||
//
|
||||
// CRYLOCK_FAST
|
||||
// A fast potentially (non-recursive) mutex.
|
||||
// CRYLOCK_RECURSIVE
|
||||
// A recursive mutex.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
enum CryLockType
|
||||
{
|
||||
CRYLOCK_FAST = 1,
|
||||
CRYLOCK_RECURSIVE = 2,
|
||||
};
|
||||
|
||||
#define CRYLOCK_HAVE_FASTLOCK 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Primitive locks and conditions.
|
||||
//
|
||||
// Primitive locks are represented by instance of class CryLockT<Type>
|
||||
//
|
||||
//
|
||||
template<CryLockType Type>
|
||||
class CryLockT
|
||||
{
|
||||
/* Unsupported lock type. */
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Typedefs.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef CryLockT<CRYLOCK_RECURSIVE> CryCriticalSection;
|
||||
typedef CryLockT<CRYLOCK_FAST> CryCriticalSectionNonRecursive;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryAutoCriticalSection implements a helper class to automatically
|
||||
// lock critical section in constructor and release on destructor.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<class LockClass>
|
||||
class CryAutoLock
|
||||
{
|
||||
private:
|
||||
LockClass* m_pLock;
|
||||
|
||||
CryAutoLock();
|
||||
CryAutoLock(const CryAutoLock<LockClass>&);
|
||||
CryAutoLock<LockClass>& operator = (const CryAutoLock<LockClass>&);
|
||||
|
||||
public:
|
||||
CryAutoLock(LockClass& Lock)
|
||||
: m_pLock(&Lock) { m_pLock->Lock(); }
|
||||
CryAutoLock(const LockClass& Lock)
|
||||
: m_pLock(const_cast<LockClass*>(&Lock)) { m_pLock->Lock(); }
|
||||
~CryAutoLock() { m_pLock->Unlock(); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auto critical section is the most commonly used type of auto lock.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef CryAutoLock<CryCriticalSection> CryAutoCriticalSection;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Threads.
|
||||
|
||||
// Base class for runnable objects.
|
||||
//
|
||||
// A runnable is an object with a Run() and a Cancel() method. The Run()
|
||||
// method should perform the runnable's job. The Cancel() method may be
|
||||
// called by another thread requesting early termination of the Run() method.
|
||||
// The runnable may ignore the Cancel() call, the default implementation of
|
||||
// Cancel() does nothing.
|
||||
class CryRunnable
|
||||
{
|
||||
public:
|
||||
virtual ~CryRunnable() { }
|
||||
virtual void Run() = 0;
|
||||
virtual void Cancel() { }
|
||||
};
|
||||
|
||||
// Class holding information about a thread.
|
||||
//
|
||||
// A reference to the thread information can be obtained by calling GetInfo()
|
||||
// on the CrySimpleThread (or derived class) instance.
|
||||
//
|
||||
// NOTE:
|
||||
// If the code is compiled with NO_THREADINFO defined, then the GetInfo()
|
||||
// method will return a reference to a static dummy instance of this
|
||||
// structure. It is currently undecided if NO_THREADINFO will be defined for
|
||||
// release builds!
|
||||
|
||||
struct CryThreadInfo
|
||||
{
|
||||
// The symbolic name of the thread.
|
||||
//
|
||||
// You may set this name directly or through the SetName() method of
|
||||
// CrySimpleThread (or derived class).
|
||||
AZStd::string m_Name;
|
||||
|
||||
|
||||
// A thread identification number.
|
||||
// The number is unique but architecture specific. Do not assume anything
|
||||
// about that number except for being unique.
|
||||
//
|
||||
// This field is filled when the thread is started (i.e. before the Run()
|
||||
// method or thread routine is called). It is advised that you do not
|
||||
// change this number manually.
|
||||
uint32 m_ID;
|
||||
};
|
||||
|
||||
// Simple thread class.
|
||||
//
|
||||
// CrySimpleThread is a simple wrapper around a system thread providing
|
||||
// nothing but system-level functionality of a thread. There are two typical
|
||||
// ways to use a simple thread:
|
||||
//
|
||||
// 1. Derive from the CrySimpleThread class and provide an implementation of
|
||||
// the Run() (and optionally Cancel()) methods.
|
||||
// 2. Specify a runnable object when the thread is started. The default
|
||||
// runnable type is CryRunnable.
|
||||
//
|
||||
// The Runnable class specfied as the template argument must provide Run()
|
||||
// and Cancel() methods compatible with the following signatures:
|
||||
//
|
||||
// void Runnable::Run();
|
||||
// void Runnable::Cancel();
|
||||
//
|
||||
// If the Runnable does not support cancellation, then the Cancel() method
|
||||
// should do nothing.
|
||||
//
|
||||
// The same instance of CrySimpleThread may be used for multiple thread
|
||||
// executions /in sequence/, i.e. it is valid to re-start the thread by
|
||||
// calling Start() after the thread has been joined by calling WaitForThread().
|
||||
template<class Runnable = CryRunnable>
|
||||
class CrySimpleThread;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Include architecture specific code.
|
||||
#if AZ_LEGACY_CRYCOMMON_TRAIT_USE_PTHREADS
|
||||
#include <CryThread_pthreads.h>
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(WIN32) || defined(WIN64)
|
||||
#include <CryThread_windows.h>
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(CryThread_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
// Put other platform specific includes here!
|
||||
#include <CryThread_dummy.h>
|
||||
#endif
|
||||
|
||||
#if !defined _CRYTHREAD_CONDLOCK_GLITCH
|
||||
typedef CryLockT<CRYLOCK_RECURSIVE> CryMutex;
|
||||
#endif // !_CRYTHREAD_CONDLOCK_GLITCH
|
||||
|
||||
// Include all multithreading containers.
|
||||
#include "MultiThread_Containers.h"
|
||||
@@ -1,29 +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 <CryThread.h>
|
||||
|
||||
// Include architecture specific code.
|
||||
#if defined(LINUX) || defined(APPLE)
|
||||
#include <CryThreadImpl_pthreads.h>
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(WIN32) || defined(WIN64)
|
||||
#include <CryThreadImpl_windows.h>
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(CryThreadImpl_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
// Put other platform specific includes here!
|
||||
#endif
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADIMPL_PTHREADS_H
|
||||
#define CRYINCLUDE_CRYCOMMON_CRYTHREADIMPL_PTHREADS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryThread_pthreads.h"
|
||||
|
||||
AZ_THREAD_LOCAL CrySimpleThreadSelf* CrySimpleThreadSelf::m_Self = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryEvent(Timed) implementation
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEventTimed::Reset()
|
||||
{
|
||||
m_lockNotify.Lock();
|
||||
m_flag = false;
|
||||
m_lockNotify.Unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEventTimed::Set()
|
||||
{
|
||||
m_lockNotify.Lock();
|
||||
m_flag = true;
|
||||
m_cond.Notify();
|
||||
m_lockNotify.Unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEventTimed::Wait()
|
||||
{
|
||||
m_lockNotify.Lock();
|
||||
if (!m_flag)
|
||||
{
|
||||
m_cond.Wait(m_lockNotify);
|
||||
}
|
||||
m_flag = false;
|
||||
m_lockNotify.Unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryEventTimed::Wait(const uint32 timeoutMillis)
|
||||
{
|
||||
bool bResult = true;
|
||||
m_lockNotify.Lock();
|
||||
if (!m_flag)
|
||||
{
|
||||
bResult = m_cond.TimedWait(m_lockNotify, timeoutMillis);
|
||||
}
|
||||
m_flag = false;
|
||||
m_lockNotify.Unlock();
|
||||
return bResult;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CryCriticalSection implementation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef CryLockT<CRYLOCK_RECURSIVE> TCritSecType;
|
||||
|
||||
void CryDeleteCriticalSection(void* cs)
|
||||
{
|
||||
delete ((TCritSecType*)cs);
|
||||
}
|
||||
|
||||
void CryEnterCriticalSection(void* cs)
|
||||
{
|
||||
((TCritSecType*)cs)->Lock();
|
||||
}
|
||||
|
||||
bool CryTryCriticalSection(void* cs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CryLeaveCriticalSection(void* cs)
|
||||
{
|
||||
((TCritSecType*)cs)->Unlock();
|
||||
}
|
||||
|
||||
void CryCreateCriticalSectionInplace(void* pCS)
|
||||
{
|
||||
new (pCS) TCritSecType;
|
||||
}
|
||||
|
||||
void CryDeleteCriticalSectionInplace(void*)
|
||||
{
|
||||
}
|
||||
|
||||
void* CryCreateCriticalSection()
|
||||
{
|
||||
return (void*) new TCritSecType;
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADIMPL_PTHREADS_H
|
||||
@@ -1,345 +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 <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/std/parallel/semaphore.h> // for CreateSemaphore
|
||||
|
||||
struct SThreadNameDesc
|
||||
{
|
||||
DWORD dwType;
|
||||
LPCSTR szName;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
|
||||
AZ_THREAD_LOCAL CrySimpleThreadSelf* CrySimpleThreadSelf::m_Self = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryEvent::CryEvent()
|
||||
{
|
||||
m_handle = (void*)CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryEvent::~CryEvent()
|
||||
{
|
||||
CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEvent::Reset()
|
||||
{
|
||||
ResetEvent(m_handle);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEvent::Set()
|
||||
{
|
||||
SetEvent(m_handle);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEvent::Wait() const
|
||||
{
|
||||
WaitForSingleObject(m_handle, INFINITE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryEvent::Wait(const uint32 timeoutMillis) const
|
||||
{
|
||||
if (WaitForSingleObject(m_handle, timeoutMillis) == WAIT_TIMEOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryLock_WinMutex
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryLock_WinMutex::CryLock_WinMutex()
|
||||
: m_hdl(CreateMutex(NULL, FALSE, NULL)) {}
|
||||
CryLock_WinMutex::~CryLock_WinMutex()
|
||||
{
|
||||
CloseHandle(m_hdl);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryLock_WinMutex::Lock()
|
||||
{
|
||||
WaitForSingleObject(m_hdl, INFINITE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryLock_WinMutex::Unlock()
|
||||
{
|
||||
ReleaseMutex(m_hdl);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryLock_WinMutex::TryLock()
|
||||
{
|
||||
return WaitForSingleObject(m_hdl, 0) != WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryLock_CritSection
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryLock_CritSection::CryLock_CritSection()
|
||||
{
|
||||
InitializeCriticalSection((CRITICAL_SECTION*)&m_cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryLock_CritSection::~CryLock_CritSection()
|
||||
{
|
||||
DeleteCriticalSection((CRITICAL_SECTION*)&m_cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryLock_CritSection::Lock()
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryLock_CritSection::Unlock()
|
||||
{
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryLock_CritSection::TryLock()
|
||||
{
|
||||
return TryEnterCriticalSection((CRITICAL_SECTION*)&m_cs) != FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// most of this is taken from http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryConditionVariable::CryConditionVariable()
|
||||
{
|
||||
m_waitersCount = 0;
|
||||
m_wasBroadcast = 0;
|
||||
m_sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||
InitializeCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
m_waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryConditionVariable::~CryConditionVariable()
|
||||
{
|
||||
CloseHandle(m_sema);
|
||||
DeleteCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
CloseHandle(m_waitersDone);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryConditionVariable::Wait(LockType& lock)
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
m_waitersCount++;
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
|
||||
SignalObjectAndWait(lock._get_win32_handle(), m_sema, INFINITE, FALSE);
|
||||
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
m_waitersCount--;
|
||||
bool lastWaiter = m_wasBroadcast && m_waitersCount == 0;
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
|
||||
if (lastWaiter)
|
||||
{
|
||||
SignalObjectAndWait(m_waitersDone, lock._get_win32_handle(), INFINITE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(lock._get_win32_handle(), INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryConditionVariable::TimedWait(LockType& lock, uint32 millis)
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
m_waitersCount++;
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
|
||||
bool ok = true;
|
||||
if (WAIT_TIMEOUT == SignalObjectAndWait(lock._get_win32_handle(), m_sema, millis, FALSE))
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
m_waitersCount--;
|
||||
bool lastWaiter = m_wasBroadcast && m_waitersCount == 0;
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
|
||||
if (lastWaiter)
|
||||
{
|
||||
SignalObjectAndWait(m_waitersDone, lock._get_win32_handle(), INFINITE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(lock._get_win32_handle(), INFINITE);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryConditionVariable::NotifySingle()
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
bool haveWaiters = m_waitersCount > 0;
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
if (haveWaiters)
|
||||
{
|
||||
ReleaseSemaphore(m_sema, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryConditionVariable::Notify()
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
bool haveWaiters = false;
|
||||
if (m_waitersCount > 0)
|
||||
{
|
||||
m_wasBroadcast = 1;
|
||||
haveWaiters = true;
|
||||
}
|
||||
if (haveWaiters)
|
||||
{
|
||||
ReleaseSemaphore(m_sema, m_waitersCount, 0);
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
WaitForSingleObject(m_waitersDone, INFINITE);
|
||||
m_wasBroadcast = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)&m_waitersCountLock);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CrySemaphore::CrySemaphore(int nMaximumCount, int nInitialCount)
|
||||
{
|
||||
m_Semaphore = (void*)CreateSemaphore(NULL, nInitialCount, nMaximumCount, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CrySemaphore::~CrySemaphore()
|
||||
{
|
||||
CloseHandle((HANDLE)m_Semaphore);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CrySemaphore::Acquire()
|
||||
{
|
||||
WaitForSingleObject((HANDLE)m_Semaphore, INFINITE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CrySemaphore::Release()
|
||||
{
|
||||
ReleaseSemaphore((HANDLE)m_Semaphore, 1, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryFastSemaphore::CryFastSemaphore(int nMaximumCount, int nInitialCount)
|
||||
: m_Semaphore(nMaximumCount)
|
||||
, m_nCounter(nInitialCount)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryFastSemaphore::~CryFastSemaphore()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryFastSemaphore::Acquire()
|
||||
{
|
||||
int nCount = ~0;
|
||||
do
|
||||
{
|
||||
nCount = *const_cast<volatile int*>(&m_nCounter);
|
||||
} while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&m_nCounter), nCount - 1, nCount) != nCount);
|
||||
|
||||
// if the count would have been 0 or below, go to kernel semaphore
|
||||
if ((nCount - 1) < 0)
|
||||
{
|
||||
m_Semaphore.Acquire();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryFastSemaphore::Release()
|
||||
{
|
||||
int nCount = ~0;
|
||||
do
|
||||
{
|
||||
nCount = *const_cast<volatile int*>(&m_nCounter);
|
||||
} while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&m_nCounter), nCount + 1, nCount) != nCount);
|
||||
|
||||
// wake up kernel semaphore if we have waiter
|
||||
if (nCount < 0)
|
||||
{
|
||||
m_Semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CrySimpleThreadSelf::CrySimpleThreadSelf()
|
||||
: m_thread(NULL)
|
||||
, m_threadId(0)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CrySimpleThreadSelf::WaitForThread()
|
||||
{
|
||||
assert(m_thread);
|
||||
PREFAST_ASSUME(m_thread);
|
||||
if (GetCurrentThreadId() != m_threadId)
|
||||
{
|
||||
WaitForSingleObject((HANDLE)m_thread, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
CrySimpleThreadSelf::~CrySimpleThreadSelf()
|
||||
{
|
||||
if (m_thread)
|
||||
{
|
||||
CloseHandle(m_thread);
|
||||
}
|
||||
}
|
||||
|
||||
void CrySimpleThreadSelf::StartThread(unsigned (__stdcall * func)(void*), void* argList)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(CryThreadImpl_windows_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
m_thread = (void*)_beginthreadex(NULL, 0, func, argList, CREATE_SUSPENDED, &m_threadId);
|
||||
#endif
|
||||
assert(m_thread);
|
||||
PREFAST_ASSUME(m_thread);
|
||||
ResumeThread((HANDLE)m_thread);
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREAD_DUMMY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_CRYTHREAD_DUMMY_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryEvent::CryEvent() {}
|
||||
CryEvent::~CryEvent() {}
|
||||
void CryEvent::Reset() {}
|
||||
void CryEvent::Set() {}
|
||||
void CryEvent::Wait() const {}
|
||||
bool CryEvent::Wait(const uint32 timeoutMillis) const {}
|
||||
typedef CryEvent CryEventTimed;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class _DummyLock
|
||||
{
|
||||
public:
|
||||
_DummyLock();
|
||||
|
||||
void Lock();
|
||||
bool TryLock();
|
||||
void Unlock();
|
||||
|
||||
#if defined(AZ_DEBUG_BUILD)
|
||||
bool IsLocked();
|
||||
#endif
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryLock<CRYLOCK_FAST>
|
||||
: public _DummyLock
|
||||
{
|
||||
CryLock(const CryLock<CRYLOCK_FAST>&);
|
||||
void operator = (const CryLock<CRYLOCK_FAST>&);
|
||||
|
||||
public:
|
||||
CryLock();
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryLock<CRYLOCK_RECURSIVE>
|
||||
: public _DummyLock
|
||||
{
|
||||
CryLock(const CryLock<CRYLOCK_RECURSIVE>&);
|
||||
void operator = (const CryLock<CRYLOCK_RECURSIVE>&);
|
||||
|
||||
public:
|
||||
CryLock();
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryCondLock<CRYLOCK_FAST>
|
||||
: public CryLock<CRYLOCK_FAST>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryCondLock<CRYLOCK_RECURSIVE>
|
||||
: public CryLock<CRYLOCK_FAST>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryCond< CryLock<CRYLOCK_FAST> >
|
||||
{
|
||||
typedef CryLock<CRYLOCK_FAST> LockT;
|
||||
CryCond(const CryCond<LockT>&);
|
||||
void operator = (const CryCond<LockT>&);
|
||||
|
||||
public:
|
||||
CryCond();
|
||||
|
||||
void Notify();
|
||||
void NotifySingle();
|
||||
void Wait(LockT&);
|
||||
bool TimedWait(LockT &, uint32);
|
||||
};
|
||||
|
||||
template<>
|
||||
class CryCond< CryLock<CRYLOCK_RECURSIVE> >
|
||||
{
|
||||
typedef CryLock<CRYLOCK_RECURSIVE> LockT;
|
||||
CryCond(const CryCond<LockT>&);
|
||||
void operator = (const CryCond<LockT>&);
|
||||
|
||||
public:
|
||||
CryCond();
|
||||
|
||||
void Notify();
|
||||
void NotifySingle();
|
||||
void Wait(LockT&);
|
||||
bool TimedWait(LockT &, uint32);
|
||||
};
|
||||
|
||||
class _DummyRWLock
|
||||
{
|
||||
public:
|
||||
_DummyRWLock() { }
|
||||
|
||||
void RLock();
|
||||
bool TryRLock();
|
||||
void WLock();
|
||||
bool TryWLock();
|
||||
void Lock() { WLock(); }
|
||||
bool TryLock() { return TryWLock(); }
|
||||
void Unlock();
|
||||
};
|
||||
|
||||
template<class Runnable>
|
||||
class CrySimpleThread
|
||||
: public CryRunnable
|
||||
{
|
||||
public:
|
||||
typedef void (* ThreadFunction)(void*);
|
||||
|
||||
CrySimpleThread();
|
||||
virtual ~CrySimpleThread();
|
||||
#if !defined(NO_THREADINFO)
|
||||
CryThreadInfo& GetInfo();
|
||||
#endif
|
||||
const char* GetName();
|
||||
void SetName(const char*);
|
||||
|
||||
virtual void Run();
|
||||
virtual void Cancel();
|
||||
virtual void Start(Runnable&, unsigned = 0, const char* = NULL);
|
||||
virtual void Start(unsigned = 0, const char* = NULL);
|
||||
void StartFunction(ThreadFunction, void* = NULL, unsigned = 0);
|
||||
|
||||
void Exit();
|
||||
void Join();
|
||||
unsigned SetCpuMask(unsigned);
|
||||
unsigned GetCpuMask();
|
||||
|
||||
void Stop();
|
||||
bool IsStarted() const;
|
||||
bool IsRunning() const;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_CRYTHREAD_DUMMY_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,387 +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 <process.h>
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#undef AZ_RESTRICTED_SECTION
|
||||
#define CRYTHREAD_WINDOWS_H_SECTION_1 1
|
||||
#define CRYTHREAD_WINDOWS_H_SECTION_2 2
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryEvent represent a synchronization event
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CryEvent
|
||||
{
|
||||
public:
|
||||
CryEvent();
|
||||
~CryEvent();
|
||||
|
||||
// Reset the event to the unsignalled state.
|
||||
void Reset();
|
||||
// Set the event to the signalled state.
|
||||
void Set();
|
||||
// Access a HANDLE to wait on.
|
||||
void* GetHandle() const { return m_handle; };
|
||||
// Wait indefinitely for the object to become signalled.
|
||||
void Wait() const;
|
||||
// Wait, with a time limit, for the object to become signalled.
|
||||
bool Wait(const uint32 timeoutMillis) const;
|
||||
|
||||
private:
|
||||
CryEvent(const CryEvent&);
|
||||
CryEvent& operator = (const CryEvent&);
|
||||
|
||||
private:
|
||||
void* m_handle;
|
||||
};
|
||||
|
||||
typedef CryEvent CryEventTimed;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// from winnt.h
|
||||
struct CRY_CRITICAL_SECTION
|
||||
{
|
||||
void* DebugInfo;
|
||||
long LockCount;
|
||||
long RecursionCount;
|
||||
threadID OwningThread;
|
||||
void* LockSemaphore;
|
||||
unsigned long* SpinCount; // force size on 64-bit systems when packed
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// kernel mutex - don't use... use CryMutex instead
|
||||
class CryLock_WinMutex
|
||||
{
|
||||
public:
|
||||
CryLock_WinMutex();
|
||||
~CryLock_WinMutex();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool TryLock();
|
||||
|
||||
void* _get_win32_handle() { return m_hdl; }
|
||||
|
||||
private:
|
||||
CryLock_WinMutex(const CryLock_WinMutex&);
|
||||
CryLock_WinMutex& operator = (const CryLock_WinMutex&);
|
||||
|
||||
private:
|
||||
void* m_hdl;
|
||||
};
|
||||
|
||||
// critical section... don't use... use CryCriticalSection instead
|
||||
class CryLock_CritSection
|
||||
{
|
||||
public:
|
||||
CryLock_CritSection();
|
||||
~CryLock_CritSection();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool TryLock();
|
||||
|
||||
bool IsLocked()
|
||||
{
|
||||
return m_cs.RecursionCount > 0 && m_cs.OwningThread == CryGetCurrentThreadId();
|
||||
}
|
||||
|
||||
private:
|
||||
CryLock_CritSection(const CryLock_CritSection&);
|
||||
CryLock_CritSection& operator = (const CryLock_CritSection&);
|
||||
|
||||
private:
|
||||
CRY_CRITICAL_SECTION m_cs;
|
||||
};
|
||||
|
||||
template <>
|
||||
class CryLockT<CRYLOCK_RECURSIVE>
|
||||
: public CryLock_CritSection
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CryLockT<CRYLOCK_FAST>
|
||||
: public CryLock_CritSection
|
||||
{
|
||||
};
|
||||
class CryMutex
|
||||
: public CryLock_WinMutex
|
||||
{
|
||||
};
|
||||
#define _CRYTHREAD_CONDLOCK_GLITCH 1
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CryConditionVariable
|
||||
{
|
||||
public:
|
||||
typedef CryMutex LockType;
|
||||
|
||||
CryConditionVariable();
|
||||
~CryConditionVariable();
|
||||
void Wait(LockType& lock);
|
||||
bool TimedWait(LockType& lock, uint32 millis);
|
||||
void NotifySingle();
|
||||
void Notify();
|
||||
|
||||
private:
|
||||
CryConditionVariable(const CryConditionVariable&);
|
||||
CryConditionVariable& operator = (const CryConditionVariable&);
|
||||
|
||||
private:
|
||||
int m_waitersCount;
|
||||
CRY_CRITICAL_SECTION m_waitersCountLock;
|
||||
void* m_sema;
|
||||
void* m_waitersDone;
|
||||
size_t m_wasBroadcast;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Platform independet wrapper for a counting semaphore
|
||||
class CrySemaphore
|
||||
{
|
||||
public:
|
||||
CrySemaphore(int nMaximumCount, int nInitialCount = 0);
|
||||
~CrySemaphore();
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
private:
|
||||
void* m_Semaphore;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Platform independet wrapper for a counting semaphore
|
||||
// except that this version uses C-A-S only until a blocking call is needed
|
||||
// -> No kernel call if there are object in the semaphore
|
||||
class CryFastSemaphore
|
||||
{
|
||||
public:
|
||||
CryFastSemaphore(int nMaximumCount, int nInitialCount = 0);
|
||||
~CryFastSemaphore();
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
private:
|
||||
CrySemaphore m_Semaphore;
|
||||
volatile int32 m_nCounter;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CrySimpleThreadSelf
|
||||
{
|
||||
public:
|
||||
CrySimpleThreadSelf();
|
||||
void WaitForThread();
|
||||
virtual ~CrySimpleThreadSelf();
|
||||
protected:
|
||||
void StartThread(unsigned (__stdcall * func)(void*), void* argList);
|
||||
static AZ_THREAD_LOCAL CrySimpleThreadSelf* m_Self;
|
||||
private:
|
||||
CrySimpleThreadSelf(const CrySimpleThreadSelf&);
|
||||
CrySimpleThreadSelf& operator = (const CrySimpleThreadSelf&);
|
||||
protected:
|
||||
void* m_thread;
|
||||
uint32 m_threadId;
|
||||
};
|
||||
|
||||
template<class Runnable>
|
||||
class CrySimpleThread
|
||||
: public CryRunnable
|
||||
, public CrySimpleThreadSelf
|
||||
{
|
||||
public:
|
||||
typedef void (* ThreadFunction)(void*);
|
||||
typedef CryRunnable RunnableT;
|
||||
|
||||
void SetName(const char* Name)
|
||||
{
|
||||
m_name = Name;
|
||||
}
|
||||
const char* GetName() { return m_name; }
|
||||
|
||||
const volatile bool& GetStartedState() const { return m_bIsStarted; }
|
||||
|
||||
private:
|
||||
Runnable* m_Runnable;
|
||||
struct
|
||||
{
|
||||
ThreadFunction m_ThreadFunction;
|
||||
void* m_ThreadParameter;
|
||||
} m_ThreadFunction;
|
||||
volatile bool m_bIsStarted;
|
||||
volatile bool m_bIsRunning;
|
||||
volatile bool m_bCreatedThread;
|
||||
AZStd::string m_name;
|
||||
|
||||
protected:
|
||||
virtual void Terminate()
|
||||
{
|
||||
// This method must be empty.
|
||||
// Derived classes overriding Terminate() are not required to call this
|
||||
// method.
|
||||
}
|
||||
|
||||
private:
|
||||
static unsigned __stdcall RunRunnable(void* thisPtr)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_WINDOWS_H_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE(CryThread_windows_h)
|
||||
#endif
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
|
||||
self->m_Runnable->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->m_bCreatedThread = false;
|
||||
self->Terminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned __stdcall RunThis(void* thisPtr)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_WINDOWS_H_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE(CryThread_windows_h)
|
||||
#endif
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
|
||||
self->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->m_bCreatedThread = false;
|
||||
self->Terminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CrySimpleThread(const CrySimpleThread<Runnable>&);
|
||||
void operator = (const CrySimpleThread<Runnable>&);
|
||||
|
||||
public:
|
||||
CrySimpleThread()
|
||||
: m_bIsStarted(false)
|
||||
, m_bIsRunning(false)
|
||||
, m_bCreatedThread(false)
|
||||
{
|
||||
m_thread = NULL;
|
||||
m_Runnable = NULL;
|
||||
}
|
||||
void* GetHandle() { return m_thread; }
|
||||
|
||||
virtual ~CrySimpleThread()
|
||||
{
|
||||
if (IsStarted())
|
||||
{
|
||||
if (gEnv && gEnv->pLog)
|
||||
{
|
||||
gEnv->pLog->LogError("Runaway thread %p '%s'", m_thread, m_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
Cancel();
|
||||
WaitForThread();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
// This Run() implementation supports the void StartFunction() method.
|
||||
// However, code using this class (or derived classes) should eventually
|
||||
// be refactored to use one of the other Start() methods. This code will
|
||||
// be removed some day and the default implementation of Run() will be
|
||||
// empty.
|
||||
if (m_ThreadFunction.m_ThreadFunction != NULL)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction(m_ThreadFunction.m_ThreadParameter);
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the running thread.
|
||||
//
|
||||
// If the thread class is implemented as a derived class of CrySimpleThread,
|
||||
// then the derived class should provide an appropriate implementation for
|
||||
// this method. Calling the base class implementation is _not_ required.
|
||||
//
|
||||
// If the thread was started by specifying a Runnable (template argument),
|
||||
// then the Cancel() call is passed on to the specified runnable.
|
||||
//
|
||||
// If the thread was started using the StartFunction() method, then the
|
||||
// caller must find other means to inform the thread about the cancellation
|
||||
// request.
|
||||
virtual void Cancel()
|
||||
{
|
||||
if (IsStarted() && m_Runnable != NULL)
|
||||
{
|
||||
m_Runnable->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Start(Runnable& runnable, [[maybe_unused]] unsigned cpuMask = 0, const char* = NULL, int32 = 0)
|
||||
{
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
// Don't start thread more than once!
|
||||
return;
|
||||
}
|
||||
m_Runnable = &runnable;
|
||||
m_bCreatedThread = true;
|
||||
StartThread(RunRunnable, this);
|
||||
}
|
||||
|
||||
virtual void Start([[maybe_unused]] unsigned cpuMask = 0, const char* = NULL, int32 = 0, int32 = 0)
|
||||
{
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
// Don't start thread more than once!
|
||||
return;
|
||||
}
|
||||
m_bCreatedThread = true;
|
||||
StartThread(RunThis, this);
|
||||
}
|
||||
|
||||
void StartFunction(
|
||||
ThreadFunction threadFunction,
|
||||
void* threadParameter = NULL
|
||||
)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction = threadFunction;
|
||||
m_ThreadFunction.m_ThreadParameter = threadParameter;
|
||||
Start();
|
||||
}
|
||||
|
||||
static CrySimpleThread<Runnable>* Self()
|
||||
{
|
||||
return reinterpret_cast<CrySimpleThread<Runnable>*>(m_Self);
|
||||
}
|
||||
|
||||
void Exit()
|
||||
{
|
||||
assert(!"implemented");
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_bIsStarted = false;
|
||||
}
|
||||
|
||||
bool IsStarted() const { return m_bIsStarted; }
|
||||
bool IsRunning() const { return m_bIsRunning; }
|
||||
};
|
||||
@@ -14,7 +14,7 @@
|
||||
#define CRYINCLUDE_CRYCOMMON_IFUNCTORBASE_H
|
||||
#pragma once
|
||||
|
||||
#include <CryCommon/CryThread.h>
|
||||
#include <AzCore/std/parallel/atomic.h>
|
||||
|
||||
// Base class for functor storage.
|
||||
// Not intended for direct usage.
|
||||
@@ -28,19 +28,19 @@ public:
|
||||
|
||||
void AddRef()
|
||||
{
|
||||
CryInterlockedIncrement(&m_nReferences);
|
||||
m_nReferences.fetch_add(1, AZStd::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (CryInterlockedDecrement(&m_nReferences) <= 0)
|
||||
if (m_nReferences.fetch_sub(1, AZStd::memory_order_acq_rel) == 1)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
volatile int m_nReferences;
|
||||
AZStd::atomic_int m_nReferences;
|
||||
};
|
||||
|
||||
// Base Template for specialization.
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// In Mac, including ILog without including platform.h first fails because platform.h
|
||||
// includes CryThread.h which includes CryThread_pthreads.h which uses ILog.
|
||||
// So plaform.h needs the contents of ILog.h.
|
||||
// By including platform.h outside of the guard, we give platform.h the right include order
|
||||
#include <platform.h>
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ILOG_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ILOG_H
|
||||
#pragma once
|
||||
|
||||
@@ -37,7 +37,6 @@ struct IRenderMesh;
|
||||
#include <IXml.h>
|
||||
#include <smartptr.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <CryThread.h>
|
||||
|
||||
#ifdef MAX_SUB_MATERIALS
|
||||
// This checks that the values are in sync in the different files.
|
||||
@@ -433,8 +432,6 @@ struct IMaterial
|
||||
virtual uint32 GetDccMaterialHash() const = 0;
|
||||
virtual void SetDccMaterialHash(uint32 hash) = 0;
|
||||
|
||||
virtual CryCriticalSection& GetSubMaterialResizeLock() = 0;
|
||||
|
||||
virtual void UpdateShaderItems() = 0;
|
||||
|
||||
// </interfuscator:shuffle>
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// In Mac, including ISystem without including platform.h first fails because platform.h
|
||||
// includes CryThread.h which includes CryThread_pthreads.h which uses ISystem (gEnv).
|
||||
// So plaform.h needs the contents of ISystem.h.
|
||||
// By including platform.h outside of the guard, we give platform.h the right include order
|
||||
#include <platform.h> // Needed for LARGE_INTEGER (for consoles).
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ISYSTEM_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ISYSTEM_H
|
||||
#pragma once
|
||||
|
||||
@@ -413,67 +413,12 @@ inline void SetLastError(DWORD dwErrCode) { errno = dwErrCode; }
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern threadID GetCurrentThreadId();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern HANDLE CreateEvent(
|
||||
LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset,
|
||||
BOOL bInitialState,
|
||||
LPCSTR lpName
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern DWORD Sleep(DWORD dwMilliseconds);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern DWORD WaitForSingleObjectEx(
|
||||
HANDLE hHandle,
|
||||
DWORD dwMilliseconds,
|
||||
BOOL bAlertable);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern DWORD WaitForMultipleObjectsEx(
|
||||
DWORD nCount,
|
||||
const HANDLE* lpHandles,
|
||||
BOOL bWaitAll,
|
||||
DWORD dwMilliseconds,
|
||||
BOOL bAlertable);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern BOOL SetEvent(HANDLE hEvent);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern BOOL ResetEvent(HANDLE hEvent);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern HANDLE CreateMutex(
|
||||
LPSECURITY_ATTRIBUTES lpMutexAttributes,
|
||||
BOOL bInitialOwner,
|
||||
LPCSTR lpName
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern BOOL ReleaseMutex(HANDLE hMutex);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef DWORD (* PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
|
||||
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
extern HANDLE CreateThread(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
SIZE_T dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
);
|
||||
|
||||
extern BOOL GetComputerName(LPSTR lpBuffer, LPDWORD lpnSize); //required for CryOnline
|
||||
extern DWORD GetCurrentProcessId(void);
|
||||
|
||||
|
||||
@@ -1,285 +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
|
||||
|
||||
#if defined(APPLE) || defined(LINUX)
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
#include "CryAssert.h"
|
||||
|
||||
// Section dictionary
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define MULTITHREAD_H_SECTION_TRAITS 1
|
||||
#define MULTITHREAD_H_SECTION_DEFINE_CRYINTERLOCKEXCHANGE 2
|
||||
#define MULTITHREAD_H_SECTION_IMPLEMENT_CRYSPINLOCK 3
|
||||
#define MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDADD 4
|
||||
#define MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDADDSIZE 5
|
||||
#define MULTITHREAD_H_SECTION_CRYINTERLOCKEDFLUSHSLIST_PT1 6
|
||||
#define MULTITHREAD_H_SECTION_CRYINTERLOCKEDFLUSHSLIST_PT2 7
|
||||
#define MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDCOMPAREEXCHANGE64 8
|
||||
#endif
|
||||
|
||||
#define WRITE_LOCK_VAL (1 << 16)
|
||||
|
||||
// Traits
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_TRAITS
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
#endif
|
||||
|
||||
void CrySpinLock(volatile int* pLock, int checkVal, int setVal);
|
||||
void CryReleaseSpinLock (volatile int*, int);
|
||||
|
||||
LONG CryInterlockedIncrement(int volatile* lpAddend);
|
||||
LONG CryInterlockedDecrement(int volatile* lpAddend);
|
||||
LONG CryInterlockedOr(LONG volatile* Destination, LONG Value);
|
||||
LONG CryInterlockedExchangeAdd(LONG volatile* lpAddend, LONG Value);
|
||||
LONG CryInterlockedCompareExchange(LONG volatile* dst, LONG exchange, LONG comperand);
|
||||
void* CryInterlockedCompareExchangePointer(void* volatile* dst, void* exchange, void* comperand);
|
||||
void* CryInterlockedExchangePointer (void* volatile* dst, void* exchange);
|
||||
|
||||
void* CryCreateCriticalSection();
|
||||
void CryCreateCriticalSectionInplace(void*);
|
||||
void CryDeleteCriticalSection(void* cs);
|
||||
void CryDeleteCriticalSectionInplace(void* cs);
|
||||
void CryEnterCriticalSection(void* cs);
|
||||
bool CryTryCriticalSection(void* cs);
|
||||
void CryLeaveCriticalSection(void* cs);
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_DEFINE_CRYINTERLOCKEXCHANGE
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
#endif
|
||||
|
||||
ILINE void CrySpinLock(volatile int* pLock, int checkVal, int setVal)
|
||||
{
|
||||
#ifdef _CPU_X86
|
||||
# ifdef __GNUC__
|
||||
int val;
|
||||
__asm__ __volatile__ (
|
||||
"0: mov %[checkVal], %%eax\n"
|
||||
" lock cmpxchg %[setVal], (%[pLock])\n"
|
||||
" jnz 0b"
|
||||
: "=m" (*pLock)
|
||||
: [pLock] "r" (pLock), "m" (*pLock),
|
||||
[checkVal] "m" (checkVal),
|
||||
[setVal] "r" (setVal)
|
||||
: "eax", "cc", "memory"
|
||||
);
|
||||
# else //!__GNUC__
|
||||
__asm
|
||||
{
|
||||
mov edx, setVal
|
||||
mov ecx, pLock
|
||||
Spin:
|
||||
// Trick from Intel Optimizations guide
|
||||
#ifdef _CPU_SSE
|
||||
pause
|
||||
#endif
|
||||
mov eax, checkVal
|
||||
lock cmpxchg [ecx], edx
|
||||
jnz Spin
|
||||
}
|
||||
# endif //!__GNUC__
|
||||
#else // !_CPU_X86
|
||||
# if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_IMPLEMENT_CRYSPINLOCK
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
# endif
|
||||
# if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
# undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
# elif defined(APPLE) || defined(LINUX)
|
||||
// register int val;
|
||||
// __asm__ __volatile__ (
|
||||
// "0: mov %[checkVal], %%eax\n"
|
||||
// " lock cmpxchg %[setVal], (%[pLock])\n"
|
||||
// " jnz 0b"
|
||||
// : "=m" (*pLock)
|
||||
// : [pLock] "r" (pLock), "m" (*pLock),
|
||||
// [checkVal] "m" (checkVal),
|
||||
// [setVal] "r" (setVal)
|
||||
// : "eax", "cc", "memory"
|
||||
// );
|
||||
//while(CryInterlockedCompareExchange((volatile long*)pLock,setVal,checkVal)!=checkVal) ;
|
||||
uint loops = 0;
|
||||
while (__sync_val_compare_and_swap((volatile int32_t*)pLock, (int32_t)checkVal, (int32_t)setVal) != checkVal)
|
||||
{
|
||||
# if !defined (ANDROID) && !defined(IOS)
|
||||
_mm_pause();
|
||||
# endif
|
||||
|
||||
if (!(++loops & 0x7F))
|
||||
{
|
||||
usleep(1); // give threads with other prio chance to run
|
||||
}
|
||||
else if (!(loops & 0x3F))
|
||||
{
|
||||
sched_yield(); // give threads with same prio chance to run
|
||||
}
|
||||
}
|
||||
# else
|
||||
// NOTE: The code below will fail on 64bit architectures!
|
||||
while (_InterlockedCompareExchange((volatile LONG*)pLock, setVal, checkVal) != checkVal)
|
||||
{
|
||||
_mm_pause();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
ILINE void CryReleaseSpinLock(volatile int* pLock, int setVal)
|
||||
{
|
||||
*pLock = setVal;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ILINE void CryInterlockedAdd(volatile int* pVal, int iAdd)
|
||||
{
|
||||
#ifdef _CPU_X86
|
||||
# ifdef __GNUC__
|
||||
__asm__ __volatile__ (
|
||||
" lock add %[iAdd], (%[pVal])\n"
|
||||
: "=m" (*pVal)
|
||||
: [pVal] "r" (pVal), "m" (*pVal), [iAdd] "r" (iAdd)
|
||||
);
|
||||
# else
|
||||
__asm
|
||||
{
|
||||
mov edx, pVal
|
||||
mov eax, iAdd
|
||||
lock add [edx], eax
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
// NOTE: The code below will fail on 64bit architectures!
|
||||
#if defined(_WIN64)
|
||||
_InterlockedExchangeAdd((volatile LONG*)pVal, iAdd);
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDADD
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(APPLE) || defined(LINUX)
|
||||
CryInterlockedExchangeAdd((volatile LONG*)pVal, iAdd);
|
||||
#elif defined(APPLE)
|
||||
OSAtomicAdd32(iAdd, (volatile LONG*)pVal);
|
||||
#else
|
||||
InterlockedExchangeAdd((volatile LONG*)pVal, iAdd);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
ILINE void CryInterlockedAddSize(volatile size_t* pVal, ptrdiff_t iAdd)
|
||||
{
|
||||
#if defined(PLATFORM_64BIT)
|
||||
#if defined(_WIN64)
|
||||
_InterlockedExchangeAdd64((volatile __int64*)pVal, iAdd);
|
||||
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDADDSIZE
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(WIN32)
|
||||
InterlockedExchangeAdd64((volatile LONG64*)pVal, iAdd);
|
||||
#elif defined(APPLE) || defined(LINUX)
|
||||
(void)__sync_fetch_and_add((int64_t*)pVal, (int64_t)iAdd);
|
||||
#else
|
||||
int64 x, n;
|
||||
do
|
||||
{
|
||||
x = (int64) * pVal;
|
||||
n = x + iAdd;
|
||||
}
|
||||
while (CryInterlockedCompareExchange64((volatile int64*)pVal, n, x) != x);
|
||||
#endif
|
||||
#else
|
||||
CryInterlockedAdd((volatile int*)pVal, (int)iAdd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ILINE void CryWriteLock(volatile int* rw)
|
||||
{
|
||||
CrySpinLock(rw, 0, WRITE_LOCK_VAL);
|
||||
}
|
||||
|
||||
ILINE void CryReleaseWriteLock(volatile int* rw)
|
||||
{
|
||||
CryInterlockedAdd(rw, -WRITE_LOCK_VAL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct WriteLock
|
||||
{
|
||||
ILINE WriteLock(volatile int& rw) { CryWriteLock(&rw); prw = &rw; }
|
||||
~WriteLock() { CryReleaseWriteLock(prw); }
|
||||
private:
|
||||
volatile int* prw;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct WriteLockCond
|
||||
{
|
||||
ILINE WriteLockCond(volatile int& rw, int bActive = 1)
|
||||
{
|
||||
if (bActive)
|
||||
{
|
||||
CrySpinLock(&rw, 0, iActive = WRITE_LOCK_VAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
iActive = 0;
|
||||
}
|
||||
prw = &rw;
|
||||
}
|
||||
ILINE WriteLockCond() { prw = &(iActive = 0); }
|
||||
~WriteLockCond()
|
||||
{
|
||||
CryInterlockedAdd(prw, -iActive);
|
||||
}
|
||||
void SetActive(int bActive = 1) { iActive = -bActive & WRITE_LOCK_VAL; }
|
||||
void Release() { CryInterlockedAdd(prw, -iActive); }
|
||||
volatile int* prw;
|
||||
int iActive;
|
||||
};
|
||||
|
||||
|
||||
#if defined(LINUX) || defined(APPLE)
|
||||
ILINE int64 CryInterlockedCompareExchange64(volatile int64* addr, int64 exchange, int64 comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(addr, comperand, exchange);
|
||||
// This is OK, because long is signed int64 on Linux x86_64
|
||||
//return CryInterlockedCompareExchange((volatile long*)addr, (long)exchange, (long)comperand);
|
||||
}
|
||||
#else
|
||||
ILINE int64 CryInterlockedCompareExchange64(volatile int64* addr, int64 exchange, int64 compare)
|
||||
{
|
||||
// forward to system call
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION MULTITHREAD_H_SECTION_IMPLEMENT_CRYINTERLOCKEDCOMPAREEXCHANGE64
|
||||
#include AZ_RESTRICTED_FILE(MultiThread_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
return _InterlockedCompareExchange64((volatile int64*)addr, exchange, compare);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -34,7 +34,7 @@ namespace CryMT
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef std::vector<T, Alloc> container_type;
|
||||
typedef CryAutoCriticalSection AutoLock;
|
||||
typedef AZStd::lock_guard<AZStd::recursive_mutex> AutoLock;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// std::queue interface
|
||||
@@ -46,7 +46,7 @@ namespace CryMT
|
||||
// classic pop function of queue should not be used for thread safety, use try_pop instead
|
||||
//void pop() { AutoLock lock(m_cs); return v.erase(v.begin()); };
|
||||
|
||||
CryCriticalSection& get_lock() const { return m_cs; }
|
||||
AZStd::recursive_mutex& get_lock() const { return m_cs; }
|
||||
|
||||
bool empty() const { AutoLock lock(m_cs); return v.empty(); }
|
||||
int size() const { AutoLock lock(m_cs); return v.size(); }
|
||||
@@ -92,7 +92,7 @@ namespace CryMT
|
||||
}
|
||||
private:
|
||||
container_type v;
|
||||
mutable CryCriticalSection m_cs;
|
||||
mutable AZStd::recursive_mutex m_cs;
|
||||
};
|
||||
}; // namespace CryMT
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "MultiThread.h"
|
||||
#include "CryThread.h"
|
||||
#include <AzCore/std/parallel/spin_mutex.h>
|
||||
|
||||
namespace stl
|
||||
{
|
||||
@@ -52,43 +51,20 @@ namespace stl
|
||||
|
||||
struct PSyncMultiThread
|
||||
{
|
||||
PSyncMultiThread()
|
||||
: _Semaphore(0) {}
|
||||
PSyncMultiThread() {}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
CryWriteLock(&_Semaphore);
|
||||
m_lock.lock();
|
||||
}
|
||||
void Unlock()
|
||||
{
|
||||
CryReleaseWriteLock(&_Semaphore);
|
||||
}
|
||||
int IsLocked() const volatile
|
||||
{
|
||||
return _Semaphore;
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
volatile int _Semaphore;
|
||||
AZStd::spin_mutex m_lock;
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
struct PSyncDebug
|
||||
: public PSyncMultiThread
|
||||
{
|
||||
void Lock()
|
||||
{
|
||||
assert(!IsLocked());
|
||||
PSyncMultiThread::Lock();
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef PSyncNone PSyncDebug;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SYNCHRONIZATION_H
|
||||
|
||||
@@ -923,21 +923,6 @@ threadID GetCurrentThreadId()
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
HANDLE CreateEvent
|
||||
(
|
||||
LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset,
|
||||
BOOL bInitialState,
|
||||
LPCSTR lpName
|
||||
)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "CreateEvent not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD Sleep(DWORD dwMilliseconds)
|
||||
{
|
||||
@@ -1003,95 +988,6 @@ DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "WaitForSingleObjectEx not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD WaitForMultipleObjectsEx(
|
||||
DWORD nCount,
|
||||
const HANDLE* lpHandles,
|
||||
BOOL bWaitAll,
|
||||
DWORD dwMilliseconds,
|
||||
BOOL bAlertable)
|
||||
{
|
||||
//TODO: implement
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "WaitForSingleObject not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BOOL SetEvent(HANDLE hEvent)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "SetEvent not implemented yet");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BOOL ResetEvent(HANDLE hEvent)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "ResetEvent not implemented yet");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
HANDLE CreateMutex
|
||||
(
|
||||
LPSECURITY_ATTRIBUTES lpMutexAttributes,
|
||||
BOOL bInitialOwner,
|
||||
LPCSTR lpName
|
||||
)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "CreateMutex not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BOOL ReleaseMutex(HANDLE hMutex)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "ReleaseMutex not implemented yet");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef DWORD (* PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
|
||||
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
HANDLE CreateThread
|
||||
(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
SIZE_T dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
//TODO: implement
|
||||
CRY_ASSERT_MESSAGE(0, "CreateThread not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(LINUX) || defined(APPLE)
|
||||
BOOL GetComputerName(LPSTR lpBuffer, LPDWORD lpnSize)
|
||||
{
|
||||
@@ -1270,90 +1166,7 @@ int CryMessageBox(const char* lpText, const char* lpCaption, unsigned int uType)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(LINUX) || defined(APPLE) || defined(DEFINE_CRY_INTERLOCKED_INCREMENT)
|
||||
//[K01]: http://www.memoryhole.net/kyle/2007/05/atomic_incrementing.html
|
||||
//http://forums.devx.com/archive/index.php/t-160558.html
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DLL_EXPORT LONG CryInterlockedIncrement(LONG volatile* lpAddend)
|
||||
{
|
||||
/*int r;
|
||||
__asm__ __volatile__ (
|
||||
"lock ; xaddl %0, (%1) \n\t"
|
||||
: "=r" (r)
|
||||
: "r" (lpAddend), "0" (1)
|
||||
: "memory"
|
||||
);
|
||||
return (LONG) (r + 1); */// add, since we get the original value back.
|
||||
return __sync_fetch_and_add(lpAddend, 1) + 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DLL_EXPORT LONG CryInterlockedDecrement(LONG volatile* lpAddend)
|
||||
{
|
||||
/*int r;
|
||||
__asm__ __volatile__ (
|
||||
"lock ; xaddl %0, (%1) \n\t"
|
||||
: "=r" (r)
|
||||
: "r" (lpAddend), "0" (-1)
|
||||
: "memory"
|
||||
);
|
||||
return (LONG) (r - 1); */// subtract, since we get the original value back.
|
||||
return __sync_fetch_and_sub(lpAddend, 1) - 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DLL_EXPORT LONG CryInterlockedExchangeAdd(LONG volatile* lpAddend, LONG Value)
|
||||
{
|
||||
/* LONG r;
|
||||
__asm__ __volatile__ (
|
||||
#if defined(LINUX64) || defined(APPLE) // long is 64 bits on amd64.
|
||||
"lock ; xaddq %0, (%1) \n\t"
|
||||
#else
|
||||
"lock ; xaddl %0, (%1) \n\t"
|
||||
#endif
|
||||
: "=r" (r)
|
||||
: "r" (lpAddend), "0" (Value)
|
||||
: "memory"
|
||||
);
|
||||
return r;*/
|
||||
return __sync_fetch_and_add(lpAddend, Value);
|
||||
}
|
||||
|
||||
DLL_EXPORT LONG CryInterlockedOr(LONG volatile* Destination, LONG Value)
|
||||
{
|
||||
return __sync_fetch_and_or(Destination, Value);
|
||||
}
|
||||
|
||||
DLL_EXPORT LONG CryInterlockedCompareExchange(LONG volatile* dst, LONG exchange, LONG comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(dst, comperand, exchange);
|
||||
/*LONG r;
|
||||
__asm__ __volatile__ (
|
||||
#if defined(LINUX64) || defined(APPLE) // long is 64 bits on amd64.
|
||||
"lock ; cmpxchgq %2, (%1) \n\t"
|
||||
#else
|
||||
"lock ; cmpxchgl %2, (%1) \n\t"
|
||||
#endif
|
||||
: "=a" (r)
|
||||
: "r" (dst), "r" (exchange), "0" (comperand)
|
||||
: "memory"
|
||||
);
|
||||
return r;*/
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORT void* CryInterlockedCompareExchangePointer(void* volatile* dst, void* exchange, void* comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(dst, comperand, exchange);
|
||||
//return (void*)CryInterlockedCompareExchange((long volatile*)dst, (long)exchange, (long)comperand);
|
||||
}
|
||||
|
||||
DLL_EXPORT void* CryInterlockedExchangePointer(void* volatile* dst, void* exchange)
|
||||
{
|
||||
__sync_synchronize();
|
||||
return __sync_lock_test_and_set(dst, exchange);
|
||||
//return (void*)CryInterlockedCompareExchange((long volatile*)dst, (long)exchange, (long)comperand);
|
||||
}
|
||||
#if defined(LINUX) || defined(APPLE)
|
||||
|
||||
threadID CryGetCurrentThreadId()
|
||||
{
|
||||
|
||||
@@ -86,8 +86,6 @@ set(FILES
|
||||
CryPodArray.h
|
||||
CrySizer.h
|
||||
CrySystemBus.h
|
||||
CryThread.h
|
||||
CryThreadImpl.h
|
||||
CryTypeInfo.h
|
||||
CryVersion.h
|
||||
FrameProfiler.h
|
||||
@@ -95,7 +93,6 @@ set(FILES
|
||||
LegacyAllocator.h
|
||||
MetaUtils.h
|
||||
MiniQueue.h
|
||||
MultiThread.h
|
||||
MultiThread_Containers.h
|
||||
NullAudioSystem.h
|
||||
PNoise3.h
|
||||
@@ -152,11 +149,6 @@ set(FILES
|
||||
CryAssert_Mac.h
|
||||
CryLibrary.cpp
|
||||
CryLibrary.h
|
||||
CryThread_dummy.h
|
||||
CryThread_pthreads.h
|
||||
CryThread_windows.h
|
||||
CryThreadImpl_pthreads.h
|
||||
CryThreadImpl_windows.h
|
||||
Linux32Specific.h
|
||||
Linux64Specific.h
|
||||
Linux_Win32Wrapper.h
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
#include <AzCore/std/parallel/spin_mutex.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Physics defines.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -2834,8 +2836,8 @@ struct IGeometry
|
||||
virtual int PointInsideStatus(const Vec3& pt) = 0; // for meshes, will create an auxiliary hashgrid for acceleration
|
||||
// IntersectLocked - the main function for geomtries. pdata1,pdata2,pparams can be 0 - defaults will be assumed.
|
||||
// returns a pointer to an internal thread-specific contact buffer, locked with the lock argument
|
||||
virtual int IntersectLocked(IGeometry* pCollider, geom_world_data* pdata1, geom_world_data* pdata2, intersection_params* pparams, geom_contact*& pcontacts, WriteLockCond& lock) = 0;
|
||||
virtual int IntersectLocked(IGeometry* pCollider, geom_world_data* pdata1, geom_world_data* pdata2, intersection_params* pparams, geom_contact*& pcontacts, WriteLockCond& lock, int iCaller) = 0;
|
||||
virtual int IntersectLocked(IGeometry* pCollider, geom_world_data* pdata1, geom_world_data* pdata2, intersection_params* pparams, geom_contact*& pcontacts, AZStd::spin_mutex& lock) = 0;
|
||||
virtual int IntersectLocked(IGeometry* pCollider, geom_world_data* pdata1, geom_world_data* pdata2, intersection_params* pparams, geom_contact*& pcontacts, AZStd::spin_mutex& lock, int iCaller) = 0;
|
||||
// Intersect - same as Intersect, but doesn't lock pcontacts
|
||||
virtual int Intersect(IGeometry* pCollider, geom_world_data* pdata1, geom_world_data* pdata2, intersection_params* pparams, geom_contact*& pcontacts) = 0;
|
||||
// FindClosestPoint - for non-convex meshes only does local search, doesn't guarantee global minimum
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
#define PRINTF_EMPTY_FORMAT ""
|
||||
#endif
|
||||
|
||||
|
||||
//default stack size for threads, currently only used on pthread platforms
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION PLATFORM_H_SECTION_8
|
||||
@@ -143,14 +142,6 @@
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#elif defined(LINUX) || defined(APPLE)
|
||||
#if !defined(_DEBUG)
|
||||
#define SIMPLE_THREAD_STACK_SIZE_KB (256)
|
||||
#else
|
||||
#define SIMPLE_THREAD_STACK_SIZE_KB (256 * 4)
|
||||
#endif
|
||||
#else
|
||||
#define SIMPLE_THREAD_STACK_SIZE_KB (32)
|
||||
#endif
|
||||
|
||||
#include <AzCore/PlatformDef.h>
|
||||
@@ -199,7 +190,7 @@
|
||||
#elif defined(ANDROID)
|
||||
#include "AndroidSpecific.h"
|
||||
#elif defined(IOS)
|
||||
#include "iOSSpecific.h"
|
||||
#include "iOSSpecific.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -38,10 +38,6 @@ struct SSystemGlobalEnvironment* gEnv = nullptr;
|
||||
#include AZ_RESTRICTED_FILE(platform_impl_h)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// If not in static library.
|
||||
#include <CryThreadImpl.h>
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
void CryPureCallHandler()
|
||||
{
|
||||
@@ -278,111 +274,6 @@ void InitRootDir(char szExeFileName[], uint nExeSize, char szExeRootName[], uint
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG CryInterlockedIncrement(int volatile* lpAddend)
|
||||
{
|
||||
return InterlockedIncrement((volatile LONG*)lpAddend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG CryInterlockedDecrement(int volatile* lpAddend)
|
||||
{
|
||||
return InterlockedDecrement((volatile LONG*)lpAddend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG CryInterlockedExchangeAdd(LONG volatile* lpAddend, LONG Value)
|
||||
{
|
||||
return InterlockedExchangeAdd(lpAddend, Value);
|
||||
}
|
||||
|
||||
LONG CryInterlockedOr(LONG volatile* Destination, LONG Value)
|
||||
{
|
||||
return InterlockedOr(Destination, Value);
|
||||
}
|
||||
|
||||
LONG CryInterlockedCompareExchange(LONG volatile* dst, LONG exchange, LONG comperand)
|
||||
{
|
||||
return InterlockedCompareExchange(dst, exchange, comperand);
|
||||
}
|
||||
|
||||
void* CryInterlockedCompareExchangePointer(void* volatile* dst, void* exchange, void* comperand)
|
||||
{
|
||||
return InterlockedCompareExchangePointer(dst, exchange, comperand);
|
||||
}
|
||||
|
||||
void* CryInterlockedExchangePointer(void* volatile* dst, void* exchange)
|
||||
{
|
||||
return InterlockedExchangePointer(dst, exchange);
|
||||
}
|
||||
|
||||
void CryInterlockedAdd(volatile size_t* pVal, ptrdiff_t iAdd)
|
||||
{
|
||||
#if defined (PLATFORM_64BIT)
|
||||
#if !defined(NDEBUG)
|
||||
size_t v = (size_t)
|
||||
#endif
|
||||
InterlockedAdd64((volatile int64*)pVal, iAdd);
|
||||
#else
|
||||
size_t v = (size_t)CryInterlockedExchangeAdd((volatile long*)pVal, (long)iAdd);
|
||||
v += iAdd;
|
||||
#endif
|
||||
assert((iAdd == 0) || (iAdd < 0 && v < v - (size_t)iAdd) || (iAdd > 0 && v > v - (size_t)iAdd));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void* CryCreateCriticalSection()
|
||||
{
|
||||
CRITICAL_SECTION* pCS = new CRITICAL_SECTION;
|
||||
InitializeCriticalSection(pCS);
|
||||
return pCS;
|
||||
}
|
||||
|
||||
void CryCreateCriticalSectionInplace(void* pCS)
|
||||
{
|
||||
InitializeCriticalSection((CRITICAL_SECTION*)pCS);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryDeleteCriticalSection(void* cs)
|
||||
{
|
||||
CRITICAL_SECTION* pCS = (CRITICAL_SECTION*)cs;
|
||||
if (pCS->LockCount >= 0)
|
||||
{
|
||||
CryFatalError("Critical Section hanging lock");
|
||||
}
|
||||
DeleteCriticalSection(pCS);
|
||||
delete pCS;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryDeleteCriticalSectionInplace(void* cs)
|
||||
{
|
||||
CRITICAL_SECTION* pCS = (CRITICAL_SECTION*)cs;
|
||||
if (pCS->LockCount >= 0)
|
||||
{
|
||||
CryFatalError("Critical Section hanging lock");
|
||||
}
|
||||
DeleteCriticalSection(pCS);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryEnterCriticalSection(void* cs)
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CryTryCriticalSection(void* cs)
|
||||
{
|
||||
return TryEnterCriticalSection((CRITICAL_SECTION*)cs) != 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CryLeaveCriticalSection(void* cs)
|
||||
{
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)cs);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CrySetFileAttributes(const char* lpFileName, uint32 dwFileAttributes)
|
||||
{
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
|
||||
#include <platform.h>
|
||||
#include <type_traits>
|
||||
#include <MultiThread.h>
|
||||
|
||||
void CryFatalError(const char*, ...) PRINTF_PARAMS(1, 2);
|
||||
#if defined(APPLE)
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#include <AzCore/std/parallel/atomic.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// SMART POINTER
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -353,38 +355,32 @@ protected:
|
||||
class CMultiThreadRefCount
|
||||
{
|
||||
public:
|
||||
CMultiThreadRefCount()
|
||||
: m_cnt(0) {}
|
||||
CMultiThreadRefCount() {}
|
||||
virtual ~CMultiThreadRefCount() {}
|
||||
|
||||
inline int AddRef()
|
||||
{
|
||||
return CryInterlockedIncrement(&m_cnt);
|
||||
return m_count.fetch_add(1, AZStd::memory_order_acq_rel) + 1; // because we get the original value back
|
||||
}
|
||||
inline int Release()
|
||||
{
|
||||
const int nCount = CryInterlockedDecrement(&m_cnt);
|
||||
assert(nCount >= 0);
|
||||
const int nCount = m_count.fetch_sub(1, AZStd::memory_order_acq_rel) - 1; // because we get the original value back
|
||||
AZ_Assert(nCount >= 0, "Deleting Reference Counted Object Twice");
|
||||
if (nCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
else if (nCount < 0)
|
||||
{
|
||||
assert(0);
|
||||
CryFatalError("Deleting Reference Counted Object Twice");
|
||||
}
|
||||
return nCount;
|
||||
}
|
||||
|
||||
inline int GetRefCount() const { return m_cnt; }
|
||||
inline int GetRefCount() const { return m_count.load(AZStd::memory_order_acquire); }
|
||||
|
||||
protected:
|
||||
// Allows the memory for the object to be deallocated in the dynamic module where it was originally constructed, as it may use different memory manager (Debug/Release configurations)
|
||||
virtual void DeleteThis() { delete this; }
|
||||
|
||||
private:
|
||||
volatile int m_cnt;
|
||||
AZStd::atomic_int m_count{ 0 };
|
||||
};
|
||||
|
||||
// base class for interfaces implementing reference counting that needs to be thread-safe
|
||||
@@ -405,29 +401,24 @@ public:
|
||||
|
||||
virtual void AddRef()
|
||||
{
|
||||
CryInterlockedIncrement(&m_nRefCounter);
|
||||
m_nRefCounter.fetch_add(1, AZStd::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
virtual void Release()
|
||||
{
|
||||
const int nCount = CryInterlockedDecrement(&m_nRefCounter);
|
||||
assert(nCount >= 0);
|
||||
const int nCount = m_nRefCounter.fetch_sub(1, AZStd::memory_order_acq_rel) - 1; // because we get the original value back
|
||||
AZ_Assert(nCount >= 0, "Deleting Reference Counted Object Twice");
|
||||
if (nCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
else if (nCount < 0)
|
||||
{
|
||||
assert(0);
|
||||
CryFatalError("Deleting Reference Counted Object Twice");
|
||||
}
|
||||
}
|
||||
|
||||
Counter NumRefs() const { return m_nRefCounter; }
|
||||
Counter NumRefs() const { return m_nRefCounter.load(AZStd::memory_order_acquire); }
|
||||
|
||||
protected:
|
||||
|
||||
volatile Counter m_nRefCounter;
|
||||
AZStd::atomic<Counter> m_nRefCounter{ 0 };
|
||||
};
|
||||
|
||||
typedef _i_reference_target<int> _i_reference_target_t;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <AzCore/Debug/StackTracer.h>
|
||||
#include <AzCore/Debug/EventTraceDrillerBus.h>
|
||||
#include <AzCore/std/parallel/spin_mutex.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#define VS_VERSION_INFO 1
|
||||
@@ -153,13 +154,13 @@ void DebugCallStack::SetUserDialogEnable(const bool bUserDialogEnable)
|
||||
DWORD g_idDebugThreads[10];
|
||||
const char* g_nameDebugThreads[10];
|
||||
int g_nDebugThreads = 0;
|
||||
volatile int g_lockThreadDumpList = 0;
|
||||
AZStd::spin_mutex g_lockThreadDumpList;
|
||||
|
||||
void MarkThisThreadForDebugging(const char* name)
|
||||
{
|
||||
EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), name);
|
||||
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
AZStd::scoped_lock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
if (g_nDebugThreads == sizeof(g_idDebugThreads) / sizeof(g_idDebugThreads[0]))
|
||||
{
|
||||
@@ -179,7 +180,7 @@ void MarkThisThreadForDebugging(const char* name)
|
||||
|
||||
void UnmarkThisThreadFromDebugging()
|
||||
{
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
AZStd::scoped_lock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
for (int i = g_nDebugThreads - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user