Merge branch 'development' into TIF/Runtime
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: ar_bug_report.md
|
||||
about: Create a bug for a an issue found in the Automated Review
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
name: Automated Review Bug report
|
||||
about: Create a report when a failure occurs in main branch
|
||||
title: ''
|
||||
labels: 'Automated_Review'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Failed Jenkins Job Information:**
|
||||
The name of the job that failed, job build number, and code snippit of the failure.
|
||||
|
||||
**Attachments**
|
||||
Attach the Jenkins job log as a .txt file and any other relevant information.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -9,20 +9,8 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
#! Adds the --project-path argument to the VS IDE debugger command arguments
|
||||
function(add_vs_debugger_arguments)
|
||||
# Inject the project root into the --project-path argument into the Visual Studio Debugger arguments by defaults
|
||||
list(APPEND app_targets AutomatedTesting.GameLauncher AutomatedTesting.ServerLauncher)
|
||||
list(APPEND app_targets AssetBuilder AssetProcessor AssetProcessorBatch Editor)
|
||||
foreach(app_target IN LISTS app_targets)
|
||||
if (TARGET ${app_target})
|
||||
set_property(TARGET ${app_target} APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${CMAKE_CURRENT_LIST_DIR}\"")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if(NOT PROJECT_NAME)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(AutomatedTesting
|
||||
LANGUAGES C CXX
|
||||
VERSION 1.0.0.0
|
||||
@@ -30,7 +18,6 @@ if(NOT PROJECT_NAME)
|
||||
include(EngineFinder.cmake OPTIONAL)
|
||||
find_package(o3de REQUIRED)
|
||||
o3de_initialize()
|
||||
add_vs_debugger_arguments()
|
||||
else()
|
||||
# Add the project_name to global LY_PROJECTS_TARGET_NAME property
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/project.json" project_json)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:92fae957e7559bc486cf11d454dda4e066c1d25f03f7ff43d76f0869c54fec4e
|
||||
size 41820
|
||||
oid sha256:68193ec6abac0cb04fd9842d540814d31655b8ffd1c5a9ff1086fe800c0c8c72
|
||||
size 40812
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:46eadb0c54b22ef320639c05086abb3df6147623da0a15ff85e52a752c1114b4
|
||||
size 38908
|
||||
oid sha256:bf9aa8e1075a1f1c3e3e15958106e4f79760e37abfc4e87b823712873984cb8d
|
||||
size 19516
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6d032e52065468197a83056aabe8565b4add43e046c3bcd0d838c2f41cb96607
|
||||
size 33420
|
||||
oid sha256:2cf646a0a977c2edc5ee2ab6351ef633f194ce60c59ea3cb8359f71648db668e
|
||||
size 374492
|
||||
|
||||
@@ -49,7 +49,7 @@ class TestViewMenuOptions(EditorTestHelper):
|
||||
view_menu_options = [
|
||||
("Center on Selection",),
|
||||
("Show Quick Access Bar",),
|
||||
("Viewport", "Wireframe"),
|
||||
("Viewport", "Configure Layout"),
|
||||
("Viewport", "Go to Position"),
|
||||
("Viewport", "Center on Selection"),
|
||||
("Viewport", "Go to Location"),
|
||||
|
||||
@@ -89,7 +89,7 @@ class TestMenus(object):
|
||||
expected_lines = [
|
||||
"Center on Selection Action triggered",
|
||||
"Show Quick Access Bar Action triggered",
|
||||
"Wireframe Action triggered",
|
||||
"Configure Layout Action triggered",
|
||||
"Go to Position Action triggered",
|
||||
"Center on Selection Action triggered",
|
||||
"Go to Location Action triggered",
|
||||
|
||||
@@ -41,7 +41,7 @@ def PrefabLevel_OpensLevelWithEntities():
|
||||
EXPECTED_EMPTY_ENTITY_POS = Vector3(10.00, 20.0, 30.0)
|
||||
|
||||
helper.init_idle()
|
||||
helper.open_level("prefab", "PrefabLevel_OpensLevelWithEntities")
|
||||
helper.open_level("Prefab", "PrefabLevel_OpensLevelWithEntities")
|
||||
|
||||
def find_entity(entity_name):
|
||||
searchFilter = entity.SearchFilter()
|
||||
|
||||
@@ -40,6 +40,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Smoke
|
||||
Sandbox
|
||||
)
|
||||
endif()
|
||||
@@ -15,7 +15,7 @@ from automatedtesting_shared.base import TestAutomationBase
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
|
||||
|
||||
@pytest.mark.SUITE_sandbox
|
||||
@pytest.mark.SUITE_smoke
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("level", ["temp_level"])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source": "Levels/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab",
|
||||
"Source": "Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab",
|
||||
"ContainerEntity": {
|
||||
"Id": "Entity_[403811863694]",
|
||||
"Name": "Level",
|
||||
@@ -15,7 +15,8 @@
|
||||
"Component_[13764860261821571747]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 13764860261821571747,
|
||||
"Parent Entity": ""
|
||||
"Parent Entity": "",
|
||||
"Cached World Transform Parent": ""
|
||||
},
|
||||
"Component_[15844324401733835865]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -101,9 +101,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{6AA79EE4-7EC3-5717-87AE-EDD7D886FD7F}"
|
||||
|
||||
@@ -107,9 +107,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -101,9 +101,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"DefaultMaterial": {
|
||||
"SurfaceType": "Default_1"
|
||||
},
|
||||
"MaterialLibrary": {
|
||||
"assetId": {
|
||||
"guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}"
|
||||
|
||||
@@ -9,17 +9,8 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
# Cmake version 3.19 is the minimum version needed for all of Open 3D Engine's supported platforms
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# CMP0111 introduced in 3.19 has a bug that produces the policy to warn every time there is an
|
||||
# INTERFACE IMPORTED library. We use this type of libraries for handling 3rdParty. The rest of
|
||||
# the documentation states that INTERFACE IMPORTED libraries do not require to set locations, but
|
||||
# the policy still warns about it. Issue: https://gitlab.kitware.com/cmake/cmake/-/issues/21470
|
||||
# The issue was fixed in 3.19.1 so we just disable the policy for 3.19
|
||||
if(CMAKE_VERSION VERSION_EQUAL 3.19)
|
||||
cmake_policy(SET CMP0111 OLD)
|
||||
endif()
|
||||
# Cmake version 3.20 is the minimum version needed for all of Open 3D Engine's supported platforms
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
include(cmake/LySet.cmake)
|
||||
include(cmake/Version.cmake)
|
||||
@@ -88,50 +79,51 @@ if(NOT INSTALLED_ENGINE)
|
||||
# Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra
|
||||
# external subdirectories
|
||||
add_engine_json_external_subdirectories()
|
||||
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
|
||||
|
||||
# Loop over the additional external subdirectories and invoke add_subdirectory on them
|
||||
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
|
||||
# Hash the extenal_directory name and append it to the Binary Directory section of add_subdirectory
|
||||
# This is to deal with potential situations where multiple external directories has the same last directory name
|
||||
# For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory
|
||||
file(REAL_PATH ${external_directory} full_directory_path)
|
||||
string(SHA256 full_directory_hash ${full_directory_path})
|
||||
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit
|
||||
# when the external subdirectory contains relative paths of significant length
|
||||
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
|
||||
# Use the last directory as the suffix path to use for the Binary Directory
|
||||
get_filename_component(directory_name ${external_directory} NAME)
|
||||
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
|
||||
endforeach()
|
||||
|
||||
else()
|
||||
ly_find_o3de_packages()
|
||||
endif()
|
||||
|
||||
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
|
||||
|
||||
# Loop over the additional external subdirectories and invoke add_subdirectory on them
|
||||
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
|
||||
# Hash the extenal_directory name and append it to the Binary Directory section of add_subdirectory
|
||||
# This is to deal with potential situations where multiple external directories has the same last directory name
|
||||
# For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory
|
||||
file(REAL_PATH ${external_directory} full_directory_path)
|
||||
string(SHA256 full_directory_hash ${full_directory_path})
|
||||
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit
|
||||
# when the external subdirectory contains relative paths of significant length
|
||||
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
|
||||
# Use the last directory as the suffix path to use for the Binary Directory
|
||||
get_filename_component(directory_name ${external_directory} NAME)
|
||||
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
|
||||
endforeach()
|
||||
|
||||
################################################################################
|
||||
# Post-processing
|
||||
################################################################################
|
||||
# The following steps have to be done after all targets are registered:
|
||||
# Defer generation of the StaticModules.inl file which is needed to create the AZ::Module derived class in monolithic
|
||||
# builds until after all the targets are known
|
||||
ly_delayed_generate_static_modules_inl()
|
||||
|
||||
# 1. Add any dependencies registered via ly_enable_gems
|
||||
ly_enable_gems_delayed()
|
||||
|
||||
# 2. generate a settings registry .setreg file for all ly_add_project_dependencies() and ly_add_target_dependencies() calls
|
||||
# 2. Defer generation of the StaticModules.inl file which is needed to create the AZ::Module derived class in monolithic
|
||||
# builds until after all the targets are known and all the gems are enabled
|
||||
ly_delayed_generate_static_modules_inl()
|
||||
|
||||
# 3. generate a settings registry .setreg file for all ly_add_project_dependencies() and ly_add_target_dependencies() calls
|
||||
# to provide applications with the filenames of gem modules to load
|
||||
# This must be done before ly_delayed_target_link_libraries() as that inserts BUILD_DEPENDENCIES as MANUALLY_ADDED_DEPENDENCIES
|
||||
# if the build dependency is a MODULE_LIBRARY. That would cause a false load dependency to be generated
|
||||
ly_delayed_generate_settings_registry()
|
||||
|
||||
# 3. link targets where the dependency was yet not declared, we need to have the declaration so we do different
|
||||
# 4. link targets where the dependency was yet not declared, we need to have the declaration so we do different
|
||||
# linking logic depending on the type of target
|
||||
ly_delayed_target_link_libraries()
|
||||
|
||||
# 4. generate a registry file for unit testing for platforms that support unit testing
|
||||
# 5. generate a registry file for unit testing for platforms that support unit testing
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_delayed_generate_unit_test_module_registry()
|
||||
endif()
|
||||
|
||||
@@ -140,7 +140,10 @@ typedef uint8 byte;
|
||||
#define STDMETHODCALLTYPE
|
||||
#endif
|
||||
|
||||
#define _ALIGN(num) __attribute__ ((aligned(num)))
|
||||
#define _ALIGN(num) \
|
||||
__attribute__ ((aligned(num))) \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#define _PACK __attribute__ ((packed))
|
||||
|
||||
// Safe memory freeing
|
||||
|
||||
@@ -282,11 +282,9 @@ struct TIntTraits
|
||||
static const size_t nPOS_BITS
|
||||
= sizeof(T) * 8 - bSIGNED;
|
||||
|
||||
static const T nMIN
|
||||
= bSIGNED ? T (T(1) << (T(sizeof(T) * 8 - 1))) : T(0);
|
||||
static const T nMIN = std::numeric_limits<T>::min();
|
||||
|
||||
static const T nMAX
|
||||
= ~nMIN;
|
||||
static const T nMAX = std::numeric_limits<T>::max();
|
||||
};
|
||||
|
||||
template<uint S>
|
||||
|
||||
@@ -1154,13 +1154,13 @@ struct DiskOperationInfo
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiskOperationInfo& operator - (const DiskOperationInfo& rv)
|
||||
DiskOperationInfo operator - (const DiskOperationInfo& rv)
|
||||
{
|
||||
DiskOperationInfo res(*this);
|
||||
return res -= rv;
|
||||
}
|
||||
|
||||
DiskOperationInfo& operator + (const DiskOperationInfo& rv)
|
||||
DiskOperationInfo operator + (const DiskOperationInfo& rv)
|
||||
{
|
||||
DiskOperationInfo res(*this);
|
||||
return res += rv;
|
||||
|
||||
@@ -104,7 +104,10 @@ typedef float FLOAT;
|
||||
#define STDMETHODCALLTYPE
|
||||
#endif
|
||||
|
||||
#define _ALIGN(num) __attribute__ ((aligned(num)))
|
||||
#define _ALIGN(num) \
|
||||
__attribute__ ((aligned(num))) \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#define _PACK __attribute__ ((packed))
|
||||
|
||||
// Safe memory freeing
|
||||
|
||||
@@ -67,7 +67,7 @@ struct CryPakMock
|
||||
MOCK_METHOD1(PoolMalloc, void*(size_t size));
|
||||
MOCK_METHOD1(PoolFree, void(void* p));
|
||||
MOCK_METHOD3(PoolAllocMemoryBlock, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> (size_t nSize, const char* sUsage, size_t nAlign));
|
||||
MOCK_METHOD3(FindFirst, AZ::IO::ArchiveFileIterator(AZStd::string_view pDir, uint32_t nFlags, bool bAllOwUseFileSystem));
|
||||
MOCK_METHOD2(FindFirst, AZ::IO::ArchiveFileIterator(AZStd::string_view pDir, AZ::IO::IArchive::EFileSearchType));
|
||||
MOCK_METHOD1(FindNext, AZ::IO::ArchiveFileIterator(AZ::IO::ArchiveFileIterator handle));
|
||||
MOCK_METHOD1(FindClose, bool(AZ::IO::ArchiveFileIterator));
|
||||
MOCK_METHOD1(GetModificationTime, AZ::IO::IArchive::FileTime(AZ::IO::HandleType f));
|
||||
|
||||
@@ -111,7 +111,9 @@ int64 CryGetTicksPerSec();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _MS_ALIGN(num) __declspec(align(num))
|
||||
#define _MS_ALIGN(num) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
__declspec(align(num))
|
||||
|
||||
#define DEFINE_ALIGNED_DATA(type, name, alignment) _declspec(align(alignment)) type name;
|
||||
#define DEFINE_ALIGNED_DATA_STATIC(type, name, alignment) static _declspec(align(alignment)) type name;
|
||||
|
||||
@@ -93,7 +93,9 @@ int64 CryGetTicksPerSec();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _MS_ALIGN(num) __declspec(align(num))
|
||||
#define _MS_ALIGN(num) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
__declspec(align(num))
|
||||
|
||||
#define DEFINE_ALIGNED_DATA(type, name, alignment) _declspec(align(alignment)) type name;
|
||||
#define DEFINE_ALIGNED_DATA_STATIC(type, name, alignment) static _declspec(align(alignment)) type name;
|
||||
|
||||
@@ -733,12 +733,12 @@ enum ETriState
|
||||
|
||||
// Fallback for Alignment macro of GCC/CLANG (must be after the class definition)
|
||||
#if !defined(_ALIGN)
|
||||
#define _ALIGN(num)
|
||||
#define _ALIGN(num) AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
// Fallback for Alignment macro of MSVC (must be before the class definition)
|
||||
#if !defined(_MS_ALIGN)
|
||||
#define _MS_ALIGN(num)
|
||||
#define _MS_ALIGN(num) AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option")
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
|
||||
@@ -306,8 +306,9 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
|
||||
|
||||
AZStd::unordered_set<AZStd::string> pakList;
|
||||
|
||||
bool allowFileSystem = true;
|
||||
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(search.c_str(), 0, allowFileSystem);
|
||||
const bool allowFileSystem = true;
|
||||
const uint32_t skipPakFiles = 1;
|
||||
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(search.c_str(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskOnly);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
@@ -320,7 +321,7 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
|
||||
{
|
||||
if (AZ::StringFunc::Equal(handle.m_filename.data(), LevelPakName))
|
||||
{
|
||||
// level folder contain pak files like 'level.pak'
|
||||
// level folder contain pak files like 'level.pak'
|
||||
// which we only want to load during level loading.
|
||||
continue;
|
||||
}
|
||||
@@ -351,7 +352,7 @@ void CLevelSystem::ScanFolder(const char* subfolder, bool modFolder)
|
||||
PopulateLevels(search, folder, pPak, modFolder, false);
|
||||
// Load levels outside of the bundles to maintain backward compatibility.
|
||||
PopulateLevels(search, folder, pPak, modFolder, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CLevelSystem::PopulateLevels(
|
||||
@@ -360,7 +361,7 @@ void CLevelSystem::PopulateLevels(
|
||||
{
|
||||
// allow this find first to actually touch the file system
|
||||
// (causes small overhead but with minimal amount of levels this should only be around 150ms on actual DVD Emu)
|
||||
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(searchPattern.c_str(), 0, fromFileSystemOnly);
|
||||
AZ::IO::ArchiveFileIterator handle = pPak->FindFirst(searchPattern.c_str(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskOnly);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
@@ -973,7 +974,7 @@ void CLevelSystem::UnloadLevel()
|
||||
m_lastLevelName.clear();
|
||||
|
||||
SAFE_RELEASE(m_pCurrentLevel);
|
||||
|
||||
|
||||
// Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed).
|
||||
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
|
||||
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace AZ
|
||||
template <typename Type>
|
||||
friend struct AZStd::IntrusivePtrCountPolicy;
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
friend class InstanceDatabase;
|
||||
|
||||
// Pointer to the InstanceDatabase that owns this instance. Will be null if the InstanceData object
|
||||
|
||||
@@ -46,14 +46,22 @@ namespace AZ
|
||||
*/
|
||||
using CreateFunction = AZStd::function<Instance<Type>(AssetData*)>;
|
||||
|
||||
using CreateFunctionWithParam = AZStd::function<Instance<Type>(AssetData*, const AZStd::any* param)>;
|
||||
|
||||
/**
|
||||
* Deletion takes an asset as input and transfers ownership to the method.
|
||||
*/
|
||||
using DeleteFunction = AZStd::function<void(Type*)>;
|
||||
|
||||
/// [Required] The function to use when creating an instance.
|
||||
/// The system will assert if no creation function is provided.
|
||||
CreateFunction m_createFunction;
|
||||
/// A function to use when creating an instance.
|
||||
/// The system will assert if both @m_createFunction and @m_createFunctionWithParam
|
||||
/// creation functions are invalid.
|
||||
CreateFunction m_createFunction = nullptr;
|
||||
|
||||
/// A function with an additional custom param to use when creating an instance.
|
||||
/// The system will assert if both @m_createFunction and @m_createFunctionWithParam
|
||||
/// creation functions are invalid.
|
||||
CreateFunctionWithParam m_createFunctionWithParam = nullptr;
|
||||
|
||||
/// [Optional] The function to use when deleting an instance.
|
||||
DeleteFunction m_deleteFunction = [](Type* t) { delete t; };
|
||||
@@ -156,28 +164,14 @@ namespace AZ
|
||||
* Use this function when creating an InstanceDatabase that will handle concrete classes of @ref Type.
|
||||
* \param assetType - All instances will be based on subclasses of this asset type.
|
||||
* \param handler - An InstanceHandler that creates instances of @ref assetType assets.
|
||||
* \param checkAssetIds - If true, it will be validated that "instance->m_assetId == asset.GetId()"
|
||||
*/
|
||||
static void Create(const AssetType& assetType, const InstanceHandler<Type>& handler);
|
||||
|
||||
/**
|
||||
* Create the InstanceDatabase with no handlers. Individual handlers must be added using @ref AddHandler().
|
||||
* Use this function when creating an InstanceDatabase that will handle subclasses of @ref Type.
|
||||
* \param assetType - All instances will be based on subclasses of this asset type.
|
||||
*/
|
||||
static void Create(const AssetType& assetType);
|
||||
static void Create(const AssetType& assetType, const InstanceHandler<Type>& handler, bool checkAssetIds = true);
|
||||
|
||||
static void Destroy();
|
||||
static bool IsReady();
|
||||
static InstanceDatabase& Instance();
|
||||
|
||||
/**
|
||||
* Add an InstanceHandler that will create instances for assets of type @ref assetType.
|
||||
*/
|
||||
void AddHandler(const AssetType& assetType, const InstanceHandler<Type>& handler);
|
||||
void AddHandler(const AssetType& assetType, typename InstanceHandler<Type>::CreateFunction createFunction);
|
||||
|
||||
void RemoveHandler(const AssetType& assetType);
|
||||
|
||||
/**
|
||||
* Attempts to find an instance associated with the provided id. If the instance exists, it
|
||||
* is returned. If no instance is found, nullptr is returned. If is safe to call this from
|
||||
@@ -205,18 +199,20 @@ namespace AZ
|
||||
* when acquiring an instance.
|
||||
* @return Returns a smart pointer to the instance, which was either found or created.
|
||||
*/
|
||||
Data::Instance<Type> FindOrCreate(const InstanceId& id, const Asset<AssetData>& asset);
|
||||
Data::Instance<Type> FindOrCreate(const InstanceId& id, const Asset<AssetData>& asset, const AZStd::any* param = nullptr);
|
||||
|
||||
//! Calls the above FindOrCreate using an InstanceId created from the asset
|
||||
Data::Instance<Type> FindOrCreate(const Asset<AssetData>& asset);
|
||||
Data::Instance<Type> FindOrCreate(const Asset<AssetData>& asset, const AZStd::any* param = nullptr);
|
||||
|
||||
//! Calls FindOrCreate using a random InstanceId
|
||||
Data::Instance<Type> Create(const Asset<AssetData>& asset);
|
||||
Data::Instance<Type> Create(const Asset<AssetData>& asset, const AZStd::any* param = nullptr);
|
||||
|
||||
private:
|
||||
InstanceDatabase(const AssetType& assetType);
|
||||
~InstanceDatabase();
|
||||
|
||||
bool m_checkAssetIds = true;
|
||||
//useAssetTypeAsKeyForHandlers;
|
||||
static const char* GetEnvironmentName();
|
||||
|
||||
// Utility function called by InstanceData to remove the instance from the database.
|
||||
@@ -224,11 +220,7 @@ namespace AZ
|
||||
|
||||
void ValidateSameAsset(InstanceData* instance, const Data::Asset<AssetData>& asset) const;
|
||||
|
||||
// Performs a thread-safe search for the InstanceHandler for a given asset type.
|
||||
bool FindHandler(const AssetType& assetType, InstanceHandler<Type>& handlerOut);
|
||||
|
||||
mutable AZStd::shared_mutex m_handlersMutex;
|
||||
AZStd::unordered_map<AssetType, InstanceHandler<Type>> m_handlers;
|
||||
InstanceHandler<Type> m_instanceHandler;
|
||||
|
||||
// m_database uses a recursive_mutex instead of a shared_mutex because it's possible to recursively
|
||||
// create or destroy instances on the same thread while in the midst of creating or destroying an instance.
|
||||
@@ -241,10 +233,11 @@ namespace AZ
|
||||
static EnvironmentVariable<InstanceDatabase*> ms_instance;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
EnvironmentVariable<InstanceDatabase<Type>*> InstanceDatabase<Type>::ms_instance = nullptr;
|
||||
template<typename Type>
|
||||
EnvironmentVariable<InstanceDatabase<Type>*>
|
||||
InstanceDatabase<Type>::ms_instance = nullptr;
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
InstanceDatabase<Type>::~InstanceDatabase()
|
||||
{
|
||||
#ifdef AZ_DEBUG_BUILD
|
||||
@@ -261,52 +254,7 @@ namespace AZ
|
||||
"AZ::Data::%s still has active references.", Type::GetDatabaseName());
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::AddHandler(const AssetType& assetType, const InstanceHandler<Type>& handler)
|
||||
{
|
||||
AZ_Assert(handler.m_createFunction, "You are required to provide a create function to InstanceDatabase.");
|
||||
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_handlersMutex);
|
||||
auto result = m_handlers.emplace(assetType, handler);
|
||||
AZ_Assert(result.second, "An InstanceHandler already exists for this AssetType");
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::AddHandler(const AssetType& assetType, typename InstanceHandler<Type>::CreateFunction createFunction)
|
||||
{
|
||||
InstanceHandler<Type> instanceHandler;
|
||||
instanceHandler.m_createFunction = createFunction;
|
||||
|
||||
AddHandler(assetType, instanceHandler);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::RemoveHandler(const AssetType& assetType)
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_handlersMutex);
|
||||
m_handlers.erase(assetType);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
bool InstanceDatabase<Type>::FindHandler(const AssetType& assetType, InstanceHandler<Type>& handlerOut)
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_handlersMutex);
|
||||
|
||||
auto handlerIter = m_handlers.find(assetType);
|
||||
if (handlerIter != m_handlers.end())
|
||||
{
|
||||
// Since the handler is just a couple pointers, we copy the handler so we can
|
||||
// release the lock right away.
|
||||
handlerOut = handlerIter->second;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::Find(const InstanceId& id) const
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> lock(m_databaseMutex);
|
||||
@@ -318,8 +266,9 @@ namespace AZ
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::FindOrCreate(const InstanceId& id, const Asset<AssetData>& asset)
|
||||
template<typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::FindOrCreate(
|
||||
const InstanceId& id, const Asset<AssetData>& asset, const AZStd::any* param)
|
||||
{
|
||||
if (!id.IsValid())
|
||||
{
|
||||
@@ -358,24 +307,6 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
if (!azrtti_istypeof(m_baseAssetType, assetLocal.Get()))
|
||||
{
|
||||
InstanceHandler<Type> instanceHandler;
|
||||
|
||||
// If a handler was incorrectly registered for an unrelated asset type, this is the
|
||||
// first chance we have to discover that fact, because up until now all we had was two
|
||||
// TypeIds.
|
||||
if (FindHandler(assetLocal.GetType(), instanceHandler))
|
||||
{
|
||||
AZ_Assert(false, "An InstanceHandler was added for asset type %s which is not a subclass of the base asset type %s.",
|
||||
assetLocal.GetType().ToString<AZStd::string>().data(),
|
||||
m_baseAssetType.ToString<AZStd::string>().data()
|
||||
);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Take a lock to guard the insertion. Note that this will not guard against recursive insertions on the same thread.
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> lock(m_databaseMutex);
|
||||
|
||||
@@ -390,48 +321,46 @@ namespace AZ
|
||||
}
|
||||
|
||||
// Emplace a new instance and return it.
|
||||
InstanceHandler<Type> instanceHandler;
|
||||
if (FindHandler(assetLocal.GetType(), instanceHandler))
|
||||
// It's possible for the m_createFunction call to recursively trigger another FindOrCreate call, so be aware that
|
||||
// the contents of m_database may change within this call.
|
||||
Data::Instance<Type> instance = nullptr;
|
||||
if (!param)
|
||||
{
|
||||
// It's possible for the m_createFunction call to recursively trigger another FindOrCreate call, so be aware that
|
||||
// the contents of m_database may change within this call.
|
||||
Data::Instance<Type> instance = instanceHandler.m_createFunction(assetLocal.Get());
|
||||
if (instance)
|
||||
{
|
||||
AZ_Assert(m_database.find(id) == m_database.end(),
|
||||
"Instance creation for asset id %s resulted in a recursive creation of that asset, which was unexpected. "
|
||||
"This asset might be erroneously referencing itself as a dependent asset.", id.ToString<AZStd::string>().c_str());
|
||||
|
||||
instance->m_id = id;
|
||||
instance->m_parentDatabase = this;
|
||||
instance->m_assetId = assetLocal.GetId();
|
||||
instance->m_assetType = assetLocal.GetType();
|
||||
m_database.emplace(id, instance.get());
|
||||
}
|
||||
return AZStd::move(instance);
|
||||
instance = m_instanceHandler.m_createFunction(assetLocal.Get());
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(
|
||||
"InstanceDatabase", false,
|
||||
"No InstanceHandler found for asset type %s", assetLocal.GetType().ToString<AZStd::string>().data());
|
||||
return nullptr;
|
||||
instance = m_instanceHandler.m_createFunctionWithParam(assetLocal.Get(), param);
|
||||
}
|
||||
|
||||
if (instance)
|
||||
{
|
||||
AZ_Assert(m_database.find(id) == m_database.end(),
|
||||
"Instance creation for asset id %s resulted in a recursive creation of that asset, which was unexpected. "
|
||||
"This asset might be erroneously referencing itself as a dependent asset.", id.ToString<AZStd::string>().c_str());
|
||||
|
||||
instance->m_id = id;
|
||||
instance->m_parentDatabase = this;
|
||||
instance->m_assetId = assetLocal.GetId();
|
||||
instance->m_assetType = assetLocal.GetType();
|
||||
m_database.emplace(id, instance.get());
|
||||
}
|
||||
return AZStd::move(instance);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::FindOrCreate(const Asset<AssetData>& asset)
|
||||
template<typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::FindOrCreate(const Asset<AssetData>& asset, const AZStd::any* param)
|
||||
{
|
||||
return FindOrCreate(Data::InstanceId::CreateFromAssetId(asset.GetId()), asset);
|
||||
return FindOrCreate(Data::InstanceId::CreateFromAssetId(asset.GetId()), asset, param);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::Create(const Asset<AssetData>& asset)
|
||||
template<typename Type>
|
||||
Data::Instance<Type> InstanceDatabase<Type>::Create(const Asset<AssetData>& asset, const AZStd::any* param)
|
||||
{
|
||||
return FindOrCreate(Data::InstanceId::CreateRandom(), asset);
|
||||
return FindOrCreate(Data::InstanceId::CreateRandom(), asset, param);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::ReleaseInstance(InstanceData* instance, const InstanceId& instanceId)
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> lock(m_databaseMutex);
|
||||
@@ -447,22 +376,13 @@ namespace AZ
|
||||
instance->m_useCount.compare_exchange_strong(expectedRefCount, -1))
|
||||
{
|
||||
m_database.erase(instance->GetId());
|
||||
|
||||
InstanceHandler<Type> instanceHandler;
|
||||
if (FindHandler(instance->GetAssetType(), instanceHandler))
|
||||
{
|
||||
instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false,
|
||||
"Cannot delete Instance. No InstanceHandler found for asset type %s", instance->GetAssetType().ToString<AZStd::string>().data());
|
||||
}
|
||||
m_instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::ValidateSameAsset(InstanceData* instance, const Data::Asset<AssetData>& asset) const
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::ValidateSameAsset(
|
||||
InstanceData* instance, const Data::Asset<AssetData>& asset) const
|
||||
{
|
||||
/**
|
||||
* The following validation layer is disabled in release, but is designed to catch a couple related edge cases
|
||||
@@ -476,46 +396,47 @@ namespace AZ
|
||||
*/
|
||||
|
||||
#if defined (AZ_DEBUG_BUILD)
|
||||
AZ_Error("InstanceDatabase", instance->m_assetId == asset.GetId(),
|
||||
"InstanceDatabase::FindOrCreate found the requested instance, but a different asset was used to create it. "
|
||||
"Instances of a specific id should be acquired using the same asset. Either make sure the instance id "
|
||||
"is actually unique, or that you are using the same asset each time for that particular id.");
|
||||
if (m_checkAssetIds)
|
||||
{
|
||||
AZ_Error(
|
||||
"InstanceDatabase", (instance->m_assetId == asset.GetId()),
|
||||
"InstanceDatabase::FindOrCreate found the requested instance, but a different asset was used to create it. "
|
||||
"Instances of a specific id should be acquired using the same asset. Either make sure the instance id "
|
||||
"is actually unique, or that you are using the same asset each time for that particular id.");
|
||||
}
|
||||
#else
|
||||
AZ_UNUSED(instance);
|
||||
AZ_UNUSED(asset);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
InstanceDatabase<Type>::InstanceDatabase(const AssetType& assetType)
|
||||
: m_baseAssetType(assetType)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::Create(const AssetType& assetType)
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::Create(const AssetType& assetType, const InstanceHandler<Type>& handler, bool checkAssetIds)
|
||||
{
|
||||
AZ_Assert(!ms_instance || !ms_instance.Get(), "InstanceDatabase already created!");
|
||||
|
||||
if (!ms_instance)
|
||||
{
|
||||
ms_instance = Environment::CreateVariable<InstanceDatabase*>(GetEnvironmentName());
|
||||
ms_instance = Environment::CreateVariable<InstanceDatabase<Type>*>(GetEnvironmentName());
|
||||
}
|
||||
|
||||
if (!ms_instance.Get())
|
||||
{
|
||||
ms_instance.Set(aznew InstanceDatabase<Type>(assetType));
|
||||
}
|
||||
|
||||
AZ_Assert(handler.m_createFunction || handler.m_createFunctionWithParam, "At least one create function must be valid");
|
||||
ms_instance.Get()->m_instanceHandler = handler;
|
||||
ms_instance.Get()->m_checkAssetIds = checkAssetIds;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void InstanceDatabase<Type>::Create(const AssetType& assetType, const InstanceHandler<Type>& handler)
|
||||
{
|
||||
Create(assetType);
|
||||
Instance().AddHandler(assetType, handler);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::Destroy()
|
||||
{
|
||||
AZ_Assert(ms_instance, "InstanceDatabase not created!");
|
||||
@@ -523,7 +444,7 @@ namespace AZ
|
||||
*ms_instance = nullptr;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
bool InstanceDatabase<Type>::IsReady()
|
||||
{
|
||||
if (!ms_instance)
|
||||
@@ -534,7 +455,7 @@ namespace AZ
|
||||
return ms_instance && *ms_instance;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
InstanceDatabase<Type>& InstanceDatabase<Type>::Instance()
|
||||
{
|
||||
if (!ms_instance)
|
||||
@@ -546,10 +467,12 @@ namespace AZ
|
||||
return *(*ms_instance);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
const char* InstanceDatabase<Type>::GetEnvironmentName()
|
||||
{
|
||||
static_assert(HasInstanceDatabaseName<Type>::value, "All classes used as instances in an InstanceDatabase need to define AZ_INSTANCE_DATA in the class.");
|
||||
static_assert(
|
||||
HasInstanceDatabaseName<Type>::value,
|
||||
"All classes used as instances in an InstanceDatabase need to define AZ_INSTANCE_DATA in the class.");
|
||||
return Type::GetDatabaseName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ namespace UnitTest
|
||||
static const AssetId s_assetId3{ Uuid("{D9CDAB04-D206-431E-BDC0-1DD615D56197}") };
|
||||
|
||||
// test asset type
|
||||
class TestAssetType
|
||||
: public AssetData
|
||||
class TestAssetType : public AssetData
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TestAssetType, AZ::SystemAllocator, 0);
|
||||
@@ -47,30 +46,30 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class TestInstanceA
|
||||
: public InstanceData
|
||||
class TestInstanceA : public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(TestInstanceA, "{65CBF1C8-F65F-4A84-8A11-B510BC435DB0}");
|
||||
AZ_CLASS_ALLOCATOR(TestInstanceA, AZ::SystemAllocator, 0);
|
||||
|
||||
TestInstanceA(TestAssetType* asset)
|
||||
: m_asset{asset, AZ::Data::AssetLoadBehavior::Default}
|
||||
{}
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{
|
||||
}
|
||||
|
||||
Asset<TestAssetType> m_asset;
|
||||
};
|
||||
|
||||
class TestInstanceB
|
||||
: public InstanceData
|
||||
class TestInstanceB : public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(TestInstanceB, "{4ED0A8BF-7800-44B2-AC73-2CB759C61C37}");
|
||||
AZ_CLASS_ALLOCATOR(TestInstanceB, AZ::SystemAllocator, 0);
|
||||
|
||||
TestInstanceB(TestAssetType* asset)
|
||||
: m_asset{asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{}
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{
|
||||
}
|
||||
|
||||
~TestInstanceB()
|
||||
{
|
||||
@@ -86,8 +85,7 @@ namespace UnitTest
|
||||
|
||||
// test asset handler
|
||||
template<typename AssetDataT>
|
||||
class MyAssetHandler
|
||||
: public AssetHandler
|
||||
class MyAssetHandler : public AssetHandler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(MyAssetHandler, AZ::SystemAllocator, 0);
|
||||
@@ -120,13 +118,12 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class InstanceDatabaseTest
|
||||
: public AllocatorsFixture
|
||||
class InstanceDatabaseTest : public AllocatorsFixture
|
||||
{
|
||||
protected:
|
||||
MyAssetHandler<TestAssetType>* m_assetHandler;
|
||||
public:
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
@@ -200,7 +197,7 @@ namespace UnitTest
|
||||
|
||||
AZStd::vector<Uuid> guids;
|
||||
AZStd::vector<Asset<TestAssetType>> assets;
|
||||
|
||||
|
||||
for (size_t i = 0; i < assetIdCount; ++i)
|
||||
{
|
||||
Uuid guid = Uuid::CreateRandom();
|
||||
@@ -211,7 +208,6 @@ namespace UnitTest
|
||||
assets.emplace_back(assetManager.CreateAsset<TestAssetType>(guid, AZ::Data::AssetLoadBehavior::Default));
|
||||
}
|
||||
|
||||
|
||||
AZStd::vector<AZStd::thread> threads;
|
||||
AZStd::mutex mutex;
|
||||
AZStd::atomic<int> threadCount((int)threadCountMax);
|
||||
@@ -232,27 +228,29 @@ namespace UnitTest
|
||||
|
||||
for (size_t i = 0; i < threadCountMax; ++i)
|
||||
{
|
||||
threads.emplace_back([&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
{
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
while(timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
threads.emplace_back(
|
||||
[&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
const Uuid uuid = guids[index];
|
||||
const InstanceId instanceId{uuid};
|
||||
const AssetId assetId{uuid};
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
Instance<TestInstanceA> instance = instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
}
|
||||
while (timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
const Uuid uuid = guids[index];
|
||||
const InstanceId instanceId{ uuid };
|
||||
const AssetId assetId{ uuid };
|
||||
|
||||
threadCount--;
|
||||
cv.notify_one();
|
||||
});
|
||||
Instance<TestInstanceA> instance =
|
||||
instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
}
|
||||
|
||||
threadCount--;
|
||||
cv.notify_one();
|
||||
});
|
||||
}
|
||||
|
||||
bool timedOut = false;
|
||||
@@ -261,7 +259,9 @@ namespace UnitTest
|
||||
while (threadCount > 0 && !timedOut)
|
||||
{
|
||||
AZStd::unique_lock<AZStd::mutex> lock(mutex);
|
||||
timedOut = (AZStd::cv_status::timeout == cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
timedOut =
|
||||
(AZStd::cv_status::timeout ==
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(threadCount == 0) << "One or more threads appear to be deadlocked at " << timer.GetDeltaTimeInSeconds() << " seconds";
|
||||
@@ -280,8 +280,8 @@ namespace UnitTest
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
{
|
||||
// This is the original test scenario from when InstanceDatabase was first implemented
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper( 8, 100, 5 );
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(8, 100, 5);
|
||||
|
||||
// This value is checked in as 1 so this test doesn't take too much time, but can be increased locally to soak the test.
|
||||
const size_t attempts = 1;
|
||||
@@ -291,10 +291,10 @@ namespace UnitTest
|
||||
printf("Attempt %zu of %zu... \n", i, attempts);
|
||||
|
||||
// The idea behind this series of tests is that there are two threads sharing one Instance, and both threads try to
|
||||
// create or release that instance at the same time.
|
||||
// create or release that instance at the same time.
|
||||
// At the time, this set of scenarios has something like a 10% failure rate.
|
||||
const size_t duration = 2;
|
||||
// threads, AssetIds, seconds
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
@@ -306,7 +306,7 @@ namespace UnitTest
|
||||
|
||||
// Here we try a bunch of different threadCount:assetCount ratios to be thorough
|
||||
const size_t duration = 2;
|
||||
// threads, AssetIds, seconds
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 2, duration);
|
||||
@@ -328,7 +328,10 @@ namespace UnitTest
|
||||
|
||||
// Tests whether the deleter actually calls delete properly without
|
||||
// a parent database.
|
||||
instance->m_onDeleteCallback = [this, &m_deleted] () { m_deleted = true; };
|
||||
instance->m_onDeleteCallback = [this, &m_deleted]()
|
||||
{
|
||||
m_deleted = true;
|
||||
};
|
||||
}
|
||||
|
||||
EXPECT_TRUE(m_deleted);
|
||||
@@ -386,242 +389,4 @@ namespace UnitTest
|
||||
InstanceDatabase<TestInstanceB>::Destroy();
|
||||
}
|
||||
|
||||
|
||||
class InstanceDatabaseTestWithMultipleSubclasses
|
||||
: public AllocatorsFixture
|
||||
{
|
||||
protected:
|
||||
// We have "BaseAsset" with subclasses "FooAsset" and "BarAsset",
|
||||
// and corresponding "BaseInstance" with subclasses "FooInstance" and "BarInstance".
|
||||
// There is one "InstanceDatabse<BaseInstance>" that can create instances of both subtypes.
|
||||
|
||||
class BaseAsset
|
||||
: public AssetData
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BaseAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{35B443A6-D8ED-4C3C-A3F0-D642251F0AA5}", AssetData);
|
||||
|
||||
BaseAsset()
|
||||
{
|
||||
m_status = AssetStatus::Ready;
|
||||
}
|
||||
};
|
||||
|
||||
class BaseInstance
|
||||
: public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(BaseInstance, "{EFEC3406-2CB7-462E-A676-C22177E143E6}");
|
||||
AZ_CLASS_ALLOCATOR(BaseInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
BaseInstance(BaseAsset* asset)
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{}
|
||||
|
||||
Asset<BaseAsset> m_asset;
|
||||
};
|
||||
|
||||
class FooAsset
|
||||
: public BaseAsset
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FooAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{74BAE278-3DCA-4ADD-807E-2A6873F9EA3C}", BaseAsset);
|
||||
};
|
||||
|
||||
class BarAsset
|
||||
: public BaseAsset
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BarAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{2BCD66F5-768B-4569-9FC2-DE92ABC9C0BF}", BaseAsset);
|
||||
};
|
||||
|
||||
class FooInstance
|
||||
: public BaseInstance
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FooInstance, "{B5487509-5518-4591-AC96-03E623A584B7}", BaseInstance);
|
||||
AZ_CLASS_ALLOCATOR(FooInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
FooInstance(BaseAsset* asset)
|
||||
: BaseInstance(asset)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_typeid<FooAsset>() == asset->GetType());
|
||||
}
|
||||
};
|
||||
|
||||
class BarInstance
|
||||
: public BaseInstance
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BarInstance, "{CE9C844A-625D-4899-B7DB-8127D4618D25}", BaseInstance);
|
||||
AZ_CLASS_ALLOCATOR(BarInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
BarInstance(BaseAsset* asset)
|
||||
: BaseInstance(asset)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_typeid<BarAsset>() == asset->GetType());
|
||||
}
|
||||
};
|
||||
|
||||
MyAssetHandler<FooAsset> m_fooAssetHandler;
|
||||
MyAssetHandler<BarAsset> m_barAssetHandler;
|
||||
|
||||
public:
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
AllocatorInstance<PoolAllocator>::Create();
|
||||
AllocatorInstance<ThreadPoolAllocator>::Create();
|
||||
|
||||
// create the asset database
|
||||
{
|
||||
AssetManager::Descriptor desc;
|
||||
AssetManager::Create(desc);
|
||||
}
|
||||
|
||||
// create the instance database
|
||||
{
|
||||
InstanceDatabase<BaseInstance>::Create(azrtti_typeid<BaseAsset>());
|
||||
|
||||
InstanceHandler<BaseInstance> fooHandler;
|
||||
fooHandler.m_createFunction = [](AssetData* assetData)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_istypeof<FooAsset>(assetData));
|
||||
return aznew FooInstance(static_cast<FooAsset*>(assetData));
|
||||
};
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), fooHandler);
|
||||
|
||||
// Using a different overload of AddHandler()
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<BarAsset>(), [](AssetData* assetData)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_istypeof<BarAsset>(assetData));
|
||||
return aznew BarInstance(static_cast<BarAsset*>(assetData));
|
||||
});
|
||||
}
|
||||
|
||||
AssetManager::Instance().RegisterHandler(&m_fooAssetHandler, AzTypeInfo<FooAsset>::Uuid());
|
||||
AssetManager::Instance().RegisterHandler(&m_barAssetHandler, AzTypeInfo<BarAsset>::Uuid());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
AssetManager::Instance().UnregisterHandler(&m_fooAssetHandler);
|
||||
AssetManager::Instance().UnregisterHandler(&m_barAssetHandler);
|
||||
AssetManager::Destroy();
|
||||
|
||||
InstanceDatabase<BaseInstance>::Destroy();
|
||||
|
||||
AllocatorInstance<ThreadPoolAllocator>::Destroy();
|
||||
AllocatorInstance<PoolAllocator>::Destroy();
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, InstanceCreate)
|
||||
{
|
||||
auto& assetManager = AssetManager::Instance();
|
||||
auto& instanceDatabase = InstanceDatabase<BaseInstance>::Instance();
|
||||
|
||||
Asset<FooAsset> fooAsset = assetManager.CreateAsset<FooAsset>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
Asset<BarAsset> barAsset = assetManager.CreateAsset<BarAsset>(s_assetId1, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
// Run the creation tests on 'A' first.
|
||||
|
||||
Instance<BaseInstance> fooInstanceA = instanceDatabase.Find(s_instanceId0);
|
||||
EXPECT_EQ(fooInstanceA, nullptr);
|
||||
|
||||
Instance<BaseInstance> barInstanceA = instanceDatabase.Find(s_instanceId1);
|
||||
EXPECT_EQ(barInstanceA, nullptr);
|
||||
|
||||
fooInstanceA = instanceDatabase.FindOrCreate(s_instanceId0, fooAsset);
|
||||
EXPECT_NE(fooInstanceA, nullptr);
|
||||
EXPECT_EQ(fooInstanceA->m_asset, fooAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<FooInstance>() == fooInstanceA->RTTI_GetType());
|
||||
EXPECT_EQ(fooInstanceA, instanceDatabase.Find(s_instanceId0));
|
||||
|
||||
barInstanceA = instanceDatabase.FindOrCreate(s_instanceId1, barAsset);
|
||||
EXPECT_NE(barInstanceA, nullptr);
|
||||
EXPECT_EQ(barInstanceA->m_asset, barAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<BarInstance>() == barInstanceA->RTTI_GetType());
|
||||
EXPECT_EQ(barInstanceA, instanceDatabase.Find(s_instanceId1));
|
||||
|
||||
// Run the same test on 'B' to make sure it works independently.
|
||||
|
||||
Instance<BaseInstance> fooInstanceB = instanceDatabase.Find(s_instanceId2);
|
||||
EXPECT_EQ(fooInstanceB, nullptr);
|
||||
|
||||
Instance<BaseInstance> barInstanceB = instanceDatabase.Find(s_instanceId3);
|
||||
EXPECT_EQ(barInstanceB, nullptr);
|
||||
|
||||
fooInstanceB = instanceDatabase.FindOrCreate(s_instanceId2, fooAsset);
|
||||
EXPECT_NE(fooInstanceB, nullptr);
|
||||
EXPECT_EQ(fooInstanceB->m_asset, fooAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<FooInstance>() == fooInstanceB->RTTI_GetType());
|
||||
EXPECT_EQ(fooInstanceB, instanceDatabase.Find(s_instanceId2));
|
||||
|
||||
barInstanceB = instanceDatabase.FindOrCreate(s_instanceId3, barAsset);
|
||||
EXPECT_NE(barInstanceB, nullptr);
|
||||
EXPECT_EQ(barInstanceB->m_asset, barAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<BarInstance>() == barInstanceB->RTTI_GetType());
|
||||
EXPECT_EQ(barInstanceB, instanceDatabase.Find(s_instanceId3));
|
||||
|
||||
// Make sure the instances are unique
|
||||
|
||||
EXPECT_NE(fooInstanceA, fooInstanceB);
|
||||
EXPECT_NE(barInstanceA, barInstanceB);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, TestError_AddHandler_AssetTypeIsNotSubclass)
|
||||
{
|
||||
MyAssetHandler<TestAssetType> testAssetHandler;
|
||||
AssetManager::Instance().RegisterHandler(&testAssetHandler, azrtti_typeid<TestAssetType>());
|
||||
|
||||
// Register an instance handler with an unrelated asset type. This can't actually
|
||||
// check the AssetType yet because all it has are AssetType GUIDs, no actual data.
|
||||
{
|
||||
InstanceHandler<BaseInstance> instanceHandler;
|
||||
instanceHandler.m_createFunction = [](AssetData* assetData)
|
||||
{
|
||||
return aznew BaseInstance(static_cast<BaseAsset*>(assetData));
|
||||
};
|
||||
|
||||
AssetType unrelatedAssetType = azrtti_typeid<TestAssetType>();
|
||||
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(unrelatedAssetType, instanceHandler);
|
||||
}
|
||||
|
||||
// Try to use the unrelated handler. This is where we'll actually get an error.
|
||||
{
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
Asset<TestAssetType> testAsset = AssetManager::Instance().CreateAsset<TestAssetType>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
EXPECT_EQ(nullptr, InstanceDatabase<BaseInstance>::Instance().FindOrCreate(s_instanceId0, testAsset));
|
||||
|
||||
AZ_TEST_STOP_ASSERTTEST(1);
|
||||
}
|
||||
|
||||
AssetManager::Instance().UnregisterHandler(&testAssetHandler);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, TestError_AddHandler_AlreadyExists)
|
||||
{
|
||||
InstanceHandler<BaseInstance> instanceHandler;
|
||||
instanceHandler.m_createFunction = [](AssetData*)
|
||||
{
|
||||
return nullptr; // Doesn't matter
|
||||
};
|
||||
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
// The SetUp() function already registered a handler for FooAsset so this should fail
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), instanceHandler);
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), [](AssetData*) { return nullptr; });
|
||||
|
||||
AZ_TEST_STOP_ASSERTTEST(2);
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
ly_add_target(
|
||||
NAME AzAutoGen HEADERONLY
|
||||
NAMESPACE AZ
|
||||
|
||||
@@ -292,8 +292,13 @@ namespace AZ
|
||||
const typename VecType::FloatType cmp2 = VecType::AndNot(cmp0, cmp1);
|
||||
|
||||
// -1/x
|
||||
// this step is calculated for all values of x, but only used if x > Sqrt(2) + 1
|
||||
// in order to avoid a division by zero, detect if xabs is zero here and replace it with an arbitrary value
|
||||
// if xabs does equal zero, the value here doesn't matter because the result will be thrown away
|
||||
typename VecType::FloatType xabsSafe =
|
||||
VecType::Add(xabs, VecType::And(VecType::CmpEq(xabs, VecType::ZeroFloat()), FastLoadConstant<VecType>(Simd::g_vec1111)));
|
||||
const typename VecType::FloatType y0 = VecType::And(cmp0, FastLoadConstant<VecType>(Simd::g_HalfPi));
|
||||
typename VecType::FloatType x0 = VecType::Div(FastLoadConstant<VecType>(Simd::g_vec1111), xabs);
|
||||
typename VecType::FloatType x0 = VecType::Div(FastLoadConstant<VecType>(Simd::g_vec1111), xabsSafe);
|
||||
x0 = VecType::Xor(x0, VecType::CastToFloat(FastLoadConstant<VecType>(Simd::g_negateMask)));
|
||||
|
||||
const typename VecType::FloatType y1 = VecType::And(cmp2, FastLoadConstant<VecType>(Simd::g_QuarterPi));
|
||||
@@ -368,8 +373,12 @@ namespace AZ
|
||||
|
||||
typename VecType::FloatType offset = VecType::And(x_lt_0, offset1);
|
||||
|
||||
// the result of this part of the computation is thrown away if x equals 0,
|
||||
// but if x does equal 0, it will cause a division by zero
|
||||
// so replace zero by an arbitrary value here in that case
|
||||
typename VecType::FloatType xSafe = VecType::Add(x, VecType::And(x_eq_0, FastLoadConstant<VecType>(Simd::g_vec1111)));
|
||||
const typename VecType::FloatType atan_mask = VecType::Not(VecType::Or(x_eq_0, y_eq_0));
|
||||
const typename VecType::FloatType atan_arg = VecType::Div(y, x);
|
||||
const typename VecType::FloatType atan_arg = VecType::Div(y, xSafe);
|
||||
typename VecType::FloatType atan_result = VecType::Atan(atan_arg);
|
||||
atan_result = VecType::Add(atan_result, offset);
|
||||
atan_result = VecType::AndNot(pio2_mask, atan_result);
|
||||
|
||||
@@ -471,6 +471,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec2::FloatType Vec2::Reciprocal(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(Sse::ReplaceThird(value, 1.0f), 1.0f);
|
||||
return Sse::Reciprocal(value);
|
||||
}
|
||||
|
||||
@@ -513,6 +514,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec2::FloatType Vec2::SqrtInv(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(Sse::ReplaceThird(value, 1.0f), 1.0f);
|
||||
return Sse::SqrtInv(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -507,6 +507,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec3::FloatType Vec3::Reciprocal(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(value, 1.0f);
|
||||
return Sse::Reciprocal(value);
|
||||
}
|
||||
|
||||
@@ -549,6 +550,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vec3::FloatType Vec3::SqrtInv(FloatArgType value)
|
||||
{
|
||||
value = Sse::ReplaceFourth(value, 1.0f);
|
||||
return Sse::SqrtInv(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,12 @@
|
||||
#endif
|
||||
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) __declspec(align(_alignment)) _decl
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
__declspec(align(_alignment)) \
|
||||
_decl \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof(_type)
|
||||
/// Pointer will be aliased.
|
||||
@@ -123,7 +128,12 @@
|
||||
|
||||
# define AZ_FORCE_INLINE inline
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) _decl __attribute__((aligned(_alignment)))
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
_decl \
|
||||
__attribute__((aligned(_alignment)))
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof__(_type)
|
||||
/// Pointer will be aliased.
|
||||
|
||||
@@ -161,7 +161,56 @@ namespace AZ
|
||||
return "A pair is an fixed size collection of two elements.";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
void GetTypeNamesFold(AZStd::vector<AZStd::string>& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
result.push_back(OnDemandPrettyName<T>::Get(context));
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
void GetTypeNames(AZStd::vector<AZStd::string>& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
(GetTypeNamesFold<T>(result, context), ...);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void GetTypeNamesFold(AZStd::string& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
if (!result.empty())
|
||||
{
|
||||
result += ", ";
|
||||
}
|
||||
|
||||
result += OnDemandPrettyName<T>::Get(context);
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
void GetTypeNames(AZStd::string& result, AZ::BehaviorContext& context)
|
||||
{
|
||||
(GetTypeNamesFold<T>(result, context), ...);
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct OnDemandPrettyName<AZStd::tuple<T...>>
|
||||
{
|
||||
static AZStd::string Get(AZ::BehaviorContext& context)
|
||||
{
|
||||
AZStd::string typeNames;
|
||||
GetTypeNames<T...>(typeNames, context);
|
||||
return AZStd::string::format("Tuple<%s>", typeNames.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct OnDemandToolTip<AZStd::tuple<T...>>
|
||||
{
|
||||
static AZStd::string Get(AZ::BehaviorContext&)
|
||||
{
|
||||
return "A tuple is an fixed size collection of any number of any type of element.";
|
||||
}
|
||||
};
|
||||
|
||||
template<class Key, class MappedType, class Hasher, class EqualKey, class Allocator>
|
||||
struct OnDemandPrettyName< AZStd::unordered_map<Key, MappedType, Hasher, EqualKey, Allocator> >
|
||||
{
|
||||
|
||||
@@ -813,20 +813,27 @@ namespace AZ
|
||||
{
|
||||
using ContainerType = AZStd::tuple<T...>;
|
||||
|
||||
template<size_t Index>
|
||||
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder)
|
||||
template<typename Targ, size_t Index>
|
||||
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder, const AZStd::vector<AZStd::string>& typeNames)
|
||||
{
|
||||
const AZStd::string methodName = AZStd::string::format("Get%zu", Index);
|
||||
builder->Method(methodName.data(), [](ContainerType& value) { return AZStd::get<Index>(value); })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
builder->Method(methodName.data(), [](ContainerType& thisPointer) { return AZStd::get<Index>(thisPointer); })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, Index)
|
||||
;
|
||||
|
||||
builder->Property
|
||||
( AZStd::string::format("element_%zu_%s", Index, typeNames[Index].c_str()).c_str()
|
||||
, [](ContainerType& thisPointer) { return AZStd::get<Index>(thisPointer); }
|
||||
, [](ContainerType& thisPointer, const Targ& element) { AZStd::get<Index>(thisPointer) = element; });
|
||||
}
|
||||
|
||||
template<size_t... Indices>
|
||||
template<typename... Targ, size_t... Indices>
|
||||
static void ReflectUnpackMethods(BehaviorContext::ClassBuilder<ContainerType>& builder, AZStd::index_sequence<Indices...>)
|
||||
{
|
||||
(ReflectUnpackMethodFold<Indices>(builder), ...);
|
||||
AZStd::vector<AZStd::string> typeNames;
|
||||
ScriptCanvasOnDemandReflection::GetTypeNames<T...>(typeNames, *builder.m_context);
|
||||
(ReflectUnpackMethodFold<Targ, Indices>(builder, typeNames), ...);
|
||||
}
|
||||
|
||||
static void Reflect(ReflectContext* context)
|
||||
@@ -851,9 +858,10 @@ namespace AZ
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleConstructorFunction, constructorHolder)
|
||||
;
|
||||
|
||||
ReflectUnpackMethods(builder, AZStd::make_index_sequence<sizeof...(T)>{});
|
||||
ReflectUnpackMethods<T...>(builder, AZStd::make_index_sequence<sizeof...(T)>{});
|
||||
|
||||
builder->Method("GetSize", []() { return AZStd::tuple_size<ContainerType>::value; })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ namespace AZ
|
||||
{
|
||||
using Callable = AZStd::conditional_t<AZStd::function_traits<Invocable>::value, AZStd::function<typename AZStd::function_traits<Invocable>::function_type>, Invocable>;
|
||||
public:
|
||||
AZ_RTTI((AttributeInvocable<Invocable>, "{60D5804F-9AF4-4EB1-8F5A-62AFB4883F9D}"), AZ::Attribute);
|
||||
AZ_RTTI((AttributeInvocable<Invocable>, "{60D5804F-9AF4-4EB1-8F5A-62AFB4883F9D}", Invocable), AZ::Attribute);
|
||||
AZ_CLASS_ALLOCATOR(AttributeInvocable<Invocable>, SystemAllocator, 0);
|
||||
template<typename CallableType>
|
||||
explicit AttributeInvocable(CallableType&& invocable)
|
||||
|
||||
@@ -150,8 +150,13 @@ namespace AZ
|
||||
// also needs to be an overload for every version because they all represent overloads for different non-types.
|
||||
namespace AzGenericTypeInfo
|
||||
{
|
||||
template<typename...>
|
||||
constexpr bool false_v = false;
|
||||
/// Needs to match declared parameter type.
|
||||
template <template <typename...> class> constexpr bool false_v1 = false;
|
||||
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
|
||||
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
|
||||
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
|
||||
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
|
||||
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
|
||||
|
||||
template<typename T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
@@ -162,7 +167,7 @@ namespace AZ
|
||||
template<template<typename...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v1<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -170,7 +175,7 @@ namespace AZ
|
||||
template<template<AZStd::size_t...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -178,7 +183,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -186,7 +191,7 @@ namespace AZ
|
||||
template<template<typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -194,7 +199,7 @@ namespace AZ
|
||||
template<template<typename, typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -202,7 +207,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t, typename> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,12 @@
|
||||
#include <AzCore/Serialization/Json/StringSerializer.h>
|
||||
#include <AzCore/Serialization/Json/TupleSerializer.h>
|
||||
#include <AzCore/Serialization/Json/UnorderedSetSerializer.h>
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/forward_list.h>
|
||||
@@ -33,12 +38,11 @@
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -98,6 +102,13 @@ namespace AZ
|
||||
jsonContext->Serializer<JsonArraySerializer>()
|
||||
->HandlesType<AZStd::array>();
|
||||
|
||||
jsonContext->Serializer<JsonAnySerializer>()
|
||||
->HandlesType<AZStd::any>();
|
||||
jsonContext->Serializer<JsonVariantSerializer>()
|
||||
->HandlesType<AZStd::variant>();
|
||||
jsonContext->Serializer<JsonOptionalSerializer>()
|
||||
->HandlesType<AZStd::optional>();
|
||||
|
||||
MathReflect(jsonContext);
|
||||
}
|
||||
else if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(reflectContext))
|
||||
|
||||
@@ -33,34 +33,31 @@ namespace AZ
|
||||
, m_serializerIter(serializerMapIter)
|
||||
{}
|
||||
|
||||
JsonRegistrationContext::SerializerBuilder* JsonRegistrationContext::SerializerBuilder::HandlesTypeId(const Uuid& uuid)
|
||||
JsonRegistrationContext::SerializerBuilder* JsonRegistrationContext::SerializerBuilder::HandlesTypeId(
|
||||
const Uuid& uuid, bool overwriteExisting)
|
||||
{
|
||||
if (!m_context->IsRemovingReflection())
|
||||
{
|
||||
auto serializer = m_serializerIter->second.get();
|
||||
if (uuid.IsNull())
|
||||
{
|
||||
AZ_Error("Serialization", false,
|
||||
"Could not register Json serializer %s. Its Uuid is null.",
|
||||
serializer->RTTI_GetTypeName()
|
||||
);
|
||||
AZ_Assert(false, "Could not register Json serializer %s. Its Uuid is null.", serializer->RTTI_GetTypeName());
|
||||
return this;
|
||||
}
|
||||
|
||||
auto serializerIter = m_context->m_handledTypesMap.find(uuid);
|
||||
|
||||
if (serializerIter == m_context->m_handledTypesMap.end())
|
||||
if (!overwriteExisting)
|
||||
{
|
||||
m_context->m_handledTypesMap.emplace(uuid, serializer);
|
||||
return this;
|
||||
auto emplaceResult = m_context->m_handledTypesMap.try_emplace(uuid, serializer);
|
||||
AZ_Assert(
|
||||
emplaceResult.second,
|
||||
"Couldn't register Json serializer %s. Another serializer (%s) has already been registered for the same Uuid (%s).",
|
||||
serializer->RTTI_GetTypeName(), emplaceResult.first->second->RTTI_GetTypeName(),
|
||||
uuid.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context->m_handledTypesMap.insert_or_assign(uuid, serializer);
|
||||
}
|
||||
|
||||
AZ_Error("Serialization", false,
|
||||
"Couldn't register Json serializer %s. Another serializer (%s) has already been registered for the same Uuid (%s).",
|
||||
serializer->RTTI_GetTypeName(),
|
||||
serializerIter->second->RTTI_GetTypeName(),
|
||||
serializerIter->first.ToString<OSString>().c_str()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -63,52 +63,50 @@ namespace AZ
|
||||
SerializerBuilder* operator->();
|
||||
|
||||
template <typename T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template <template<typename...> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<AZStd::size_t...> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, typename, typename, AZStd::size_t> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
template<template<typename, AZStd::size_t, typename> class T>
|
||||
SerializerBuilder* HandlesType()
|
||||
SerializerBuilder* HandlesType(bool overwriteExisting = false)
|
||||
{
|
||||
return HandlesTypeId(azrtti_typeid<T>());
|
||||
return HandlesTypeId(azrtti_typeid<T>(), overwriteExisting);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct Placeholder { AZ_TYPE_INFO(PlaceHolder, "{4425191C-F497-411A-A7C3-52928E720B0A}"); };
|
||||
|
||||
SerializerBuilder(JsonRegistrationContext* context, SerializerMap::const_iterator serializerMapIter);
|
||||
SerializerBuilder* HandlesTypeId(const AZ::Uuid& uuid);
|
||||
SerializerBuilder* HandlesTypeId(const AZ::Uuid& uuid, bool overwriteExisting);
|
||||
|
||||
JsonRegistrationContext* m_context = nullptr;
|
||||
SerializerMap::const_iterator m_serializerIter;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonUnsupportedTypesSerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonAnySerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonVariantSerializer, SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonOptionalSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result JsonUnsupportedTypesSerializer::Load(void*, const Uuid&, const rapidjson::Value&,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Invalid, GetMessage());
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonUnsupportedTypesSerializer::Store(rapidjson::Value&, const void*, const void*, const Uuid&,
|
||||
JsonSerializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Invalid, GetMessage());
|
||||
}
|
||||
|
||||
AZStd::string_view JsonAnySerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::any by design. The Json Serialization attempts to minimize the use of $type, "
|
||||
"in particular the guid version, but no way has yet been found to use AZStd::any without explicitly and always requiring "
|
||||
"one.";
|
||||
}
|
||||
|
||||
AZStd::string_view JsonVariantSerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::variant by design. The Json Serialization attempts to minimize the use of "
|
||||
"$type, in particular the guid version. While combinations of AZStd::variant can be constructed that don't require a $type, "
|
||||
"this cannot be guaranteed in general.";
|
||||
}
|
||||
|
||||
AZStd::string_view JsonOptionalSerializer::GetMessage() const
|
||||
{
|
||||
return "The Json Serialization doesn't support AZStd::optional by design. No JSON format has yet been found that wasn't deemed too "
|
||||
"complex or overly verbose.";
|
||||
}
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class JsonUnsupportedTypesSerializer : public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonUnsupportedTypesSerializer, "{AFCC76B9-1F28-429D-8B4E-020BFD95ADAC}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
JsonSerializationResult::Result Load(
|
||||
void* outputValue,
|
||||
const Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context) override;
|
||||
JsonSerializationResult::Result Store(
|
||||
rapidjson::Value& outputValue,
|
||||
const void* inputValue,
|
||||
const void* defaultValue,
|
||||
const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context) override;
|
||||
|
||||
protected:
|
||||
virtual AZStd::string_view GetMessage() const = 0;
|
||||
};
|
||||
|
||||
class JsonAnySerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonAnySerializer, "{699A0864-C4E2-4266-8141-99793C76870F}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
|
||||
class JsonVariantSerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonVariantSerializer, "{08F8E746-F8A4-4E83-8902-713E90F3F498}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
|
||||
class JsonOptionalSerializer : public JsonUnsupportedTypesSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonOptionalSerializer, "{F8AF1C95-BD1B-44D2-9B4A-F5726133A104}", JsonUnsupportedTypesSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
protected:
|
||||
AZStd::string_view GetMessage() const override;
|
||||
};
|
||||
} // namespace AZ
|
||||
@@ -175,4 +175,11 @@ namespace AZ::Utils
|
||||
path /= ".o3de";
|
||||
return path.Native();
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString GetO3deLogsDirectory()
|
||||
{
|
||||
AZ::IO::FixedMaxPath path = GetO3deManifestDirectory();
|
||||
path /= "Logs";
|
||||
return path.Native();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,9 @@ namespace AZ
|
||||
//! Retrieves the full path where the manifest file lives, i.e. "<userhome>/.o3de/o3de_manifest.json"
|
||||
AZ::IO::FixedMaxPathString GetEngineManifestPath();
|
||||
|
||||
//! Retrieves the full directory to the O3DE logs directory, i.e. "<userhome>/.o3de/Logs"
|
||||
AZ::IO::FixedMaxPathString GetO3deLogsDirectory();
|
||||
|
||||
//! Retrieves the App root path to use on the current platform
|
||||
//! If the optional is not engaged the AppRootPath should be calculated based
|
||||
//! on the location of the bootstrap.cfg file
|
||||
@@ -113,7 +116,8 @@ namespace AZ
|
||||
//! Save a string to a file. Otherwise returns a failure with error message.
|
||||
AZ::Outcome<void, AZStd::string> WriteFile(AZStd::string_view content, AZStd::string_view filePath);
|
||||
|
||||
//! Read a file into a string. Returns a failure with error message if the content could not be loaded.
|
||||
//! Read a file into a string. Returns a failure with error message if the content could not be loaded or if
|
||||
//! the file size is larger than the max file size provided.
|
||||
template<typename Container = AZStd::string>
|
||||
AZ::Outcome<Container, AZStd::string> ReadFile(AZStd::string_view filePath, size_t maxFileSize = DefaultMaxFileSize);
|
||||
}
|
||||
|
||||
@@ -544,6 +544,8 @@ set(FILES
|
||||
Serialization/Json/TupleSerializer.cpp
|
||||
Serialization/Json/UnorderedSetSerializer.h
|
||||
Serialization/Json/UnorderedSetSerializer.cpp
|
||||
Serialization/Json/UnsupportedTypesSerializer.h
|
||||
Serialization/Json/UnsupportedTypesSerializer.cpp
|
||||
Serialization/std/VariantReflection.inl
|
||||
Settings/CommandLine.cpp
|
||||
Settings/CommandLine.h
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace AZStd
|
||||
using std::exp2;
|
||||
using std::floor;
|
||||
using std::fmod;
|
||||
using std::pow;
|
||||
using std::round;
|
||||
using std::sin;
|
||||
using std::sqrt;
|
||||
|
||||
@@ -2010,6 +2010,28 @@ TEST_F(SerializeBasicTest, BasicTypeTest_Succeed)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This test will dynamic cast (azrtti_cast) between incompatible types, which should always result in nullptr.
|
||||
If this test fails, the RTTI declaration for the relevant type is incorrect.
|
||||
*/
|
||||
TEST_F(Serialization, AttributeRTTI)
|
||||
{
|
||||
{
|
||||
AttributeInvocable<AZStd::function<AZStd::string(AZStd::string)>> fn([](AZStd::string x) { return x + x; });
|
||||
Attribute* fnDownCast = &fn;
|
||||
auto fnUpCast = azrtti_cast<AttributeInvocable<AZStd::function<int(int)>>*>(fnDownCast);
|
||||
EXPECT_EQ(fnUpCast, nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
AttributeFunction<AZStd::string(AZStd::string)> fn([](AZStd::string x) { return x + x; });
|
||||
Attribute* fnDownCast = &fn;
|
||||
auto fnUpCast = azrtti_cast<AttributeFunction<int(int)>*>(fnDownCast);
|
||||
EXPECT_EQ(fnUpCast, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecation
|
||||
*/
|
||||
|
||||
@@ -95,6 +95,20 @@ namespace JsonSerializationTests
|
||||
}
|
||||
};
|
||||
|
||||
class SerializerWithOneDuplicatedTypeWithOverride
|
||||
: public JsonSerializerTemplatedMock<SerializerWithOneDuplicatedTypeWithOverride>
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(SerializerWithOneDuplicatedTypeWithOverride, "{4218D591-E578-499B-B578-ACA70C9944AB}", BaseJsonSerializer);
|
||||
~SerializerWithOneDuplicatedTypeWithOverride() override = default;
|
||||
|
||||
static void Reflect(AZ::JsonRegistrationContext* context)
|
||||
{
|
||||
context->Serializer<SerializerWithOneDuplicatedTypeWithOverride>()
|
||||
->HandlesType<bool>(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Attempts to register the same type twice
|
||||
class SerializerWithTwoSameTypes
|
||||
: public JsonSerializerTemplatedMock<SerializerWithTwoSameTypes>
|
||||
@@ -271,13 +285,29 @@ namespace JsonSerializationTests
|
||||
|
||||
EXPECT_EQ(1, m_jsonRegistrationContext->GetRegisteredSerializers().size());
|
||||
AZ::BaseJsonSerializer* mockSerializer = m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<bool>());
|
||||
EXPECT_NE(mockSerializer, nullptr);
|
||||
ASSERT_NE(mockSerializer, nullptr);
|
||||
EXPECT_EQ(AZ::AzTypeInfo<SerializerWithOneType>::Uuid(), mockSerializer->RTTI_GetType());
|
||||
|
||||
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedType::Unreflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
TEST_F(JsonRegistrationContextTests, OverwriteRegisterSameUuidWithMultipleSerializers_Succeeds)
|
||||
{
|
||||
EXPECT_NE(AZ::AzTypeInfo<SerializerWithOneDuplicatedTypeWithOverride>::Uuid(), AZ::AzTypeInfo<SerializerWithOneType>::Uuid());
|
||||
|
||||
SerializerWithOneType::Reflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedTypeWithOverride::Reflect(m_jsonRegistrationContext.get());
|
||||
|
||||
EXPECT_EQ(1, m_jsonRegistrationContext->GetRegisteredSerializers().size());
|
||||
AZ::BaseJsonSerializer* mockSerializer = m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<bool>());
|
||||
ASSERT_NE(mockSerializer, nullptr);
|
||||
EXPECT_EQ(AZ::AzTypeInfo<SerializerWithOneDuplicatedTypeWithOverride>::Uuid(), mockSerializer->RTTI_GetType());
|
||||
|
||||
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
|
||||
SerializerWithOneDuplicatedTypeWithOverride::Unreflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
TEST_F(JsonRegistrationContextTests, RegisterSameUuidWithSameSerializers_Fails)
|
||||
{
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/Json/UnsupportedTypesSerializer.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
|
||||
|
||||
namespace JsonSerializationTests
|
||||
{
|
||||
struct AnyInfo
|
||||
{
|
||||
using Type = AZStd::any;
|
||||
using Serializer = AZ::JsonAnySerializer;
|
||||
};
|
||||
|
||||
struct VariantInfo
|
||||
{
|
||||
using Type = AZStd::variant<AZStd::monostate, int, double>;
|
||||
using Serializer = AZ::JsonVariantSerializer;
|
||||
};
|
||||
|
||||
struct OptionalInfo
|
||||
{
|
||||
using Type = AZStd::optional<int>;
|
||||
using Serializer = AZ::JsonVariantSerializer;
|
||||
};
|
||||
|
||||
template<typename Info>
|
||||
class JsonUnsupportedTypesSerializerTests : public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
using Type = typename Info::Type;
|
||||
using Serializer = typename Info::Serializer;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseJsonSerializerFixture::SetUp();
|
||||
this->m_serializer = AZStd::make_unique<Serializer>();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
this->m_serializer.reset();
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<Serializer> m_serializer;
|
||||
Type m_instance{};
|
||||
};
|
||||
|
||||
using UnsupportedTypesTestTypes = ::testing::Types<AnyInfo, VariantInfo, OptionalInfo>;
|
||||
TYPED_TEST_CASE(JsonUnsupportedTypesSerializerTests, UnsupportedTypesTestTypes);
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Load_CallDirectly_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_jsonDeserializationContext->PushReporter(AZStd::move(callback));
|
||||
|
||||
JSR::Result result = this->m_serializer->Load(
|
||||
&this->m_instance, azrtti_typeid(this->m_instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext);
|
||||
this->m_jsonDeserializationContext->PopReporter();
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetResultCode().GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Load_CallThroughFrontEnd_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_deserializationSettings->m_reporting = AZStd::move(callback);
|
||||
|
||||
JSR::ResultCode result = AZ::JsonSerialization::Load(this->m_instance, *this->m_jsonDocument, *this->m_deserializationSettings);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Save_CallDirectly_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_jsonSerializationContext->PushReporter(AZStd::move(callback));
|
||||
|
||||
JSR::Result result = this->m_serializer->Store(
|
||||
*this->m_jsonDocument, &this->m_instance, nullptr, azrtti_typeid(this->m_instance), *this->m_jsonSerializationContext);
|
||||
this->m_jsonSerializationContext->PopReporter();
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetResultCode().GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonUnsupportedTypesSerializerTests, Save_CallThroughFrontEnd_ReportsIssueAndHalts)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
bool hasMessage = false;
|
||||
auto callback = [&hasMessage](AZStd::string_view message, JSR::ResultCode result, AZStd::string_view) -> JSR::ResultCode
|
||||
{
|
||||
hasMessage = !message.empty();
|
||||
return result;
|
||||
};
|
||||
this->m_serializationSettings->m_reporting = AZStd::move(callback);
|
||||
|
||||
JSR::ResultCode result = AZ::JsonSerialization::Store(
|
||||
*this->m_jsonDocument, this->m_jsonDocument->GetAllocator(), this->m_instance, *this->m_serializationSettings);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Halted, result.GetProcessing());
|
||||
EXPECT_TRUE(hasMessage);
|
||||
}
|
||||
} // namespace JsonSerializationTests
|
||||
@@ -128,6 +128,7 @@ set(FILES
|
||||
Serialization/Json/TransformSerializerTests.cpp
|
||||
Serialization/Json/TupleSerializerTests.cpp
|
||||
Serialization/Json/UnorderedSetSerializerTests.cpp
|
||||
Serialization/Json/UnsupportedTypesSerializerTests.cpp
|
||||
Serialization/Json/UuidSerializerTests.cpp
|
||||
Math/AabbTests.cpp
|
||||
Math/ColorTests.cpp
|
||||
|
||||
@@ -1290,7 +1290,7 @@ namespace AZ::IO
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AZ::IO::ArchiveFileIterator Archive::FindFirst(AZStd::string_view pDir, [[maybe_unused]] uint32_t nPathFlags, bool bAllowUseFileSystem)
|
||||
AZ::IO::ArchiveFileIterator Archive::FindFirst(AZStd::string_view pDir, EFileSearchType searchType)
|
||||
{
|
||||
auto szFullPath = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(pDir);
|
||||
if (!szFullPath)
|
||||
@@ -1299,8 +1299,26 @@ namespace AZ::IO
|
||||
return {};
|
||||
}
|
||||
|
||||
bool bScanZips{};
|
||||
bool bAllowUseFileSystem{};
|
||||
switch (searchType)
|
||||
{
|
||||
case IArchive::eFileSearchType_AllowInZipsOnly:
|
||||
bAllowUseFileSystem = false;
|
||||
bScanZips = true;
|
||||
break;
|
||||
case IArchive::eFileSearchType_AllowOnDiskAndInZips:
|
||||
bAllowUseFileSystem = true;
|
||||
bScanZips = true;
|
||||
break;
|
||||
case IArchive::eFileSearchType_AllowOnDiskOnly:
|
||||
bAllowUseFileSystem = true;
|
||||
bScanZips = false;
|
||||
break;
|
||||
}
|
||||
|
||||
AZStd::intrusive_ptr<AZ::IO::FindData> pFindData = new AZ::IO::FindData();
|
||||
pFindData->Scan(this, szFullPath->Native(), bAllowUseFileSystem);
|
||||
pFindData->Scan(this, szFullPath->Native(), bAllowUseFileSystem, bScanZips);
|
||||
|
||||
return pFindData->Fetch();
|
||||
}
|
||||
@@ -1676,7 +1694,7 @@ namespace AZ::IO
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AZ::IO::ArchiveFileIterator fileIterator = FindFirst(pWildcardIn, 0, true); fileIterator)
|
||||
if (AZ::IO::ArchiveFileIterator fileIterator = FindFirst(pWildcardIn, IArchive::eFileSearchType_AllowOnDiskOnly); fileIterator)
|
||||
{
|
||||
AZStd::vector<AZStd::string> files;
|
||||
do
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace AZ::IO
|
||||
uint64_t FTell(AZ::IO::HandleType handle) override;
|
||||
int FFlush(AZ::IO::HandleType handle) override;
|
||||
int FClose(AZ::IO::HandleType handle) override;
|
||||
AZ::IO::ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nPathFlags = 0, bool bAllOwUseFileSystem = false) override;
|
||||
AZ::IO::ArchiveFileIterator FindFirst(AZStd::string_view pDir, EFileSearchType searchType = eFileSearchType_AllowInZipsOnly) override;
|
||||
AZ::IO::ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator fileIterator) override;
|
||||
bool FindClose(AZ::IO::ArchiveFileIterator fileIterator) override;
|
||||
int FEof(AZ::IO::HandleType handle) override;
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace AZ::IO
|
||||
return m_findData && m_lastFetchValid;
|
||||
}
|
||||
|
||||
void FindData::Scan(IArchive* archive, AZStd::string_view szDir, bool bAllowUseFS)
|
||||
void FindData::Scan(IArchive* archive, AZStd::string_view szDir, bool bAllowUseFS, bool bScanZips)
|
||||
{
|
||||
// get the priority into local variable to avoid it changing in the course of
|
||||
// this function execution
|
||||
@@ -87,12 +87,18 @@ namespace AZ::IO
|
||||
{
|
||||
// first, find the file system files
|
||||
ScanFS(archive, szDir);
|
||||
ScanZips(archive, szDir);
|
||||
if (bScanZips)
|
||||
{
|
||||
ScanZips(archive, szDir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// first, find the zip files
|
||||
ScanZips(archive, szDir);
|
||||
if (bScanZips)
|
||||
{
|
||||
ScanZips(archive, szDir);
|
||||
}
|
||||
if (bAllowUseFS || nVarPakPriority != ArchiveLocationPriority::ePakPriorityPakOnly)
|
||||
{
|
||||
ScanFS(archive, szDir);
|
||||
@@ -111,30 +117,31 @@ namespace AZ::IO
|
||||
}
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool
|
||||
{
|
||||
AZ::IO::FileDesc fileDesc;
|
||||
AZStd::string filePathEntry{filePath};
|
||||
AZ::IO::ArchiveFileIterator fileIterator;
|
||||
fileIterator.m_filename = AZ::IO::PathView(filePath).Filename().Native();
|
||||
fileIterator.m_fileDesc.nAttrib = {};
|
||||
|
||||
if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(filePath))
|
||||
{
|
||||
fileDesc.nAttrib = fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
m_fileStack.emplace_back(AZStd::move(fileIterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AZ::IO::FileIOBase::GetDirectInstance()->IsReadOnly(filePath))
|
||||
{
|
||||
fileDesc.nAttrib = fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
|
||||
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
|
||||
}
|
||||
AZ::u64 fileSize = 0;
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Size(filePath, fileSize);
|
||||
fileDesc.nSize = fileSize;
|
||||
fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
|
||||
fileIterator.m_fileDesc.nSize = fileSize;
|
||||
fileIterator.m_fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
|
||||
|
||||
// These times are not supported by our file interface
|
||||
fileDesc.tAccess = fileDesc.tWrite;
|
||||
fileDesc.tCreate = fileDesc.tWrite;
|
||||
fileIterator.m_fileDesc.tAccess = fileIterator.m_fileDesc.tWrite;
|
||||
fileIterator.m_fileDesc.tCreate = fileIterator.m_fileDesc.tWrite;
|
||||
m_fileStack.emplace_back(AZStd::move(fileIterator));
|
||||
}
|
||||
[[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(filePathEntry), fileDesc);
|
||||
AZ_Assert(result.second, "Failed to insert FindData entry for filePath %s", filePath);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -164,7 +171,7 @@ namespace AZ::IO
|
||||
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive;
|
||||
fileDesc.nSize = fileEntry->desc.lSizeUncompressed;
|
||||
fileDesc.tWrite = fileEntry->GetModificationTime();
|
||||
m_mapFiles.emplace(fname, fileDesc);
|
||||
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
|
||||
}
|
||||
|
||||
ZipDir::FindDir findDirectoryEntry(zipCache);
|
||||
@@ -177,7 +184,7 @@ namespace AZ::IO
|
||||
}
|
||||
AZ::IO::FileDesc fileDesc;
|
||||
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
m_mapFiles.emplace(fname, fileDesc);
|
||||
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -246,7 +253,7 @@ namespace AZ::IO
|
||||
if (!bindRootIter->empty() && AZStd::wildcard_match(sourcePathRemainder.Native(), bindRootIter->Native()))
|
||||
{
|
||||
AZ::IO::FileDesc fileDesc{ AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory };
|
||||
m_mapFiles.emplace(bindRootIter->Native(), fileDesc);
|
||||
m_fileStack.emplace_back(AZ::IO::ArchiveFileIterator{ this, bindRootIter->Native(), fileDesc });
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -262,22 +269,19 @@ namespace AZ::IO
|
||||
|
||||
AZ::IO::ArchiveFileIterator FindData::Fetch()
|
||||
{
|
||||
AZ::IO::ArchiveFileIterator fileIterator;
|
||||
fileIterator.m_findData = this;
|
||||
if (m_mapFiles.empty())
|
||||
if (m_fileStack.empty())
|
||||
{
|
||||
return fileIterator;
|
||||
AZ::IO::ArchiveFileIterator emptyFileIterator;
|
||||
emptyFileIterator.m_lastFetchValid = false;
|
||||
emptyFileIterator.m_findData = this;
|
||||
return emptyFileIterator;
|
||||
}
|
||||
|
||||
auto pakFileIter = m_mapFiles.begin();
|
||||
AZStd::string fullFilePath;
|
||||
AZ::StringFunc::Path::GetFullFileName(pakFileIter->first.c_str(), fullFilePath);
|
||||
fileIterator.m_filename = AZStd::move(fullFilePath);
|
||||
fileIterator.m_fileDesc = pakFileIter->second;
|
||||
fileIterator.m_lastFetchValid = true;
|
||||
|
||||
// Remove Fetched item from the FindData map so that the iteration continues
|
||||
m_mapFiles.erase(pakFileIter);
|
||||
AZ::IO::ArchiveFileIterator fileIterator{ m_fileStack.back() };
|
||||
fileIterator.m_lastFetchValid = true;
|
||||
fileIterator.m_findData = this;
|
||||
m_fileStack.pop_back();
|
||||
return fileIterator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
struct IArchive;
|
||||
@@ -74,13 +73,13 @@ namespace AZ::IO
|
||||
AZ_CLASS_ALLOCATOR(FindData, AZ::SystemAllocator, 0);
|
||||
FindData() = default;
|
||||
AZ::IO::ArchiveFileIterator Fetch();
|
||||
void Scan(IArchive* archive, AZStd::string_view path, bool bAllowUseFS = false);
|
||||
void Scan(IArchive* archive, AZStd::string_view path, bool bAllowUseFS = false, bool bScanZips = true);
|
||||
|
||||
protected:
|
||||
void ScanFS(IArchive* archive, AZStd::string_view path);
|
||||
void ScanZips(IArchive* archive, AZStd::string_view path);
|
||||
|
||||
using FileMap = AZStd::map<AZStd::string, AZ::IO::FileDesc, AZStdStringLessCaseInsensitive>;
|
||||
FileMap m_mapFiles;
|
||||
using FileStack = AZStd::vector<ArchiveFileIterator>;
|
||||
FileStack m_fileStack;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -197,6 +197,13 @@ namespace AZ::IO
|
||||
eInMemoryPakLocale_PAK,
|
||||
};
|
||||
|
||||
enum EFileSearchType
|
||||
{
|
||||
eFileSearchType_AllowInZipsOnly = 0,
|
||||
eFileSearchType_AllowOnDiskAndInZips,
|
||||
eFileSearchType_AllowOnDiskOnly
|
||||
};
|
||||
|
||||
using SignedFileSize = int64_t;
|
||||
|
||||
virtual ~IArchive() = default;
|
||||
@@ -315,7 +322,7 @@ namespace AZ::IO
|
||||
|
||||
// Arguments:
|
||||
// nFlags is a combination of EPathResolutionRules flags.
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0;
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, EFileSearchType searchType = eFileSearchType_AllowInZipsOnly) = 0;
|
||||
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
//returns file modification time
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace AzFramework
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(RequestEscalateAsset, AZ::OSAllocator, 0);
|
||||
AZ_RTTI(RequestAssetStatus, "{E95C5422-5F00-478B-A984-C041DE70484F}", BaseAssetProcessorMessage);
|
||||
AZ_RTTI(RequestEscalateAsset, "{E95C5422-5F00-478B-A984-C041DE70484F}", BaseAssetProcessorMessage);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static constexpr unsigned int MessageType = AZ_CRC("AssetSystem::RequestEscalateAsset", 0x1894d94e);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzPhysics
|
||||
//! Each Physics Scene uses this as a base and will override as needed.
|
||||
CollisionConfiguration m_collisionConfig;
|
||||
|
||||
Physics::MaterialConfiguration m_defaultMaterialConfiguration; //!< Default material parameters for the project.
|
||||
Physics::DefaultMaterialConfiguration m_defaultMaterialConfiguration; //!< Default material parameters for the project.
|
||||
AZ::Data::Asset<Physics::MaterialLibraryAsset> m_materialLibraryAsset = AZ::Data::AssetLoadBehavior::NoLoad; //!< Material Library exposed by the system component SystemBus API.
|
||||
|
||||
//! Controls whether the Physics System will self register to the TickBus and call StartSimulation / FinishSimulation on each Scene.
|
||||
|
||||
@@ -83,14 +83,12 @@ namespace Physics
|
||||
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
||||
if (editContext)
|
||||
{
|
||||
AZStd::unordered_set<AZStd::string> forbiddenSurfaceTypeNames;
|
||||
forbiddenSurfaceTypeNames.insert("Default");
|
||||
editContext->Class<Physics::MaterialConfiguration>("", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "Physics Material")
|
||||
->DataElement(MaterialConfiguration::s_configLineEdit, &MaterialConfiguration::m_surfaceType, "Surface type", "Game surface type") // Uses ConfigStringLineEditCtrl in PhysX gem.
|
||||
->DataElement(MaterialConfiguration::s_configLineEdit, &MaterialConfiguration::m_surfaceType, "Name", "Name of the physics material") // Uses ConfigStringLineEditCtrl in PhysX gem.
|
||||
->Attribute(AZ::Edit::Attributes::MaxLength, 64)
|
||||
->Attribute(AZ::Edit::Attributes::ReadOnly, &MaterialConfiguration::IsNameReadOnly)
|
||||
->Attribute(MaterialConfiguration::s_stringGroup, AZ_CRC("LineEditGroupSurfaceType", 0x6670659e))
|
||||
->Attribute(MaterialConfiguration::s_forbiddenStringSet, forbiddenSurfaceTypeNames)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialConfiguration::m_staticFriction, "Static friction", "Friction coefficient when object is still")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialConfiguration::m_dynamicFriction, "Dynamic friction", "Friction coefficient when object is moving")
|
||||
@@ -178,6 +176,23 @@ namespace Physics
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DefaultMaterialConfiguration::DefaultMaterialConfiguration()
|
||||
{
|
||||
m_surfaceType = Physics::DefaultPhysicsMaterialLabel;
|
||||
}
|
||||
|
||||
void DefaultMaterialConfiguration::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<Physics::DefaultMaterialConfiguration, Physics::MaterialConfiguration>()
|
||||
->Version(1)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MaterialLibraryAsset::Reflect(AZ::ReflectContext * context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
@@ -212,7 +227,7 @@ namespace Physics
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<Physics::MaterialInfoReflectionWrapper>()
|
||||
->Version(1)
|
||||
->Version(2)
|
||||
->Field("DefaultMaterial", &MaterialInfoReflectionWrapper::m_defaultMaterialConfiguration)
|
||||
->Field("Asset", &MaterialInfoReflectionWrapper::m_materialLibraryAsset)
|
||||
;
|
||||
@@ -300,7 +315,7 @@ namespace Physics
|
||||
{
|
||||
auto foundMaterialConfiguration = AZStd::find_if(m_materialLibrary.begin(), m_materialLibrary.end(), [&materialName](const auto& data)
|
||||
{
|
||||
return data.m_configuration.m_surfaceType == materialName;
|
||||
return AZ::StringFunc::Equal(data.m_configuration.m_surfaceType, materialName, false/*bCaseSensitive*/);
|
||||
});
|
||||
|
||||
if (foundMaterialConfiguration != m_materialLibrary.end())
|
||||
@@ -372,20 +387,28 @@ namespace Physics
|
||||
serializeContext->Class<Physics::MaterialSelection>()
|
||||
->Version(3, &ClassConverters::MaterialSelectionConverter)
|
||||
->EventHandler<MaterialSelectionEventHandler>()
|
||||
->Field("EditContextMaterialLibrary", &MaterialSelection::m_editContextMaterialLibrary)
|
||||
->Field("MaterialIds", &MaterialSelection::m_materialIdsAssignedToSlots)
|
||||
;
|
||||
|
||||
if (auto editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<Physics::MaterialSelection>("Physics Material", "Select physics material library and which materials to use for the object")
|
||||
editContext->Class<Physics::MaterialSelection>("Physics Materials", "Select which physics materials to use for each element of this object")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "Mesh Surfaces", "Specify which Physics Material to use for each element of this object")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_editContextMaterialLibrary, "Library", "Physics material library from PhysX Configuration")
|
||||
->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false)
|
||||
->Attribute(AZ_CRC_CE("BrowseButtonEnabled"), false)
|
||||
->Attribute(AZ_CRC_CE("EditButton"), "")
|
||||
->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor")
|
||||
->Attribute(AZ::Edit::Attributes::DefaultAsset, &MaterialSelection::GetMaterialLibraryId)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "", "")
|
||||
->ElementAttribute(Attributes::MaterialLibraryAssetId, &MaterialSelection::GetMaterialLibraryId)
|
||||
->Attribute(AZ::Edit::Attributes::IndexedChildNameLabelOverride, &MaterialSelection::GetMaterialSlotLabel)
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->ElementAttribute(AZ::Edit::Attributes::ReadOnly, &MaterialSelection::AreMaterialSlotsReadOnly)
|
||||
->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace AZ
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
static constexpr AZStd::string_view DefaultPhysicsMaterialLabel = "<Default Physics Material>";
|
||||
|
||||
/// Physics material
|
||||
/// =========================
|
||||
/// This is the interface to the wrapper around native material type (such as PxMaterial in PhysX gem)
|
||||
@@ -97,10 +99,13 @@ namespace Physics
|
||||
class MaterialConfiguration
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(Physics::MaterialConfiguration, "{8807CAA1-AD08-4238-8FDB-2154ADD084A1}");
|
||||
AZ_RTTI(Physics::MaterialConfiguration, "{8807CAA1-AD08-4238-8FDB-2154ADD084A1}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
MaterialConfiguration() = default;
|
||||
virtual ~MaterialConfiguration() = default;
|
||||
|
||||
const static AZ::Crc32 s_stringGroup; ///< Edit context data attribute. Identifies a string group instance. String values in the same group are unique.
|
||||
const static AZ::Crc32 s_forbiddenStringSet; ///< Edit context data attribute. A set of strings that are not acceptable as values to the data element. Can be AZStd::unordered_set<AZStd::string>, AZStd::set<AZStd::string>, AZStd::vector<AZStd::string>
|
||||
const static AZ::Crc32 s_configLineEdit; ///< Edit context data element handler. Creates custom line edit widget that allows string values to be unique in a group.
|
||||
@@ -121,11 +126,28 @@ namespace Physics
|
||||
bool operator==(const MaterialConfiguration& other) const;
|
||||
bool operator!=(const MaterialConfiguration& other) const;
|
||||
|
||||
protected:
|
||||
virtual bool IsNameReadOnly() const { return false; }
|
||||
|
||||
private:
|
||||
static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
|
||||
static AZ::Color GenerateDebugColor(const char* materialName);
|
||||
};
|
||||
|
||||
class DefaultMaterialConfiguration
|
||||
: public MaterialConfiguration
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(Physics::DefaultMaterialConfiguration, "{A1F64C5C-D413-4757-9D42-51DD0EBFC270}", Physics::MaterialConfiguration);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
DefaultMaterialConfiguration();
|
||||
|
||||
protected:
|
||||
bool IsNameReadOnly() const override { return true; }
|
||||
};
|
||||
|
||||
namespace Attributes
|
||||
{
|
||||
const static AZ::Crc32 MaterialLibraryAssetId = AZ_CRC("MaterialAssetId", 0x4a88a3f5);
|
||||
@@ -237,7 +259,7 @@ namespace Physics
|
||||
AZ_TYPE_INFO(Physics::MaterialInfoReflectionWrapper, "{02AB8CBC-D35B-4E0F-89BA-A96D94DAD4F9}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
Physics::MaterialConfiguration m_defaultMaterialConfiguration;
|
||||
Physics::DefaultMaterialConfiguration m_defaultMaterialConfiguration;
|
||||
AZ::Data::Asset<Physics::MaterialLibraryAsset> m_materialLibraryAsset =
|
||||
AZ::Data::AssetLoadBehavior::NoLoad;
|
||||
};
|
||||
@@ -296,6 +318,10 @@ namespace Physics
|
||||
|
||||
// EditorContext callbacks
|
||||
AZStd::string GetMaterialSlotLabel(int index);
|
||||
|
||||
// Only used for Edit Context as it requires to have an asset reflected.
|
||||
// To get the material library use GetMaterialLibraryId()
|
||||
AZ::Data::Asset<Physics::MaterialLibraryAsset> m_editContextMaterialLibrary{ AZ::Data::AssetLoadBehavior::NoLoad };
|
||||
};
|
||||
|
||||
/// Editor Bus used to assign material to terrain surface id.
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Physics
|
||||
->Attribute(AZ::Edit::Attributes::Step, 0.01f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ColliderConfiguration::m_rotation, "Rotation", "Local rotation relative to the rigid body")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &ColliderConfiguration::GetOffsetVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ColliderConfiguration::m_materialSelection, "Physics Material", "Select physics material library and which materials to use for the shape")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ColliderConfiguration::m_materialSelection, "Physics Materials", "Select which physics materials to use for each element of this shape")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &ColliderConfiguration::GetMaterialSelectionVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ColliderConfiguration::m_tag, "Tag", "Tag used to identify colliders from one another")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ColliderConfiguration::m_restOffset, "Rest offset",
|
||||
|
||||
@@ -17,21 +17,6 @@
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
bool ShapeConfigurationVersionConverter(
|
||||
[[maybe_unused]] AZ::SerializeContext& context,
|
||||
AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
if (classElement.GetVersion() <= 1)
|
||||
{
|
||||
classElement.RemoveElementByName(AZ_CRC_CE("UseMaterialsFromAsset"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ShapeConfiguration::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
@@ -181,9 +166,10 @@ namespace Physics
|
||||
->RegisterGenericType<AZStd::shared_ptr<PhysicsAssetShapeConfiguration>>();
|
||||
|
||||
serializeContext->Class<PhysicsAssetShapeConfiguration, ShapeConfiguration>()
|
||||
->Version(2, &Internal::ShapeConfigurationVersionConverter)
|
||||
->Version(3)
|
||||
->Field("PhysicsAsset", &PhysicsAssetShapeConfiguration::m_asset)
|
||||
->Field("AssetScale", &PhysicsAssetShapeConfiguration::m_assetScale)
|
||||
->Field("UseMaterialsFromAsset", &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset)
|
||||
->Field("SubdivisionLevel", &PhysicsAssetShapeConfiguration::m_subdivisionLevel)
|
||||
;
|
||||
|
||||
@@ -196,6 +182,7 @@ namespace Physics
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &PhysicsAssetShapeConfiguration::m_assetScale, "Asset Scale", "The scale of the asset shape")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(AZ::Edit::Attributes::Step, 0.01f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset, "Physics materials from asset", "Auto-set physics materials using asset's physics material names")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Physics
|
||||
|
||||
AZ::Data::Asset<AZ::Data::AssetData> m_asset{ AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
AZ::Vector3 m_assetScale = AZ::Vector3::CreateOne();
|
||||
bool m_useMaterialsFromAsset = false; // Not reflected or exposed to the user until there is a way to auto-match mesh's materials with physics materials
|
||||
bool m_useMaterialsFromAsset = true;
|
||||
AZ::u8 m_subdivisionLevel = 4; ///< The level of subdivision if a primitive shape is replaced with a convex mesh due to scaling.
|
||||
};
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace Physics
|
||||
AzPhysics::TriggerEvent::Reflect(context);
|
||||
AzPhysics::SceneConfiguration::Reflect(context);
|
||||
MaterialConfiguration::Reflect(context);
|
||||
DefaultMaterialConfiguration::Reflect(context);
|
||||
MaterialLibraryAsset::Reflect(context);
|
||||
MaterialInfoReflectionWrapper::Reflect(context);
|
||||
JointLimitConfiguration::Reflect(context);
|
||||
|
||||
@@ -693,11 +693,11 @@ namespace AzFramework
|
||||
// set the __index so we can read values in case we change the script
|
||||
// after we export the component
|
||||
lua_pushliteral(lua, "__index");
|
||||
lua_pushcclosure(lua, &Internal::Properties__Index, 1);
|
||||
lua_pushcclosure(lua, &Internal::Properties__Index, 0);
|
||||
lua_rawset(lua, -3);
|
||||
|
||||
lua_pushliteral(lua, "__newindex");
|
||||
lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1);
|
||||
lua_pushcclosure(lua, &Internal::Properties__NewIndex, 0);
|
||||
lua_rawset(lua, -3);
|
||||
}
|
||||
lua_pop(lua, 1); // pop the properties table (or the nil value)
|
||||
@@ -900,11 +900,11 @@ namespace AzFramework
|
||||
// Ensure that this instance of Properties table has the proper __index and __newIndex metamethods.
|
||||
lua_newtable(lua); // This new table will become the Properties instance metatable. Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {}
|
||||
lua_pushliteral(lua, "__index"); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index
|
||||
lua_pushcclosure(lua, &Internal::Properties__Index, 1); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index function
|
||||
lua_pushcclosure(lua, &Internal::Properties__Index, 0); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index function
|
||||
lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index}
|
||||
|
||||
lua_pushliteral(lua, "__newindex");
|
||||
lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1);
|
||||
lua_pushcclosure(lua, &Internal::Properties__NewIndex, 0);
|
||||
lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex}
|
||||
lua_setmetatable(lua, -2); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {Meta{__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} }
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
//! ISessionHandlingClientRequests
|
||||
//! The session handling events to invoke multiplayer component handle the work on client side
|
||||
//! Requests made to the client to manage their membership in a session
|
||||
class ISessionHandlingClientRequests
|
||||
{
|
||||
public:
|
||||
@@ -63,14 +63,14 @@ namespace AzFramework
|
||||
virtual void RequestPlayerLeaveSession() = 0;
|
||||
};
|
||||
|
||||
//! ISessionHandlingServerRequests
|
||||
//! The session handling events to invoke server provider handle the work on server side
|
||||
class ISessionHandlingServerRequests
|
||||
//! ISessionProviderRequests
|
||||
//! Requests made to the service providing server/fleet management by the server
|
||||
class ISessionHandlingProviderRequests
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ISessionHandlingServerRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}");
|
||||
ISessionHandlingServerRequests() = default;
|
||||
virtual ~ISessionHandlingServerRequests() = default;
|
||||
AZ_RTTI(ISessionHandlingProviderRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}");
|
||||
ISessionHandlingProviderRequests() = default;
|
||||
virtual ~ISessionHandlingProviderRequests() = default;
|
||||
|
||||
// Handle the destroy session process
|
||||
virtual void HandleDestroySession() = 0;
|
||||
@@ -84,9 +84,14 @@ namespace AzFramework
|
||||
// @param playerConnectionConfig The required properties to handle the player leave session process
|
||||
virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
|
||||
|
||||
// Retrieves the file location of a pem-encoded TLS certificate
|
||||
// Retrieves the file location of a pem-encoded TLS certificate for Client to Server communication
|
||||
// @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
// empty string.
|
||||
virtual AZStd::string GetSessionCertificate() = 0;
|
||||
virtual AZ::IO::Path GetExternalSessionCertificate() = 0;
|
||||
|
||||
// Retrieves the file location of a pem-encoded TLS certificate for Server to Server communication
|
||||
// @return If successful, returns the file location of TLS certificate file; if not successful, returns
|
||||
// empty string.
|
||||
virtual AZ::IO::Path GetInternalSessionCertificate() = 0;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -322,12 +322,6 @@ namespace AzFramework
|
||||
//! @param optionalArgs Optional additional arguments, see BarrierOptionalArgs.
|
||||
virtual void Barrier(EntitySpawnTicket& ticket, BarrierCallback completionCallback, BarrierOptionalArgs optionalArgs = {}) = 0;
|
||||
|
||||
//! Register a handler for OnSpawned events.
|
||||
virtual void AddOnSpawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler) = 0;
|
||||
|
||||
//! Register a handler for OnDespawned events.
|
||||
virtual void AddOnDespawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler) = 0;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual AZStd::pair<EntitySpawnTicket::Id, void*> CreateTicket(AZ::Data::Asset<Spawnable>&& spawnable) = 0;
|
||||
virtual void DestroyTicket(void* ticket) = 0;
|
||||
|
||||
@@ -150,16 +150,6 @@ namespace AzFramework
|
||||
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
|
||||
}
|
||||
|
||||
void SpawnableEntitiesManager::AddOnSpawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_onSpawnedEvent);
|
||||
}
|
||||
|
||||
void SpawnableEntitiesManager::AddOnDespawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_onDespawnedEvent);
|
||||
}
|
||||
|
||||
auto SpawnableEntitiesManager::ProcessQueue(CommandQueuePriority priority) -> CommandQueueStatus
|
||||
{
|
||||
CommandQueueStatus result = CommandQueueStatus::NoCommandsLeft;
|
||||
@@ -320,8 +310,6 @@ namespace AzFramework
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
ticket.m_currentRequestId++;
|
||||
return true;
|
||||
}
|
||||
@@ -401,8 +389,6 @@ namespace AzFramework
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
ticket.m_currentRequestId++;
|
||||
return true;
|
||||
}
|
||||
@@ -434,8 +420,6 @@ namespace AzFramework
|
||||
request.m_completionCallback(request.m_ticketId);
|
||||
}
|
||||
|
||||
m_onDespawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
ticket.m_currentRequestId++;
|
||||
return true;
|
||||
}
|
||||
@@ -463,8 +447,6 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
m_onDespawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
// Rebuild the list of entities.
|
||||
ticket.m_spawnedEntities.clear();
|
||||
const Spawnable::EntityList& entities = request.m_spawnable->GetEntities();
|
||||
@@ -517,8 +499,6 @@ namespace AzFramework
|
||||
|
||||
ticket.m_currentRequestId++;
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -73,9 +73,6 @@ namespace AzFramework
|
||||
|
||||
void Barrier(EntitySpawnTicket& spawnInfo, BarrierCallback completionCallback, BarrierOptionalArgs optionalArgs = {}) override;
|
||||
|
||||
void AddOnSpawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler) override;
|
||||
void AddOnDespawnedHandler(AZ::Event<AZ::Data::Asset<Spawnable>>::Handler& handler) override;
|
||||
|
||||
//
|
||||
// The following function is thread safe but intended to be run from the main thread.
|
||||
//
|
||||
@@ -200,9 +197,6 @@ namespace AzFramework
|
||||
Queue m_highPriorityQueue;
|
||||
Queue m_regularPriorityQueue;
|
||||
|
||||
AZ::Event<AZ::Data::Asset<Spawnable>> m_onSpawnedEvent;
|
||||
AZ::Event<AZ::Data::Asset<Spawnable>> m_onDespawnedEvent;
|
||||
|
||||
AZ::SerializeContext* m_defaultSerializeContext { nullptr };
|
||||
//! The threshold used to determine if a request goes in the regular (if bigger than the value) or high priority queue (if smaller
|
||||
//! or equal to this value). The starting value of 64 is chosen as it's between default values SpawnablePriority_High and
|
||||
|
||||
@@ -28,19 +28,8 @@ namespace AzFramework
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The default height of the ground plane to do intersection tests against when orbiting");
|
||||
AZ_CVAR(float, ed_cameraSystemBoostMultiplier, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSpeed, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemPanSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertX, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertY, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
@@ -121,6 +110,13 @@ namespace AzFramework
|
||||
|
||||
AZ_CONSOLEFREEFUNC(ReloadCameraKeyBindingsConsole, AZ::ConsoleFunctorFlags::Null, "Reload keybindings for the modern camera system");
|
||||
|
||||
//! return -1.0f if inverted, 1.0f otherwise
|
||||
constexpr static float Invert(const bool invert)
|
||||
{
|
||||
constexpr float Dir[] = { 1.0f, -1.0f };
|
||||
return Dir[aznumeric_cast<int>(invert)];
|
||||
};
|
||||
|
||||
// Based on paper by David Eberly - https://www.geometrictools.com/Documentation/EulerAngles.pdf
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation)
|
||||
{
|
||||
@@ -291,6 +287,20 @@ namespace AzFramework
|
||||
RotateCameraInput::RotateCameraInput(const InputChannelId rotateChannelId)
|
||||
: m_rotateChannelId(rotateChannelId)
|
||||
{
|
||||
m_rotateSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.005f;
|
||||
};
|
||||
|
||||
m_invertPitchFn = []() constexpr
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
m_invertYawFn = []() constexpr
|
||||
{
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
bool RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
@@ -341,8 +351,9 @@ namespace AzFramework
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed;
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed;
|
||||
const float rotateSpeed = m_rotateSpeedFn();
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
|
||||
const auto clampRotation = [](const float angle)
|
||||
{
|
||||
@@ -360,6 +371,20 @@ namespace AzFramework
|
||||
: m_panAxesFn(AZStd::move(panAxesFn))
|
||||
, m_panChannelId(panChannelId)
|
||||
{
|
||||
m_panSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.01f;
|
||||
};
|
||||
|
||||
m_invertPanXFn = []() constexpr
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
m_invertPanYFn = []() constexpr
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
bool PanCameraInput::HandleEvents(
|
||||
@@ -393,17 +418,12 @@ namespace AzFramework
|
||||
|
||||
const auto panAxes = m_panAxesFn(nextCamera);
|
||||
|
||||
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * ed_cameraSystemPanSpeed;
|
||||
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * ed_cameraSystemPanSpeed;
|
||||
const float panSpeed = m_panSpeedFn();
|
||||
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * panSpeed;
|
||||
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * panSpeed;
|
||||
|
||||
const auto inv = [](const bool invert)
|
||||
{
|
||||
constexpr float Dir[] = { 1.0f, -1.0f };
|
||||
return Dir[aznumeric_cast<int>(invert)];
|
||||
};
|
||||
|
||||
nextCamera.m_lookAt += deltaPanX * inv(ed_cameraSystemPanInvertX);
|
||||
nextCamera.m_lookAt += deltaPanY * -inv(ed_cameraSystemPanInvertY);
|
||||
nextCamera.m_lookAt += deltaPanX * Invert(m_invertPanXFn());
|
||||
nextCamera.m_lookAt += deltaPanY * -Invert(m_invertPanYFn());
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -446,6 +466,15 @@ namespace AzFramework
|
||||
TranslateCameraInput::TranslateCameraInput(TranslationAxesFn translationAxesFn)
|
||||
: m_translationAxesFn(AZStd::move(translationAxesFn))
|
||||
{
|
||||
m_translateSpeedFn = []() constexpr
|
||||
{
|
||||
return 10.0f;
|
||||
};
|
||||
|
||||
m_boostMultiplierFn = []() constexpr
|
||||
{
|
||||
return 3.0f;
|
||||
};
|
||||
}
|
||||
|
||||
bool TranslateCameraInput::HandleEvents(
|
||||
@@ -497,9 +526,9 @@ namespace AzFramework
|
||||
const auto axisY = translationBasis.GetBasisY();
|
||||
const auto axisZ = translationBasis.GetBasisZ();
|
||||
|
||||
const float speed = [boost = m_boost]()
|
||||
const float speed = [boost = m_boost, &translateSpeedFn = m_translateSpeedFn, &boostMultiplierFn = m_boostMultiplierFn]()
|
||||
{
|
||||
return ed_cameraSystemTranslateSpeed * (boost ? ed_cameraSystemBoostMultiplier : 1.0f);
|
||||
return translateSpeedFn() * (boost ? boostMultiplierFn() : 1.0f);
|
||||
}();
|
||||
|
||||
if ((m_translation & TranslationType::Forward) == TranslationType::Forward)
|
||||
@@ -632,6 +661,14 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
OrbitDollyScrollCameraInput::OrbitDollyScrollCameraInput()
|
||||
{
|
||||
m_scrollSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.03f;
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyScrollCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
@@ -650,7 +687,7 @@ namespace AzFramework
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * ed_cameraSystemOrbitDollyScrollSpeed, 0.0f);
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_scrollSpeedFn(), 0.0f);
|
||||
EndActivation();
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -658,6 +695,10 @@ namespace AzFramework
|
||||
OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId)
|
||||
: m_dollyChannelId(dollyChannelId)
|
||||
{
|
||||
m_cursorSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.01f;
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyCursorMoveCameraInput::HandleEvents(
|
||||
@@ -688,10 +729,18 @@ namespace AzFramework
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * ed_cameraSystemOrbitDollyCursorSpeed, 0.0f);
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_cursorSpeedFn(), 0.0f);
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
ScrollTranslationCameraInput::ScrollTranslationCameraInput()
|
||||
{
|
||||
m_scrollSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.02f;
|
||||
};
|
||||
}
|
||||
|
||||
bool ScrollTranslationCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
@@ -714,14 +763,14 @@ namespace AzFramework
|
||||
const auto translation_basis = LookTranslation(nextCamera);
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * ed_cameraSystemScrollTranslateSpeed;
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * m_scrollSpeedFn();
|
||||
|
||||
EndActivation();
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime)
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const CameraProps& cameraProps, const float deltaTime)
|
||||
{
|
||||
const auto clamp_rotation = [](const float angle)
|
||||
{
|
||||
@@ -748,11 +797,11 @@ namespace AzFramework
|
||||
Camera camera;
|
||||
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
|
||||
// article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
|
||||
const float lookRate = AZStd::exp2(ed_cameraSystemLookSmoothness);
|
||||
const float lookRate = AZStd::exp2(cameraProps.m_rotateSmoothnessFn());
|
||||
const float lookT = AZStd::exp2(-lookRate * deltaTime);
|
||||
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT);
|
||||
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT);
|
||||
const float moveRate = AZStd::exp2(ed_cameraSystemTranslateSmoothness);
|
||||
const float moveRate = AZStd::exp2(cameraProps.m_translateSmoothnessFn());
|
||||
const float moveT = AZStd::exp2(-moveRate * deltaTime);
|
||||
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
|
||||
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT);
|
||||
|
||||
@@ -170,7 +170,14 @@ namespace AzFramework
|
||||
Activation m_activation = Activation::Idle;
|
||||
};
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, float deltaTime);
|
||||
//! Properties to use to configure behavior across all types of camera.
|
||||
struct CameraProps
|
||||
{
|
||||
AZStd::function<float()> m_rotateSmoothnessFn; //!< Rotate smoothing value (useful approx range 3-6, higher values give sharper feel).
|
||||
AZStd::function<float()> m_translateSmoothnessFn; //!< Translate smoothing value (useful approx range 3-6, higher values give sharper feel).
|
||||
};
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const CameraProps& cameraProps, float deltaTime);
|
||||
|
||||
class Cameras
|
||||
{
|
||||
@@ -225,6 +232,10 @@ namespace AzFramework
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
AZStd::function<float()> m_rotateSpeedFn;
|
||||
AZStd::function<bool()> m_invertPitchFn;
|
||||
AZStd::function<bool()> m_invertYawFn;
|
||||
|
||||
private:
|
||||
InputChannelId m_rotateChannelId;
|
||||
ClickDetector m_clickDetector;
|
||||
@@ -267,6 +278,10 @@ namespace AzFramework
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
AZStd::function<float()> m_panSpeedFn;
|
||||
AZStd::function<bool()> m_invertPanXFn;
|
||||
AZStd::function<bool()> m_invertPanYFn;
|
||||
|
||||
private:
|
||||
PanAxesFn m_panAxesFn;
|
||||
InputChannelId m_panChannelId;
|
||||
@@ -310,6 +325,9 @@ namespace AzFramework
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
void ResetImpl() override;
|
||||
|
||||
AZStd::function<float()> m_translateSpeedFn;
|
||||
AZStd::function<float()> m_boostMultiplierFn;
|
||||
|
||||
private:
|
||||
enum class TranslationType
|
||||
{
|
||||
@@ -375,9 +393,13 @@ namespace AzFramework
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
OrbitDollyScrollCameraInput();
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
AZStd::function<float()> m_scrollSpeedFn;
|
||||
};
|
||||
|
||||
class OrbitDollyCursorMoveCameraInput : public CameraInput
|
||||
@@ -389,6 +411,8 @@ namespace AzFramework
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
AZStd::function<float()> m_cursorSpeedFn;
|
||||
|
||||
private:
|
||||
InputChannelId m_dollyChannelId;
|
||||
};
|
||||
@@ -396,9 +420,13 @@ namespace AzFramework
|
||||
class ScrollTranslationCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
ScrollTranslationCameraInput();
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
AZStd::function<float()> m_scrollSpeedFn;
|
||||
};
|
||||
|
||||
class OrbitCameraInput : public CameraInput
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
|
||||
@@ -180,10 +180,7 @@ namespace AzNetworking
|
||||
//! Takes a quantized integral value and stores the floating point representation.
|
||||
void DecodeQuantizedValues();
|
||||
|
||||
# if defined AZ_COMPILER_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4201) // anonymous union
|
||||
# endif
|
||||
AZ_PUSH_DISABLE_WARNING(4201 4324, "-Wunknown-warning-option") // anonymous union, structure was padded due to alignment
|
||||
union
|
||||
{
|
||||
float m_quantizedValues[NUM_ELEMENTS];
|
||||
@@ -195,9 +192,7 @@ namespace AzNetworking
|
||||
uint32_t m_serializeValues[NUM_ELEMENTS];
|
||||
SimdTypei m_serializeVector;
|
||||
};
|
||||
# if defined AZ_COMPILER_MSVC
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
template <AZStd::size_t NUM_ELEMENTS2, AZStd::size_t NUM_BYTES2, int32_t MIN_VALUE2, int32_t MAX_VALUE2>
|
||||
friend struct QuantizedValuesConversionHelper;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Asset Editor icon</title>
|
||||
<g id="Asset-Editor-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M15.9860086,2 L21.0547888,7.65093732 L21.0547888,19.8573598 C21.0547888,21.3071072 19.8795363,22.4823598 18.4297888,22.4823598 L18.4297888,22.4823598 L14.4922888,22.4823598 L14.4922888,19.8573598 L18.4297888,19.8573598 L18.4297888,9.39834532 L14.4922888,9.39834532 L14.4922888,4.39834532 L6.61728879,4.39834532 L6.61728879,9.39834532 L3.99228879,9.39834532 L3.99228879,4.625 C3.99228879,3.17525253 5.16754132,2 6.61728879,2 L6.61728879,2 L15.9860086,2 Z M11.9720779,11.5111613 L11.9720779,22.4823598 L3.99403128,22.4823598 C2.89373128,22.4823598 2,21.5871399 2,20.4828299 L2,20.4828299 L2,13.5106911 C2,12.4089803 2.89275834,11.5111613 3.99403128,11.5111613 L3.99403128,11.5111613 L11.9720779,11.5111613 Z M5.17089634,17.6663021 L4.40036064,18.4676192 C4.18355844,18.6930823 4.18043717,19.0553841 4.39605961,19.2796209 L6.20782094,21.1637586 C6.63740095,21.610499 7.33388742,21.610499 7.76346744,21.1637586 L9.57522877,19.2796209 C9.7896555,19.0566276 9.79105801,18.6965433 9.57092774,18.4676192 L8.80039204,17.6663021 C8.58358984,17.4408391 8.23344799,17.4394206 8.01921651,17.6622102 L6.98564419,18.7447072 L5.95207186,17.6622102 C5.73744273,17.439007 5.39102661,17.437378 5.17089634,17.6663021 Z M7.76346744,12.8297629 C7.33388742,12.3830219 6.63740095,12.3830219 6.20782094,12.8297629 L6.20782094,12.8297629 L4.39605961,14.7139006 C4.18043717,14.9381368 4.18355844,15.3004386 4.40036064,15.5259017 L4.40036064,15.5259017 L5.17089634,16.3272188 C5.39102661,16.5561429 5.73744273,16.5545139 5.95207186,16.3313107 L5.95207186,16.3313107 L6.98564419,15.2447072 L8.01921651,16.3313107 C8.23344799,16.5541009 8.58358984,16.5526818 8.80039204,16.3272188 L8.80039204,16.3272188 L9.57092774,15.5259017 C9.79105801,15.2969782 9.7896555,14.9368933 9.57522877,14.7139006 L9.57522877,14.7139006 Z" id="Combined-Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>audio edit </title>
|
||||
<g id="audio-edit-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M13.671871,7.50274987 C13.8711246,7.36985092 14.1146568,7.32555128 14.3360497,7.41415057 C16.9554394,8.10079513 18.9091859,8.10079513 22.0258713,7.41415057 C22.249462,7.36489076 22.4907963,7.39200075 22.6679107,7.5248997 C22.845025,7.65779864 22.9557214,7.87929688 23,8.10079513 L23,8.10079513 L22.9572844,18.8481815 C22.9572844,20.1328713 21.7174842,21.173913 20.1013161,21.173913 C18.485148,21.173913 17.2453478,20.1550211 17.2453478,18.8481815 C17.2453478,17.5634917 18.5294265,16.5224499 20.1013161,16.5224499 C20.3669876,16.5224499 20.632659,16.5445998 20.8761912,16.6110492 C21.1861413,16.6996485 21.473952,16.4560005 21.473952,16.1459029 L21.473952,16.1459029 L21.473952,10.6858818 C18.8420026,11.3725264 17.0164667,11.3725264 14.7803985,10.7080316 L14.7803985,10.7080316 L14.7803985,11.8540584 C14.2459139,11.4245036 13.671871,10.911155 13.3192054,10.5828292 C13.3192054,9.943716 13.3334439,9.11637131 13.3619209,8.10079513 C13.3619209,7.85714706 13.4726174,7.63564882 13.671871,7.50274987 Z M13.0212906,15.3812912 C13.4908418,15.7574122 13.9909547,16.3565034 14.4824837,16.7283004 L14.4824837,16.7283004 L14.4824837,18.6657679 C14.4824837,19.9504578 13.2426835,20.9914995 11.6265154,20.9914995 C10.0103472,20.9914995 8.77054704,19.9726076 8.77054704,18.6657679 C8.77054704,17.3810781 10.0546258,16.3400364 11.6486547,16.3621862 C11.9143261,16.3621862 12.1799976,16.384336 12.4235298,16.4507855 C12.7334799,16.5393848 13.0212906,16.2957367 13.0212906,15.9856392 L13.0212906,15.9856392 Z M4.87344064,2.00000241 C6.46039809,2.00000241 7.74688128,3.28766393 7.74688128,4.87607492 C7.74688128,5.24562866 7.67724533,5.59890316 7.55039064,5.92346979 L9.18715351,7.56781732 L9.19255594,7.56260027 L10.6736079,9.04725227 L10.6664504,9.05409316 L17.0762969,15.3611124 L17.0762969,16.1842691 L14.856515,16.1842691 L9.10274173,10.5856018 L7.50474928,12.1508361 C7.66044683,12.5049585 7.74688128,12.8964744 7.74688128,13.3081966 C7.74688128,14.8966076 6.46039809,16.1842691 4.87344064,16.1842691 C3.2864832,16.1842691 2,14.8966076 2,13.3081966 C2,11.7197856 3.2864832,10.4321241 4.87344064,10.4321241 C5.28086048,10.4321241 5.66847595,10.5169943 6.01960261,10.6700351 L7.61573544,9.10677758 L6.01608448,7.51576697 C5.66588747,7.66784294 5.27950023,7.75214743 4.87344064,7.75214743 C3.2864832,7.75214743 2,6.4644859 2,4.87607492 C2,3.28766393 3.2864832,2.00000241 4.87344064,2.00000241 Z M4.87344064,11.902843 C4.09799553,11.902843 3.46937306,12.5320412 3.46937306,13.3081966 C3.46937306,14.084352 4.09799553,14.7135502 4.87344064,14.7135502 C5.64888576,14.7135502 6.27750823,14.084352 6.27750823,13.3081966 C6.27750823,12.5320412 5.64888576,11.902843 4.87344064,11.902843 Z M9.03871317,8.66478868 C8.79573029,8.66478868 8.59875374,8.86185896 8.59875374,9.10495747 C8.59875374,9.34805597 8.79573029,9.54512625 9.03871317,9.54512625 C9.28169606,9.54512625 9.47867261,9.34805597 9.47867261,9.10495747 C9.47867261,8.86185896 9.28169606,8.66478868 9.03871317,8.66478868 Z M17.0763008,2 L17.0763008,2.68379615 L11.1730797,8.47119228 L9.69202779,6.98654029 L14.856519,2 L17.0763008,2 Z M4.87344064,3.4707213 C4.09799553,3.4707213 3.46937306,4.09991955 3.46937306,4.87607492 C3.46937306,5.65223028 4.09799553,6.28142853 4.87344064,6.28142853 C5.64888576,6.28142853 6.27750823,5.65223028 6.27750823,4.87607492 C6.27750823,4.09991955 5.64888576,3.4707213 4.87344064,3.4707213 Z" id="Combined-Shape-Copy-6" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>EMFX header icon</title>
|
||||
<g id="EMFX-header-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M15.4402141,6.47369367 C15.8338027,6.6892261 16.1509659,7.03456112 16.3277603,7.4597408 L18.6714707,10.7388937 L20.9265998,13.1099302 L19.5883386,14.5962199 L17.1067913,11.9890965 L17.0892351,12 L16.9863785,11.8625904 L16.7718452,11.6372009 L16.7984797,11.6115701 L15.7677139,10.2345359 L14.2649089,13.609891 L16.9897118,16 L17,16 L17,22 L15,22 L15,16.9335637 L12.0517866,14.4145916 L11.7885832,14.2974059 L10.4131448,17.3866912 L9.63999106,19.1359308 L4,15.6954658 L5.05983853,13.9993696 L8.74227212,16.2223461 L9.96149233,13.4839327 L9.94559534,13.4768549 L12.0486395,8.75334034 L10.4719503,9.12452852 L8.88365054,12.0950967 L7.13441112,11.1254774 L9.14411801,7.42096143 L9.13441112,7.3871095 L14.1957216,6.24191249 L14.1971157,6.24907236 L14.2372583,6.24373869 L14.2372583,6.24373869 C14.6690994,6.19071527 15.0856649,6.27953958 15.4402141,6.47369367 Z M16.1344111,2 C17.2389806,2 18.1344111,2.8954305 18.1344111,4 C18.1344111,5.1045695 17.2389806,6 16.1344111,6 C15.0298416,6 14.1344111,5.1045695 14.1344111,4 C14.1344111,2.8954305 15.0298416,2 16.1344111,2 Z" id="Combined-Shape" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Veg editor icon </title>
|
||||
<g id="Veg-editor-icon-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M16.5148429,21.0425016 C16.8177068,21.0425016 17.1645673,21.2855646 17.1645673,21.7481048 C17.1645673,22.210645 16.8118623,22.453708 16.5148429,22.453708 L6.15659085,22.453708 C5.85372694,22.453708 5.50764574,22.2526162 5.50764574,21.7481048 C5.50764574,21.2435934 5.85957142,21.0425016 6.15659085,21.0425016 L16.5148429,21.0425016 Z M18.1293894,18.4805694 C18.5248398,18.4805694 18.783369,18.6215806 18.9803251,18.9179529 L21.3973486,21.6296028 C21.4913398,21.7733953 21.4260987,22.1575312 20.8849279,22.3133932 C20.3437571,22.4692552 19.8091487,22.2405042 19.7170269,22.0995716 L17.4957603,19.8222461 L5.51575322,19.8222461 L3.44599506,21.9708965 C3.25806678,22.2076933 2.65210839,22.4704438 2.11187863,22.3133932 C1.57164887,22.1563426 1.52319993,21.8555986 1.69847744,21.6296028 L4.15746187,18.8359298 C4.28086857,18.6216874 4.5612908,18.4805694 4.9475464,18.4805694 L18.1293894,18.4805694 Z M21.3923287,1.54629195 C21.9446135,1.54629195 22.3923287,1.9940072 22.3923287,2.54629195 L22.3923287,16.2168743 C22.3923287,16.7691591 21.9446135,17.2168743 21.3923287,17.2168743 L2.60767126,17.2168743 C2.05538651,17.2168743 1.60767126,16.7691591 1.60767126,16.2168743 L1.60767126,2.54629195 C1.60767126,1.9940072 2.05538651,1.54629195 2.60767126,1.54629195 L21.3923287,1.54629195 Z M8.80560763,15.9289985 C10.9624477,16.6479451 13.9204397,15.7983494 14.9166545,13.4126851 C15.9128692,11.0270207 15.0674988,8.36538278 17.161329,6.13505487 C18.5572159,4.6481696 19.9059881,3.55165429 21.2076457,2.84550893 C16.9581675,2.13086389 13.1202976,2.89580396 9.69403597,5.14032913 C6.83818733,7.01117991 5.46885511,9.11359981 5.50848138,11.7074507 C5.5219145,12.586754 6.05429493,13.5504113 7.10562269,14.5984226 C7.4393775,12.4421149 8.06340659,10.8285044 8.97770995,9.75759115 C9.89201332,8.68667789 11.2404975,7.64534569 13.0231626,6.63359455 C10.5695597,8.98708856 9.15459202,10.979178 8.77825968,12.6098629 C8.40192735,14.2405478 8.41104333,15.3469263 8.80560763,15.9289985 Z" id="Combined-Shape-Copy-2" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Lua icon</title>
|
||||
<defs>
|
||||
<path d="M10.3520891,2 L10.3520891,3.79011197 C8.61581127,3.83490503 7.22130691,4.52914353 7.22130691,5.96998687 L7.22130691,8.10833137 C7.22130691,9.71341592 6.37960225,11.5930873 4.69616767,11.8842422 L4.69616767,12.0186207 C6.37960225,12.3097756 7.22130691,13.8829731 7.22130691,15.4880576 L7.22130691,17.9428759 C7.22130691,18.7043579 7.44211284,19.2567973 7.88373133,19.6002108 C8.32534982,19.9436242 9.49904825,20.1713623 10.3520891,20.1862933 L10.3520891,22 C8.91777263,21.985069 7.17196328,21.7433437 6.38686374,21.1087754 C5.60176421,20.4742071 4.78557962,19.4352441 4.78557962,18.2855557 L4.78557962,15.1587647 C4.78557962,14.3823517 4.54778861,13.8280459 4.07219947,13.4958308 C3.59661033,13.1636156 2.90588408,12.9975105 2,12.9975105 L2,10.684195 C2.98137442,10.669264 3.69097297,10.4900945 4.12881694,10.146681 C4.56666091,9.80326759 4.78557962,9.27322436 4.78557962,8.55653545 L4.78557962,5.59798567 C4.78557962,4.4408317 5.61686205,3.68809925 6.43215772,3.04606543 C7.24745339,2.40403161 8.9781649,2 10.3520891,2 Z M13.6479109,2 C15.0218351,2 16.7525466,2.40403161 17.5678423,3.04606543 C18.383138,3.68809925 19.2144204,4.4408317 19.2144204,5.59798567 L19.2144204,5.59798567 L19.2144204,8.55653545 C19.2144204,9.27322436 19.4333391,9.80326759 19.8711831,10.146681 C20.309027,10.4900945 21.0186256,10.669264 22,10.684195 L22,10.684195 L22,12.9975105 C21.0941159,12.9975105 20.4033897,13.1636156 19.9278005,13.4958308 C19.4522114,13.8280459 19.2144204,14.3823517 19.2144204,15.1587647 L19.2144204,15.1587647 L19.2144204,18.2855557 C19.2144204,19.4352441 18.3982358,20.4742071 17.6131363,21.1087754 C16.8280367,21.7433437 15.0822274,21.985069 13.6479109,22 L13.6479109,22 L13.6479109,20.1862933 C14.5009518,20.1713623 15.6746502,19.9436242 16.1162687,19.6002108 C16.5578872,19.2567973 16.7786931,18.7043579 16.7786931,17.9428759 L16.7786931,17.9428759 L16.7786931,15.4880576 C16.7786931,13.8829731 17.6203978,12.3097756 19.3038323,12.0186207 L19.3038323,12.0186207 L19.3038323,11.8842422 C17.6203978,11.5930873 16.7786931,9.71341592 16.7786931,8.10833137 L16.7786931,8.10833137 L16.7786931,5.96998687 C16.7786931,4.52914353 15.3841887,3.83490503 13.6479109,3.79011197 L13.6479109,3.79011197 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="Lua-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use id="Combined-Shape" fill="#FFFFFF" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Material editor icon</title>
|
||||
<g id="Material-editor-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Matieral-editor" transform="translate(2.000000, 2.000000)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<path d="M10.0000677,0 C4.45458426,0 0,4.45451651 0,10.0000677 C0,15.5454835 4.45458426,20 10.0000677,20 C15.5455512,20 20.0000677,15.5454835 20.0000677,10.0000677 C20.0000677,4.45451651 15.5455512,0 10.0000677,0 L10.0000677,0 Z M17.3636715,6.36369179 L14.2727451,6.36369179 C14.0000542,4.90911431 13.6364437,3.45453683 13.0909263,2.3636376 C14.9091143,3.1818459 16.4546114,4.54550382 17.3636715,6.36369179 L17.3636715,6.36369179 Z M12.7273158,10.0000677 C12.7273158,10.6363692 12.7273158,11.2727384 12.6363963,11.818188 L7.36367147,11.818188 C7.27275191,11.2727384 7.27275191,10.6363692 7.27275191,10.0000677 C7.27275191,9.36363082 7.27275191,8.72726164 7.36367147,8.18181202 L12.6363963,8.18181202 C12.7273158,8.72726164 12.7273158,9.36363082 12.7273158,10.0000677 L12.7273158,10.0000677 Z M10.0000677,18.181812 C9.18185945,18.181812 8.09096021,16.4545436 7.54551059,13.636376 L12.3637053,13.636376 C11.9091753,16.4545436 10.8182083,18.181812 10.0000677,18.181812 L10.0000677,18.181812 Z M7.54551059,6.36369179 C8.09096021,3.54545639 9.18185945,1.81818798 10.0000677,1.81818798 C10.8182083,1.81818798 11.9091753,3.54545639 12.4545572,6.36369179 L7.54551059,6.36369179 Z M7.00006097,2.3636376 C6.45454361,3.45453683 6.00001355,4.90911431 5.72732262,6.36369179 L2.63639628,6.36369179 C3.54552414,4.54550382 5.09095344,3.1818459 7.00006097,2.3636376 L7.00006097,2.3636376 Z M2.0000271,8.18181202 L5.45456393,8.18181202 L5.45456393,10.0000677 C5.45456393,10.6363692 5.45456393,11.181812 5.54548349,11.818188 L2.0000271,11.818188 C1.90910754,11.2727384 1.81818798,10.6363692 1.81818798,10.0000677 C1.81818798,9.36363082 1.90910754,8.72726164 2.0000271,8.18181202 L2.0000271,8.18181202 Z M2.63639628,13.636376 L5.72732262,13.636376 C6.00001355,15.0908857 6.36369179,16.5454632 6.90914141,17.6363624 C5.09095344,16.8181541 3.54552414,15.4545639 2.63639628,13.636376 L2.63639628,13.636376 Z M13.0000068,17.6363624 C13.5454564,16.5454632 14.0000542,15.181873 14.1818933,13.636376 L17.2727519,13.636376 C16.4546114,15.4545639 14.9091143,16.8181541 13.0000068,17.6363624 L13.0000068,17.6363624 Z M18.0000406,11.818188 L14.5455038,11.818188 C14.6364234,11.181812 14.6364234,10.6363692 14.6364234,10.0000677 C14.6364234,9.36363082 14.6364234,8.8181812 14.5455038,8.18181202 L18.0000406,8.18181202 C18.0909602,8.72726164 18.1818798,9.36363082 18.1818798,10.0000677 C18.1818798,10.6363692 18.0909602,11.2727384 18.0000406,11.818188 L18.0000406,11.818188 Z" id="Fill-4"></path>
|
||||
<path d="M10.0000677,18.8342378 L10.0000677,9.74336565 L10.0000677,0.652425764 C10.0000677,-2.07482233 20.0000677,4.28880172 20.0000677,9.74336565 C20.0000677,15.1978618 10.0000677,21.5615536 10.0000677,18.8342378" id="Fill-6"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>SC icon</title>
|
||||
<g id="SC-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M10.6929214,4.51764023 L2.96130718,4.51764023 L2.96130718,7.96706695 C2.96130718,8.28694683 3.20917431,8.54770094 3.51331968,8.54770094 L10.1409089,8.54770094 C10.4487844,8.54770094 10.6929214,8.29023965 10.6929214,7.96706695 L10.6929214,4.51764023 Z M14.2332467,16.4348559 L14.2332467,20.1725393 C14.2332467,20.4924192 14.4811138,20.7531733 14.7852592,20.7531733 L21.4128484,20.7531733 C21.7207239,20.7531733 21.9648609,20.495712 21.9648609,20.1725393 L21.9648609,16.4348559 L14.2332467,16.4348559 Z M13.2835051,19.1726688 C10.2249629,19.1726688 8.77405507,18.054406 8.77405507,16.1545309 C8.77405507,13.0382457 10.3731227,12.1561574 12.1046383,10.771073 C13.1119101,9.96532998 15.7122691,8.72781013 15.4186287,7.15556325 C15.0742932,5.31187844 13.7887132,5.54159503 12.960578,5.54159503 C12.5216884,5.54159503 12.3086302,5.54159503 11.7395986,5.54159503 L11.7395986,8.55852782 C11.7395986,9.19716613 11.2523897,9.71488477 10.6393701,9.71488477 L3.10022852,9.71488477 C2.49258909,9.71488477 2,9.19561124 2,8.55852782 L2,3.15635695 C2,2.51771864 2.48720892,2 3.10022852,2 L10.6393701,2 C11.2470095,2 11.7395986,2.51927353 11.7395986,3.15635695 L11.7395986,4.28718075 C11.8084605,4.30424636 12.8206778,4.28718075 13.2914795,4.28718075 C14.5272025,4.28718075 16.430931,4.71571873 16.7735044,7.15556325 C17.1046429,9.5139666 13.8637795,11.1020402 12.960578,11.7649711 C12.0573765,12.4279019 9.98473571,13.9400026 10.3731227,16.1545309 C10.5917354,17.4010303 11.1401369,17.4935013 13.2835051,17.616248 L13.2835051,15.0963595 C13.2835051,14.4577212 13.770714,13.9400026 14.3837336,13.9400026 L21.8997715,13.9400026 C22.5074109,13.9400026 23,14.4592761 23,15.0963595 L23,20.8436431 C23,21.4822814 22.5127911,22 21.8997715,22 L14.3837336,22 C13.7760942,22 13.2835051,21.4807265 13.2835051,20.8436431 L13.2835051,19.1726688 Z" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>trackview icon</title>
|
||||
<g id="trackview-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M16.823,12.203 L21.02,17.385 L22.2679088,17.3858875 C22.5440511,17.3858875 22.7679088,17.6097451 22.7679088,17.8858875 L22.7679088,21.8858875 C22.7679088,22.1620299 22.5440511,22.3858875 22.2679088,22.3858875 L18.2679088,22.3858875 C17.9917664,22.3858875 17.7679088,22.1620299 17.7679088,21.8858875 L17.7679088,17.8858875 C17.7679088,17.6097451 17.9917664,17.3858875 18.2679088,17.3858875 L18.446,17.385 L15.6897008,13.9821947 C16.0317886,13.6205494 16.3299516,13.0552321 16.7322326,12.3605204 L16.823,12.203 Z M21.2679088,18.3858875 L19.2679088,18.3858875 C19.0224489,18.3858875 18.8183004,18.5627627 18.7759644,18.7960119 L18.7679088,18.8858875 L18.7679088,20.8858875 C18.7679088,21.1313474 18.9447839,21.3354959 19.1780331,21.3778318 L19.2679088,21.3858875 L21.2679088,21.3858875 C21.5133687,21.3858875 21.7175171,21.2090124 21.7598531,20.9757631 L21.7679088,20.8858875 L21.7679088,18.8858875 C21.7679088,18.6097451 21.5440511,18.3858875 21.2679088,18.3858875 Z M6.5,7.5 C6.77614237,7.5 7,7.72385763 7,8 L7,12 C7,12.0920475 6.97512693,12.1782855 6.93173534,12.2523596 L8.899,14.864 L12.509852,11.9428149 C12.7234766,12.2722403 12.9272144,12.5724038 13.1110529,12.8336411 C13.2808268,13.0748924 13.4477424,13.3538315 13.6273782,13.6099678 L8.64746364,17.6429264 L8.587,17.568 L8.48965074,17.6429264 L4.614,12.5 L2.5,12.5 C2.22385763,12.5 2,12.2761424 2,12 L2,8 C2,7.72385763 2.22385763,7.5 2.5,7.5 L6.5,7.5 Z M14.7503327,2 C16.9804584,2 19.2448408,4.31018839 18.680341,6.52966995 C18.3107266,7.98290763 16.9879633,10.228611 16.3314778,11.3623164 C15.7632532,12.3436012 15.4564503,13 14.7503327,13 C14.1697909,13 13.8202563,12.2587581 13.4539789,11.7382724 C12.5819908,10.499164 11.1465939,8.15794141 10.8399585,6.34792109 C10.456795,4.08616686 12.520207,2 14.7503327,2 Z M5.5,8.5 L3.5,8.5 C3.25454011,8.5 3.05039163,8.67687516 3.00805567,8.91012437 L3,9 L3,11 C3,11.2454599 3.17687516,11.4496084 3.41012437,11.4919443 L3.5,11.5 L5.5,11.5 C5.74545989,11.5 5.94960837,11.3231248 5.99194433,11.0898756 L6,11 L6,9 C6,8.72385763 5.77614237,8.5 5.5,8.5 Z M14.7630032,3.64006918 C13.4587768,3.64006918 12.2520482,4.86010532 12.4761306,6.1828288 C12.6554577,7.24136838 13.4949093,8.61056669 14.0048671,9.33522446 C14.2190741,9.63961592 14.4234896,10.0731104 14.7630032,10.0731104 C15.1759562,10.0731104 15.3553813,9.68923405 15.6876915,9.11535718 C16.0716186,8.45234135 16.8451996,7.13900479 17.0613582,6.28911952 C17.3914901,4.99111802 16.0672296,3.64006918 14.7630032,3.64006918 Z" id="Combined-Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>UI editor icon</title>
|
||||
<g id="UI-editor-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M17.2586018,20.75 C17.5703793,20.75 17.9274484,21.0083567 17.9274484,21.5 C17.9274484,21.9916433 17.5643628,22.25 17.2586018,22.25 L6.59549278,22.25 C6.28371519,22.25 5.92744838,22.0362554 5.92744838,21.5 C5.92744838,20.9637446 6.28973169,20.75 6.59549278,20.75 L17.2586018,20.75 Z M18.761301,18.25 C19.1702062,18.25 19.4375316,18.3951808 19.6411889,18.7003165 L22.1404492,21.4921472 C22.2376383,21.6401916 22.1701774,22.035686 21.6105938,22.1961567 C21.0510103,22.3566274 20.4982123,22.1211124 20.4029562,21.9760125 L18.1061133,19.6313487 L5.71849881,19.6313487 L3.57831926,21.8435327 C3.38399691,22.0873313 2.7574214,22.3578511 2.19881088,22.1961567 C1.64020036,22.0344623 1.590103,21.7248255 1.77134414,21.4921472 L4.31399299,18.6158681 C4.44159848,18.3952908 4.73156178,18.25 5.13095934,18.25 L18.761301,18.25 Z M21.3225516,1.75 C21.8748364,1.75 22.3225516,2.19771525 22.3225516,2.75 L22.3225516,16.25 C22.3225516,16.8022847 21.8748364,17.25 21.3225516,17.25 L2.82255162,17.25 C2.27026687,17.25 1.82255162,16.8022847 1.82255162,16.25 L1.82255162,2.75 C1.82255162,2.19771525 2.27026687,1.75 2.82255162,1.75 L21.3225516,1.75 Z M6.34022315,10.6954321 L8.86065341,14.1918975 L8.10519831,14.7407678 C8.03763155,14.7755937 7.97006479,14.8104197 7.8973133,14.8299937 L7.78364943,14.8460092 L5.1111786,14.9475958 C4.69666668,14.954558 4.37144365,14.5550509 4.4333144,14.158968 L4.46000935,14.0513382 L5.3853134,11.5175921 C5.41340273,11.4329953 5.45293841,11.364153 5.51491033,11.3030805 L5.58476804,11.2443023 L6.34022315,10.6954321 Z M16.6597247,8.52554056 L9.81373289,13.4994447 L7.28027754,10.0124426 L14.1262693,5.03853841 L16.6597247,8.52554056 Z M18.9647934,6.05595685 C19.168837,6.31373009 19.1620706,6.6550625 18.9646323,6.84607209 L18.8917853,6.90385362 L17.5997791,7.84255106 L15.0663237,4.35554892 L16.3583299,3.41685147 C16.5750186,3.25941794 16.9000316,3.31183746 17.1130757,3.52293254 L17.1872884,3.60943115 L18.9647934,6.05595685 Z" id="Combined-Shape-Copy-9" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -19,5 +19,14 @@
|
||||
<file alias="resolution.svg">Menu/resolution.svg</file>
|
||||
<file alias="debug.svg">Menu/debug.svg</file>
|
||||
<file alias="camera.svg">Menu/camera.svg</file>
|
||||
<file alias="asset_editor.svg">Menu/asset_editor.svg</file>
|
||||
<file alias="audio_editor.svg">Menu/audio_editor.svg</file>
|
||||
<file alias="emfx_editor.svg">Menu/emfx_editor.svg</file>
|
||||
<file alias="landscape_canvas_editor.svg">Menu/landscape_canvas_editor.svg</file>
|
||||
<file alias="lua_editor.svg">Menu/lua_editor.svg</file>
|
||||
<file alias="material_editor.svg">Menu/material_editor.svg</file>
|
||||
<file alias="script_canvas_editor.svg">Menu/script_canvas_editor.svg</file>
|
||||
<file alias="trackview_editor.svg">Menu/trackview_editor.svg</file>
|
||||
<file alias="ui_editor.svg">Menu/ui_editor.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS true
|
||||
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ATOM_RPI_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ZERO_COLOR_CONVERSION_TEST true
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
|
||||
if(NOT LY_MONOLITHIC_GAME)
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/AzTest/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
ly_add_target(
|
||||
@@ -30,7 +29,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
3rdParty::GoogleBenchmark
|
||||
AZ::AzCore
|
||||
PLATFORM_INCLUDE_FILES
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -916,9 +916,6 @@ namespace AzToolsFramework
|
||||
eECMF_USE_VIEWPORT_CENTER = 0x2,
|
||||
};
|
||||
|
||||
/// Populate global edit-time context menu.
|
||||
virtual void PopulateEditorGlobalContextMenu(QMenu * /*menu*/, const AZ::Vector2& /*point*/, int /*flags*/) {}
|
||||
|
||||
/// Populate slice portion of edit-time context menu
|
||||
virtual void PopulateEditorGlobalContextMenu_SliceSection(QMenu * /*menu*/, const AZ::Vector2& /*point*/, int /*flags*/) {}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace AzToolsFramework::AssetUtils
|
||||
AZStd::vector<AzFramework::GemInfo> gemInfoList;
|
||||
if (!AzFramework::GetGemsInfo(gemInfoList, *settingsRegistry))
|
||||
{
|
||||
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to read gems from project folder(%s).\n", projectPath);
|
||||
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to read gems from project folder(%.*s).\n", AZ_STRING_ARG(projectPath));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Entries/FolderAssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
|
||||
@@ -22,6 +23,9 @@ AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
#include <QCollator>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
AZ_CVAR(
|
||||
bool, ed_useNewAssetBrowserTableView, false, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"Use the new AssetBrowser TableView for searching assets.");
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
@@ -31,7 +35,11 @@ namespace AzToolsFramework
|
||||
AssetBrowserFilterModel::AssetBrowserFilterModel(QObject* parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
m_showColumn.insert(AssetBrowserModel::m_column);
|
||||
m_showColumn.insert(aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName));
|
||||
if (ed_useNewAssetBrowserTableView)
|
||||
{
|
||||
m_showColumn.insert(aznumeric_cast<int>(AssetBrowserEntry::Column::Path));
|
||||
}
|
||||
m_collator.setNumericMode(true);
|
||||
AssetBrowserComponentNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
@@ -128,28 +136,58 @@ namespace AzToolsFramework
|
||||
auto compFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(m_filter);
|
||||
if (compFilter)
|
||||
{
|
||||
auto& subFilters = compFilter->GetSubFilters();
|
||||
auto it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool
|
||||
const auto& subFilters = compFilter->GetSubFilters();
|
||||
|
||||
const auto compositeFilterIterator = AZStd::find_if(subFilters.cbegin(), subFilters.cend(), [subFilters](FilterConstType filter) -> bool
|
||||
{
|
||||
auto assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(filter);
|
||||
const auto assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(filter);
|
||||
return !assetTypeFilter.isNull();
|
||||
});
|
||||
if (it != subFilters.end())
|
||||
|
||||
if (compositeFilterIterator != subFilters.end())
|
||||
{
|
||||
m_assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(*it);
|
||||
m_assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(*compositeFilterIterator);
|
||||
}
|
||||
it = AZStd::find_if(subFilters.begin(), subFilters.end(), [subFilters](FilterConstType filter) -> bool
|
||||
|
||||
const auto compStringFilterIter = AZStd::find_if(subFilters.cbegin(), subFilters.cend(), [](FilterConstType filter) -> bool
|
||||
{
|
||||
auto stringFilter = qobject_cast<QSharedPointer<const StringFilter> >(filter);
|
||||
return !stringFilter.isNull();
|
||||
//The real StringFilter is really a CompositeFilter with just one StringFilter in its subfilter list
|
||||
//To know if it is actually a StringFilter we have to get that subfilter and check if it is a Stringfilter.
|
||||
const auto stringCompositeFilter = qobject_cast<QSharedPointer<const CompositeFilter> >(filter);
|
||||
bool isStringFilter = false;
|
||||
if (stringCompositeFilter)
|
||||
{
|
||||
const auto& stringSubfilters = stringCompositeFilter->GetSubFilters();
|
||||
auto canBeCasted = [](FilterConstType filt) -> bool
|
||||
{
|
||||
auto strFilter = qobject_cast<QSharedPointer<const StringFilter>>(filt);
|
||||
return !strFilter.isNull();
|
||||
};
|
||||
const auto stringSubfliterConstIter = AZStd::find_if(stringSubfilters.cbegin(), stringSubfilters.cend(), canBeCasted);
|
||||
|
||||
//A Composite StringFilter will only have just one subfilter and nothing more.
|
||||
if (stringSubfliterConstIter != stringSubfilters.end() && stringSubfilters.size() == 1)
|
||||
{
|
||||
isStringFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isStringFilter;
|
||||
});
|
||||
if (it != subFilters.end())
|
||||
if (compStringFilterIter != subFilters.end())
|
||||
{
|
||||
m_stringFilter = qobject_cast<QSharedPointer<const StringFilter> >(*it);
|
||||
const auto compStringFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(*compStringFilterIter);
|
||||
|
||||
if (!compStringFilter->GetSubFilters().isEmpty() && compStringFilter->GetSubFilters()[0])
|
||||
{
|
||||
m_stringFilter = qobject_cast<QSharedPointer<const StringFilter>>(compStringFilter->GetSubFilters()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
invalidateFilter();
|
||||
Q_EMIT filterChanged();
|
||||
emit stringFilterPopulated(!m_stringFilter.isNull());
|
||||
}
|
||||
|
||||
void AssetBrowserFilterModel::filterUpdatedSlot()
|
||||
|
||||
@@ -45,15 +45,15 @@ namespace AzToolsFramework
|
||||
//asset type filtering
|
||||
void SetFilter(FilterConstType filter);
|
||||
void FilterUpdatedSlotImmediate();
|
||||
|
||||
const FilterConstType& GetFilter() const { return m_filter; }
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AssetBrowserComponentNotificationBus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnAssetBrowserComponentReady() override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stringFilterPopulated(bool);
|
||||
void filterChanged();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//QSortFilterProxyModel
|
||||
protected:
|
||||
@@ -68,7 +68,7 @@ namespace AzToolsFramework
|
||||
protected:
|
||||
//set for filtering columns
|
||||
//if the column is in the set the column is not filtered and is shown
|
||||
AZStd::fixed_unordered_set<int, 3, static_cast<int>(AssetBrowserEntry::Column::Count)> m_showColumn;
|
||||
AZStd::fixed_unordered_set<int, 3, aznumeric_cast<int>(AssetBrowserEntry::Column::Count)> m_showColumn;
|
||||
bool m_alreadyRecomputingFilters = false;
|
||||
//asset source name match filter
|
||||
FilterConstType m_filter;
|
||||
|
||||
@@ -27,8 +27,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
const int AssetBrowserModel::m_column = static_cast<int>(AssetBrowserEntry::Column::DisplayName);
|
||||
|
||||
AssetBrowserModel::AssetBrowserModel(QObject* parent)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_rootEntry(nullptr)
|
||||
@@ -143,8 +141,9 @@ namespace AzToolsFramework
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
if ((parent.column() != static_cast<int>(AssetBrowserEntry::Column::DisplayName)) &&
|
||||
(parent.column() != static_cast<int>(AssetBrowserEntry::Column::Name)))
|
||||
if ((parent.column() != aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName)) &&
|
||||
(parent.column() != aznumeric_cast<int>(AssetBrowserEntry::Column::Name)) &&
|
||||
(parent.column() != aznumeric_cast<int>(AssetBrowserEntry::Column::Path)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -164,7 +163,7 @@ namespace AzToolsFramework
|
||||
|
||||
int AssetBrowserModel::columnCount(const QModelIndex& /*parent*/) const
|
||||
{
|
||||
return static_cast<int>(AssetBrowserEntry::Column::Count);
|
||||
return aznumeric_cast<int>(AssetBrowserEntry::Column::Count);
|
||||
}
|
||||
|
||||
QVariant AssetBrowserModel::data(const QModelIndex& index, int role) const
|
||||
@@ -393,7 +392,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
int row = entry->row();
|
||||
index = createIndex(row, m_column, entry);
|
||||
index = createIndex(row, aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName), entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,8 +91,6 @@ namespace AzToolsFramework
|
||||
static void SourceIndexesToAssetIds(const QModelIndexList& indexes, AZStd::vector<AZ::Data::AssetId>& assetIds);
|
||||
static void SourceIndexesToAssetDatabaseEntries(const QModelIndexList& indexes, AZStd::vector<AssetBrowserEntry*>& entries);
|
||||
|
||||
const static int m_column;
|
||||
|
||||
private:
|
||||
AZStd::shared_ptr<RootAssetBrowserEntry> m_rootEntry;
|
||||
bool m_loaded;
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <AssetBrowser/AssetBrowserFilterModel.h>
|
||||
#include <AssetBrowser/AssetBrowserTableModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
AssetBrowserTableModel::AssetBrowserTableModel(QObject* parent /* = nullptr */)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setDynamicSortFilter(false);
|
||||
}
|
||||
|
||||
void AssetBrowserTableModel::setSourceModel(QAbstractItemModel* sourceModel)
|
||||
{
|
||||
m_filterModel = qobject_cast<AssetBrowserFilterModel*>(sourceModel);
|
||||
AZ_Assert(
|
||||
m_filterModel,
|
||||
"Error in AssetBrowserTableModel initialization, class expects source model to be an AssetBrowserFilterModel.");
|
||||
QSortFilterProxyModel::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
QModelIndex AssetBrowserTableModel::mapToSource(const QModelIndex& proxyIndex) const
|
||||
{
|
||||
Q_ASSERT(!proxyIndex.isValid() || proxyIndex.model() == this);
|
||||
if (!proxyIndex.isValid())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
return m_indexMap[proxyIndex.row()];
|
||||
}
|
||||
|
||||
QVariant AssetBrowserTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||
{
|
||||
return tr(AssetBrowserEntry::m_columnNames[section]);
|
||||
}
|
||||
return QSortFilterProxyModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QVariant AssetBrowserTableModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
auto sourceIndex = mapToSource(index);
|
||||
if (!sourceIndex.isValid())
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
AssetBrowserEntry* entry = GetAssetEntry(sourceIndex);
|
||||
if (entry == nullptr)
|
||||
{
|
||||
AZ_Assert(false, "AssetBrowserTableModel - QModelIndex does not reference an AssetEntry. Source model is not valid.");
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return sourceIndex.data(role);
|
||||
}
|
||||
|
||||
QModelIndex AssetBrowserTableModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? QModelIndex() : createIndex(row, column, m_indexMap[row].internalPointer());
|
||||
}
|
||||
|
||||
int AssetBrowserTableModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return !parent.isValid() ? m_indexMap.size() : 0;
|
||||
}
|
||||
|
||||
int AssetBrowserTableModel::BuildTableModelMap(
|
||||
const QAbstractItemModel* model, const QModelIndex& parent /*= QModelIndex()*/, int row /*= 0*/)
|
||||
{
|
||||
int rows = model ? model->rowCount(parent) : 0;
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
QModelIndex index = model->index(i, 0, parent);
|
||||
AssetBrowserEntry* entry = GetAssetEntry(m_filterModel->mapToSource(index));
|
||||
//We only wanna see the source assets.
|
||||
if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source)
|
||||
{
|
||||
beginInsertRows(parent, row, row);
|
||||
m_indexMap[row] = index;
|
||||
endInsertRows();
|
||||
|
||||
Q_EMIT dataChanged(index, index);
|
||||
++row;
|
||||
}
|
||||
|
||||
if (model->hasChildren(index))
|
||||
{
|
||||
row = BuildTableModelMap(model, index, row);
|
||||
}
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
AssetBrowserEntry* AssetBrowserTableModel::GetAssetEntry(QModelIndex index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
return static_cast<AssetBrowserEntry*>(index.internalPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("AssetBrowser", false, "Invalid Source Index provided to GetAssetEntry.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetBrowserTableModel::UpdateTableModelMaps()
|
||||
{
|
||||
emit layoutAboutToBeChanged();
|
||||
if (!m_indexMap.isEmpty())
|
||||
{
|
||||
beginRemoveRows(m_indexMap.first(), m_indexMap.first().row(), m_indexMap.last().row());
|
||||
m_indexMap.clear();
|
||||
endRemoveRows();
|
||||
}
|
||||
BuildTableModelMap(sourceModel());
|
||||
emit layoutChanged();
|
||||
}
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
#include "AssetBrowser/moc_AssetBrowserTableModel.cpp"
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QPointer>
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
class AssetBrowserFilterModel;
|
||||
class AssetBrowserEntry;
|
||||
|
||||
class AssetBrowserTableModel
|
||||
: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AssetBrowserTableModel, AZ::SystemAllocator, 0);
|
||||
explicit AssetBrowserTableModel(QObject* parent = nullptr);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// QSortFilterProxyModel
|
||||
void setSourceModel(QAbstractItemModel* sourceModel) override;
|
||||
QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void UpdateTableModelMaps();
|
||||
|
||||
protected:
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role /* = Qt::DisplayRole */) const override;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
AssetBrowserEntry* GetAssetEntry(QModelIndex index) const;
|
||||
int BuildTableModelMap(const QAbstractItemModel* model, const QModelIndex& parent = QModelIndex(), int row = 0);
|
||||
|
||||
private:
|
||||
QPointer<AssetBrowserFilterModel> m_filterModel;
|
||||
QMap<int, QModelIndex> m_indexMap;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
@@ -46,6 +46,7 @@ namespace AzToolsFramework
|
||||
const char* AssetBrowserEntry::m_columnNames[] =
|
||||
{
|
||||
"Name",
|
||||
"Path",
|
||||
"Source ID",
|
||||
"Fingerprint",
|
||||
"Guid",
|
||||
@@ -128,6 +129,8 @@ namespace AzToolsFramework
|
||||
return QString::fromUtf8(m_name.c_str());
|
||||
case Column::DisplayName:
|
||||
return m_displayName;
|
||||
case Column::Path:
|
||||
return m_displayPath;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace AzToolsFramework
|
||||
enum class Column
|
||||
{
|
||||
Name,
|
||||
Path,
|
||||
SourceID,
|
||||
Fingerprint,
|
||||
Guid,
|
||||
@@ -135,6 +136,7 @@ namespace AzToolsFramework
|
||||
protected:
|
||||
AZStd::string m_name;
|
||||
QString m_displayName;
|
||||
QString m_displayPath;
|
||||
AZStd::string m_relativePath;
|
||||
AZStd::string m_fullPath;
|
||||
AZStd::vector<AssetBrowserEntry*> m_children;
|
||||
|
||||