Merge branch 'aws-lumberyard:development' into SerializeContextToolsConvertHandleAnyValidation
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -125,7 +125,7 @@ enum ESystemConfigPlatform
|
||||
{
|
||||
CONFIG_INVALID_PLATFORM = 0,
|
||||
CONFIG_PC = 1,
|
||||
CONFIG_OSX_GL = 2,
|
||||
CONFIG_MAC = 2,
|
||||
CONFIG_OSX_METAL = 3,
|
||||
CONFIG_ANDROID = 4,
|
||||
CONFIG_IOS = 5,
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <IRenderer.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
@@ -84,7 +83,7 @@ public: // types
|
||||
//! If this is not passed then the defaults below are used
|
||||
struct TextOptions
|
||||
{
|
||||
IFFont* font; //!< default is "default"
|
||||
AZStd::string fontName; //!< default is "default"
|
||||
unsigned int effectIndex; //!< default is 0
|
||||
AZ::Vector3 color; //!< default is (1,1,1)
|
||||
HAlign horizontalAlignment; //!< default is HAlign::Left
|
||||
|
||||
@@ -137,5 +137,6 @@ enum class AnimParamType
|
||||
Invalid = static_cast<int>(0xFFFFFFFF)
|
||||
};
|
||||
|
||||
static const int OLD_APARAM_USER = 100;
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_MAESTRO_TYPES_ANIMPARAMTYPE_H
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// If you make changes in ICryPak.h, make changes here, to dirty the PCH.
|
||||
#include "CrySystem_precompiled.h"
|
||||
@@ -561,7 +561,7 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
|
||||
|
||||
if (pex)
|
||||
{
|
||||
MINIDUMP_TYPE mdumpValue;
|
||||
MINIDUMP_TYPE mdumpValue = MiniDumpNormal;
|
||||
bool bDump = true;
|
||||
switch (g_cvars.sys_dump_type)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace LegacyLevelSystem
|
||||
//------------------------------------------------------------------------
|
||||
static void LoadLevel(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
AZ_Error("SpawnableLevelSystem", arguments.empty(), "LoadLevel requires a level file name to be provided.");
|
||||
AZ_Error("SpawnableLevelSystem", arguments.size() > 1, "LoadLevel requires a single level file name to be provided.");
|
||||
AZ_Error("SpawnableLevelSystem", !arguments.empty(), "LoadLevel requires a level file name to be provided.");
|
||||
AZ_Error("SpawnableLevelSystem", arguments.size() == 1, "LoadLevel requires a single level file name to be provided.");
|
||||
|
||||
if (!arguments.empty() && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
@@ -88,7 +89,6 @@ CLog::CLog(ISystem* pSystem)
|
||||
|
||||
m_nMainThreadId = CryGetCurrentThreadId();
|
||||
|
||||
m_logFileHandle = AZ::IO::InvalidHandle;
|
||||
#if defined(KEEP_LOG_FILE_OPEN)
|
||||
m_bFirstLine = true;
|
||||
#endif
|
||||
@@ -162,35 +162,6 @@ void CLog::RegisterConsoleVariables()
|
||||
REGISTER_COMMAND("log_flush", &LogFlushFile, 0, "Flush the log file");
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
//testbed
|
||||
{
|
||||
int iSave0 = m_pLogVerbosity->GetIVal();
|
||||
int iSave1 = m_pLogFileVerbosity->GetIVal();
|
||||
|
||||
for(int i=0;i<=4;++i)
|
||||
{
|
||||
m_pLogVerbosity->Set(i);
|
||||
m_pLogFileVerbosity->Set(i);
|
||||
|
||||
LogWithType(eAlways,"CLog selftest: Verbosity=%d FileVerbosity=%d",m_pLogVerbosity->GetIVal(),m_pLogFileVerbosity->GetIVal());
|
||||
LogWithType(eAlways,"--------------");
|
||||
|
||||
LogWithType(eError,"eError");
|
||||
LogWithType(eWarning,"eWarning");
|
||||
LogWithType(eMessage,"eMessage");
|
||||
LogWithType(eInput,"eInput");
|
||||
LogWithType(eInputResponse,"eInputResponse");
|
||||
|
||||
LogWarning("LogWarning()");
|
||||
LogError("LogError()");
|
||||
LogWithType(eAlways,"--------------");
|
||||
}
|
||||
|
||||
m_pLogVerbosity->Set(iSave0);
|
||||
m_pLogFileVerbosity->Set(iSave1);
|
||||
}
|
||||
*/
|
||||
#undef DEFAULT_VERBOSITY
|
||||
}
|
||||
|
||||
@@ -210,7 +181,7 @@ CLog::~CLog()
|
||||
|
||||
UnregisterConsoleVariables();
|
||||
|
||||
CloseLogFile(true);
|
||||
CloseLogFile();
|
||||
}
|
||||
|
||||
void CLog::UnregisterConsoleVariables()
|
||||
@@ -224,31 +195,36 @@ void CLog::UnregisterConsoleVariables()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLog::CloseLogFile([[maybe_unused]] bool forceClose)
|
||||
void CLog::CloseLogFile()
|
||||
{
|
||||
if (m_logFileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Close(m_logFileHandle);
|
||||
m_logFileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
m_logFileHandle.Close();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
|
||||
bool CLog::OpenLogFile(const char* filename, int mode)
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
|
||||
AZ_Assert(m_logFileHandle == AZ::IO::InvalidHandle, "Attempt to open log file when one is already open. This would lead to a handle leak.");
|
||||
|
||||
if ((!filename) || (filename[0] == 0))
|
||||
if (m_logFileHandle.IsOpen())
|
||||
{
|
||||
return m_logFileHandle;
|
||||
// Can only AZ_Assert if a file is open, otherwise the AZ_Assert
|
||||
// would eventually lead to OpenLogFile being opened up again
|
||||
AZ_Assert(false, "Attempt to open log file when one is already open. This would lead to a handle leak.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filename == nullptr || filename[0] == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode(mode), m_logFileHandle);
|
||||
AZ::IO::FileIOBase* fileSystem = AZ::IO::FileIOBase::GetDirectInstance();
|
||||
if (AZ::IO::FixedMaxPath logFilePath; fileSystem->ReplaceAlias(logFilePath, filename))
|
||||
{
|
||||
logFilePath = logFilePath.LexicallyNormal();
|
||||
m_logFileHandle.Open(logFilePath.c_str(), mode);
|
||||
}
|
||||
|
||||
if (m_logFileHandle != AZ::IO::InvalidHandle)
|
||||
if (m_logFileHandle.IsOpen())
|
||||
{
|
||||
#if defined(KEEP_LOG_FILE_OPEN)
|
||||
m_bFirstLine = true;
|
||||
@@ -257,11 +233,11 @@ AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
|
||||
else
|
||||
{
|
||||
#if defined(LINUX) || defined(APPLE)
|
||||
syslog(LOG_NOTICE, "Failed to open log file [%s], mode [%s]", filename, mode);
|
||||
syslog(LOG_NOTICE, "Failed to open log file [%s], mode [%d]", filename, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_logFileHandle;
|
||||
return m_logFileHandle.IsOpen();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1114,12 +1090,15 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
|
||||
|
||||
if (logToFile)
|
||||
{
|
||||
if (m_logFileHandle == AZ::IO::InvalidHandle)
|
||||
if (!m_logFileHandle.IsOpen())
|
||||
{
|
||||
OpenLogFile(m_szFilename, "w+t");
|
||||
constexpr auto openMode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND
|
||||
| AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE
|
||||
| AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY;
|
||||
OpenLogFile(m_szFilename, openMode);
|
||||
}
|
||||
|
||||
if (m_logFileHandle != AZ::IO::InvalidHandle)
|
||||
if (m_logFileHandle.IsOpen())
|
||||
{
|
||||
#if defined(KEEP_LOG_FILE_OPEN)
|
||||
if (m_bFirstLine)
|
||||
@@ -1130,9 +1109,9 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
|
||||
if (bAdd)
|
||||
{
|
||||
// if adding to a prior line erase the \n at the end.
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Seek(m_logFileHandle, -2, AZ::IO::SeekType::SeekFromEnd);
|
||||
m_logFileHandle.Seek(-2, AZ::IO::SystemFile::SeekMode::SF_SEEK_END);
|
||||
}
|
||||
AZ::IO::FPutS(tempString.c_str(), m_logFileHandle);
|
||||
m_logFileHandle.Write(tempString.c_str(), tempString.size());
|
||||
#if !defined(KEEP_LOG_FILE_OPEN)
|
||||
CloseLogFile();
|
||||
#endif
|
||||
@@ -1383,6 +1362,23 @@ bool CLog::SetFileName(const char* fileNameOrAbsolutePath, bool backupLogs)
|
||||
|
||||
CreateBackupFile();
|
||||
|
||||
AZ::IO::FileIOBase* fileSystem = AZ::IO::FileIOBase::GetDirectInstance();
|
||||
AZ::IO::FixedMaxPath newLogFilePath;
|
||||
if (fileSystem->ReplaceAlias(newLogFilePath, m_szFilename))
|
||||
{
|
||||
newLogFilePath = newLogFilePath.LexicallyNormal();
|
||||
}
|
||||
if (m_logFileHandle.IsOpen() && newLogFilePath != m_logFileHandle.Name())
|
||||
{
|
||||
constexpr auto openMode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND
|
||||
| AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE
|
||||
| AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY;
|
||||
if(AZ::IO::SystemFile newLogFile; newLogFile.Open(m_szFilename, openMode))
|
||||
{
|
||||
m_logFileHandle = AZStd::move(newLogFile);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1537,9 +1533,9 @@ const char* CLog::GetModuleFilter()
|
||||
void CLog::FlushAndClose()
|
||||
{
|
||||
#if defined(KEEP_LOG_FILE_OPEN)
|
||||
if (m_logFileHandle)
|
||||
if (m_logFileHandle.IsOpen())
|
||||
{
|
||||
CloseLogFile(true);
|
||||
CloseLogFile();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ private: // -------------------------------------------------------------------
|
||||
void LogStringToConsole(const char* szString, ELogType logType, bool bAdd) {}
|
||||
#endif // !defined(EXCLUDE_NORMAL_LOG)
|
||||
|
||||
AZ::IO::HandleType OpenLogFile(const char* filename, const char* mode);
|
||||
void CloseLogFile(bool force = false);
|
||||
bool OpenLogFile(const char* filename, int mode);
|
||||
void CloseLogFile();
|
||||
|
||||
// will format the message into m_szTemp
|
||||
void FormatMessage(const char* szCommand, ...) PRINTF_PARAMS(2, 3);
|
||||
@@ -152,15 +152,11 @@ private: // -------------------------------------------------------------------
|
||||
virtual const char* GetAssetScopeString();
|
||||
#endif
|
||||
|
||||
ISystem* m_pSystem; //
|
||||
float m_fLastLoadingUpdateTime; // for non-frequent streamingEngine update
|
||||
//char m_szTemp[MAX_TEMP_LENGTH_SIZE]; //
|
||||
char m_szFilename[MAX_FILENAME_SIZE]; // can be with path
|
||||
mutable char m_sBackupFilename[MAX_FILENAME_SIZE]; // can be with path
|
||||
AZ::IO::HandleType m_logFileHandle;
|
||||
CryStackStringT<char, 32> m_LogMode; //mode m_pLogFile has been opened with
|
||||
AZ::IO::HandleType m_errFileHandle;
|
||||
int m_nErrCount;
|
||||
ISystem* m_pSystem; //
|
||||
float m_fLastLoadingUpdateTime; // for non-frequent streamingEngine update
|
||||
char m_szFilename[MAX_FILENAME_SIZE]; // can be with path
|
||||
mutable char m_sBackupFilename[MAX_FILENAME_SIZE]; // can be with path
|
||||
AZ::IO::SystemFile m_logFileHandle;
|
||||
|
||||
bool m_backupLogs;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
if (pSystem && !pSystem->IsQuitting())
|
||||
{
|
||||
LRESULT result;
|
||||
LRESULT result = 0;
|
||||
bool bAny = false;
|
||||
for (std::vector<IWindowMessageHandler*>::const_iterator it = pSystem->m_windowMessageHandlers.begin(); it != pSystem->m_windowMessageHandlers.end(); ++it)
|
||||
{
|
||||
|
||||
@@ -729,7 +729,7 @@ protected: // -------------------------------------------------------------
|
||||
CCmdLine* m_pCmdLine;
|
||||
|
||||
string m_currentLanguageAudio;
|
||||
string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg
|
||||
string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_android.cfg or system_windows_pc.cfg
|
||||
|
||||
std::vector< std::pair<CTimeValue, float> > m_updateTimes;
|
||||
|
||||
|
||||
@@ -634,7 +634,7 @@ ICVar* CSystem::attachVariable (const char* szVarName, int* pContainer, const ch
|
||||
IConsole* pConsole = GetIConsole();
|
||||
|
||||
ICVar* pOldVar = pConsole->GetCVar (szVarName);
|
||||
int nDefault;
|
||||
int nDefault = 0;
|
||||
if (pOldVar)
|
||||
{
|
||||
nDefault = pOldVar->GetIVal();
|
||||
@@ -864,11 +864,6 @@ bool CSystem::InitShine([[maybe_unused]] const SSystemInitParams& initParams)
|
||||
|
||||
EBUS_EVENT(UiSystemBus, InitializeSystem);
|
||||
|
||||
if (!m_env.pLyShine)
|
||||
{
|
||||
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "LYShine System did not initialize correctly. Please check that the LyShine gem is enabled for this project in *_dependencies.cmake.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1213,7 +1208,7 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
|
||||
{
|
||||
assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
||||
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
|
||||
R"(This typically done by setting he "assets" field in the bootstrap.cfg for within a .setreg file)""\n"
|
||||
R"(This typically done by setting the "assets" field within a .setreg file)""\n"
|
||||
R"(A fallback of %s will be used.)",
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
|
||||
assetPlatform.c_str());
|
||||
@@ -2022,8 +2017,8 @@ void CSystem::CreateSystemVars()
|
||||
REGISTER_CVAR2("sys_streaming_in_blocks", &g_cvars.sys_streaming_in_blocks, 1, VF_NULL,
|
||||
"Streaming of large files happens in blocks");
|
||||
|
||||
#if (defined(WIN32) || defined(WIN64)) && !defined(_RELEASE)
|
||||
REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 3, 0, "Use or not use floating point exceptions.");
|
||||
#if (defined(WIN32) || defined(WIN64)) && defined(_DEBUG)
|
||||
REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 2, 0, "Use or not use floating point exceptions.");
|
||||
#else // Float exceptions by default disabled for console builds.
|
||||
REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 0, 0, "Use or not use floating point exceptions.");
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,5 @@ set(FILES
|
||||
ViewSystem/View.h
|
||||
ViewSystem/ViewSystem.cpp
|
||||
ViewSystem/ViewSystem.h
|
||||
CrySystem_precompiled.cpp
|
||||
WindowsErrorReporting.cpp
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -77,6 +77,27 @@
|
||||
#endif // defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (arguments.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto entityIdStr = AZStd::string(arguments.front());
|
||||
const auto entityIdValue = AZStd::stoull(entityIdStr);
|
||||
|
||||
AZStd::string entityName;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(
|
||||
entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, AZ::EntityId(entityIdValue));
|
||||
|
||||
AZ_Printf("Entity Debug", "EntityId: %" PRIu64 ", Entity Name: %s", entityIdValue, entityName.c_str());
|
||||
}
|
||||
|
||||
AZ_CONSOLEFREEFUNC(
|
||||
PrintEntityName, AZ::ConsoleFunctorFlags::Null, "Parameter: EntityId value, Prints the name of the entity to the console");
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -1260,7 +1281,7 @@ namespace AZ
|
||||
// So auto load is turned off if option "AutoLoad" key is bool that is false
|
||||
if (valueName == "AutoLoad" && !value)
|
||||
{
|
||||
// Strip off the AutoLoead entry from the path
|
||||
// Strip off the AutoLoad entry from the path
|
||||
auto autoLoadKey = AZ::StringFunc::TokenizeLast(path, "/");
|
||||
if (!autoLoadKey)
|
||||
{
|
||||
@@ -1330,7 +1351,7 @@ namespace AZ
|
||||
{
|
||||
auto CompareDynamicModuleDescriptor = [&dynamicLibraryPath](const DynamicModuleDescriptor& entry)
|
||||
{
|
||||
return entry.m_dynamicLibraryPath.contains(dynamicLibraryPath);
|
||||
return AZ::IO::PathView(entry.m_dynamicLibraryPath).Stem() == AZ::IO::PathView(dynamicLibraryPath).Stem();
|
||||
};
|
||||
if (auto moduleIter = AZStd::find_if(gemModules.begin(), gemModules.end(), CompareDynamicModuleDescriptor);
|
||||
moduleIter == gemModules.end())
|
||||
|
||||
@@ -172,78 +172,10 @@ namespace AZ
|
||||
|
||||
//! Rotation modifiers
|
||||
//! @{
|
||||
//! @deprecated Use SetLocalRotation()
|
||||
//! Sets the entity's rotation in the world.
|
||||
//! The origin of the axes is the entity's position in world space.
|
||||
//! @param eulerAnglesRadians A three-dimensional vector, containing Euler angles in radians, to rotate the entity by.
|
||||
virtual void SetRotation([[maybe_unused]] const AZ::Vector3& eulerAnglesRadians) {}
|
||||
|
||||
//! @deprecated Use SetLocalRotation()
|
||||
//! Sets the entity's rotation around the world's X axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The X coordinate Euler angle in radians to use for the entity's rotation.
|
||||
virtual void SetRotationX([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use SetLocalRotation()
|
||||
//! Sets the entity's rotation around the world's Y axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The Y coordinate Euler angle in radians to use for the entity's rotation.
|
||||
virtual void SetRotationY([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use SetLocalRotation()
|
||||
//! Sets the entity's rotation around the world's Z axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The Z coordinate Euler angle in radians to use for the entity's rotation.
|
||||
virtual void SetRotationZ([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use SetLocalRotationQuaternion()
|
||||
//! Sets the entity's rotation in the world in quaternion notation.
|
||||
//! The origin of the axes is the entity's position in world space.
|
||||
//! @param quaternion A quaternion that represents the rotation to use for the entity.
|
||||
virtual void SetRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {}
|
||||
|
||||
//! @deprecated Use RotateAroundLocalX()
|
||||
//! Rotates the entity around the world's X axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the X axis.
|
||||
virtual void RotateByX([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use RotateAroundLocalY()
|
||||
//! Rotates the entity around the world's Y axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Y axis.
|
||||
virtual void RotateByY([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use RotateAroundLocalZ()
|
||||
//! Rotates the entity around the world's Z axis.
|
||||
//! The origin of the axis is the entity's position in world space.
|
||||
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Z axis.
|
||||
virtual void RotateByZ([[maybe_unused]] float eulerAngleRadian) {}
|
||||
|
||||
//! @deprecated Use GetLocalRotation()
|
||||
//! Gets the entity's rotation in the world in Euler angles rotation in radians.
|
||||
//! @return A three-dimensional vector, containing Euler angles in radians, that represents the entity's rotation.
|
||||
virtual AZ::Vector3 GetRotationEulerRadians() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! @deprecated Use GetLocalRotationQuaternion()
|
||||
//! Gets the entity's rotation in the world in quaternion format.
|
||||
//! @return A quaternion that represents the entity's rotation in world space.
|
||||
virtual AZ::Quaternion GetRotationQuaternion() { return AZ::Quaternion::CreateZero(); }
|
||||
|
||||
//! @deprecated Use GetLocalRotation()
|
||||
//! Gets the entity's rotation around the world's X axis.
|
||||
//! @return The Euler angle in radians by which the the entity is rotated around the X axis in world space.
|
||||
virtual float GetRotationX() { return FLT_MAX; }
|
||||
|
||||
//! @deprecated Use GetLocalRotation()
|
||||
//! Gets the entity's rotation around the world's Y axis.
|
||||
//! @return The Euler angle in radians by which the the entity is rotated around the Y axis in world space.
|
||||
virtual float GetRotationY() { return FLT_MAX; }
|
||||
|
||||
//! @deprecated Use GetLocalRotation()
|
||||
//! Gets the entity's rotation around the world's Z axis.
|
||||
//! @return The Euler angle in radians by which the the entity is rotated around the Z axis in world space.
|
||||
virtual float GetRotationZ() { return FLT_MAX; }
|
||||
virtual void SetWorldRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {}
|
||||
|
||||
//! Get angles in radian for each principle axis around which the world transform is
|
||||
//! rotated in the order of z-axis and y-axis and then x-axis.
|
||||
@@ -287,18 +219,11 @@ namespace AZ
|
||||
|
||||
//! Scale modifiers
|
||||
//! @{
|
||||
//! Set local scale of the transform.
|
||||
//! @param scale The new scale to set.
|
||||
virtual void SetLocalScale([[maybe_unused]] const AZ::Vector3& scale) {}
|
||||
|
||||
//! Get the scale value in local space.
|
||||
//! @deprecated GetLocalScale is deprecated, and is left only to allow migration of legacy vector scale.
|
||||
//! Get the legacy vector scale value in local space.
|
||||
//! @return The scale value in local space.
|
||||
virtual AZ::Vector3 GetLocalScale() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! Get the scale value in world space.
|
||||
//! @return The scale value in world space.
|
||||
virtual AZ::Vector3 GetWorldScale() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! Set the uniform scale value in local space.
|
||||
virtual void SetLocalUniformScale([[maybe_unused]] float scale) {}
|
||||
|
||||
|
||||
@@ -95,6 +95,12 @@ namespace AZ::IO
|
||||
constexpr int Compare(AZStd::string_view pathString) const noexcept;
|
||||
constexpr int Compare(const value_type* pathString) const noexcept;
|
||||
|
||||
// Extension for fixed strings
|
||||
//! extension: fixed string types with MaxPathLength capacity
|
||||
//! Returns a new instance of an AZStd::fixed_string with capacity of MaxPathLength
|
||||
//! made from the internal string
|
||||
constexpr AZStd::fixed_string<MaxPathLength> FixedMaxPathString() const noexcept;
|
||||
|
||||
// decomposition
|
||||
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
|
||||
//! "/O3DE/foo/bar/name.txt"
|
||||
|
||||
@@ -915,6 +915,11 @@ namespace AZ::IO
|
||||
return compare_string_view(path);
|
||||
}
|
||||
|
||||
constexpr AZStd::fixed_string<MaxPathLength> PathView::FixedMaxPathString() const noexcept
|
||||
{
|
||||
return AZStd::fixed_string<MaxPathLength>(m_path.begin(), m_path.end());
|
||||
}
|
||||
|
||||
// decomposition
|
||||
constexpr auto PathView::RootName() const -> PathView
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Platform
|
||||
|
||||
using FileHandleType = SystemFile::FileHandleType;
|
||||
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode);
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode);
|
||||
SystemFile::SizeType Tell(FileHandleType handle, const SystemFile* systemFile);
|
||||
bool Eof(FileHandleType handle, const SystemFile* systemFile);
|
||||
AZ::u64 ModificationTime(FileHandleType handle, const SystemFile* systemFile);
|
||||
@@ -68,9 +68,8 @@ void SystemFile::CreatePath(const char* fileName)
|
||||
}
|
||||
|
||||
SystemFile::SystemFile()
|
||||
: m_handle{ AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE }
|
||||
{
|
||||
m_fileName[0] = '\0';
|
||||
m_handle = AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
SystemFile::~SystemFile()
|
||||
@@ -81,6 +80,25 @@ SystemFile::~SystemFile()
|
||||
}
|
||||
}
|
||||
|
||||
SystemFile::SystemFile(SystemFile&& other)
|
||||
: SystemFile{}
|
||||
{
|
||||
AZStd::swap(m_fileName, other.m_fileName);
|
||||
AZStd::swap(m_handle, other.m_handle);
|
||||
}
|
||||
|
||||
SystemFile& SystemFile::operator=(SystemFile&& other)
|
||||
{
|
||||
// Close the current file and take over the SystemFile handle and filename
|
||||
Close();
|
||||
m_fileName = AZStd::move(other.m_fileName);
|
||||
m_handle = AZStd::move(other.m_handle);
|
||||
other.m_fileName = {};
|
||||
other.m_handle = AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Open - %s", fileName);
|
||||
@@ -88,42 +106,42 @@ bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
|
||||
|
||||
if (fileName) // If we reopen the file we are allowed to have NULL file name
|
||||
{
|
||||
if (strlen(fileName) > AZ_ARRAY_SIZE(m_fileName) - 1)
|
||||
if (strlen(fileName) > m_fileName.max_size())
|
||||
{
|
||||
EBUS_EVENT(FileIOEventBus, OnError, this, nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// store the filename
|
||||
azsnprintf(m_fileName, AZ_ARRAY_SIZE(m_fileName), "%s", fileName);
|
||||
m_fileName = fileName;
|
||||
}
|
||||
|
||||
if (FileIOBus::HasHandlers())
|
||||
{
|
||||
bool isOpen = false;
|
||||
bool isHandled = false;
|
||||
EBUS_EVENT_RESULT(isHandled, FileIOBus, OnOpen, *this, m_fileName, mode, platformFlags, isOpen);
|
||||
EBUS_EVENT_RESULT(isHandled, FileIOBus, OnOpen, *this, m_fileName.c_str(), mode, platformFlags, isOpen);
|
||||
if (isHandled)
|
||||
{
|
||||
return isOpen;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Assert(!IsOpen(), "This file (%s) is already open!", m_fileName);
|
||||
AZ_Assert(!IsOpen(), "This file (%s) is already open!", m_fileName.c_str());
|
||||
|
||||
return PlatformOpen(mode, platformFlags);
|
||||
}
|
||||
|
||||
bool SystemFile::ReOpen(int mode, int platformFlags)
|
||||
{
|
||||
AZ_Assert(strlen(m_fileName) > 0, "Missing filename. You must call open first!");
|
||||
AZ_Assert(!m_fileName.empty(), "Missing filename. You must call open first!");
|
||||
return Open(0, mode, platformFlags);
|
||||
}
|
||||
|
||||
void SystemFile::Close()
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Close - %s", m_fileName);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Close - %s", m_fileName);
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Close - %s", m_fileName.c_str());
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Close - %s", m_fileName.c_str());
|
||||
|
||||
if (FileIOBus::HasHandlers())
|
||||
{
|
||||
@@ -138,9 +156,9 @@ void SystemFile::Close()
|
||||
PlatformClose();
|
||||
}
|
||||
|
||||
void SystemFile::Seek(SizeType offset, SeekMode mode)
|
||||
void SystemFile::Seek(SeekSizeType offset, SeekMode mode)
|
||||
{
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Seek - %s:%i", m_fileName, offset);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Seek - %s:%i", m_fileName.c_str(), offset);
|
||||
|
||||
if (FileIOBus::HasHandlers())
|
||||
{
|
||||
@@ -167,15 +185,15 @@ bool SystemFile::Eof()
|
||||
|
||||
AZ::u64 SystemFile::ModificationTime()
|
||||
{
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime - %s", m_fileName);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime - %s", m_fileName.c_str());
|
||||
|
||||
return Platform::ModificationTime(m_handle, this);
|
||||
}
|
||||
|
||||
SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Read - %s:%i", m_fileName, byteSize);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read - %s:%i", m_fileName, byteSize);
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
|
||||
|
||||
if (FileIOBus::HasHandlers())
|
||||
{
|
||||
@@ -193,8 +211,8 @@ SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
|
||||
|
||||
SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Write - %s:%i", m_fileName, byteSize);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Write - %s:%i", m_fileName, byteSize);
|
||||
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
|
||||
|
||||
if (FileIOBus::HasHandlers())
|
||||
{
|
||||
@@ -212,14 +230,14 @@ SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
|
||||
|
||||
void SystemFile::Flush()
|
||||
{
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Flush - %s", m_fileName);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Flush - %s", m_fileName.c_str());
|
||||
|
||||
Platform::Flush(m_handle, this);
|
||||
}
|
||||
|
||||
SystemFile::SizeType SystemFile::Length() const
|
||||
{
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length - %s", m_fileName);
|
||||
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length - %s", m_fileName.c_str());
|
||||
|
||||
return Platform::Length(m_handle, this);
|
||||
}
|
||||
@@ -379,9 +397,9 @@ namespace
|
||||
HasPosixEnumOption(PermissionModeFlags::Write);
|
||||
|
||||
#undef HasPosixEnumOption
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
FileDescriptorRedirector::FileDescriptorRedirector(int sourceFileDescriptor)
|
||||
: m_sourceFileDescriptor(sourceFileDescriptor)
|
||||
{
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/IO/SystemFile_Platform.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
|
||||
// Establish a consistent size that works across platforms. It's actually larger than this
|
||||
// on platforms we support, but this is a good least common denominator
|
||||
@@ -51,11 +52,15 @@ namespace AZ
|
||||
};
|
||||
|
||||
using SizeType = AZ::IO::Internal::SizeType;
|
||||
using SeekSizeType = AZ::IO::Internal::SeekSizeType;
|
||||
using FileHandleType = AZ::IO::Internal::FileHandleType;
|
||||
|
||||
SystemFile();
|
||||
~SystemFile();
|
||||
|
||||
SystemFile(SystemFile&&);
|
||||
SystemFile& operator=(SystemFile&&);
|
||||
|
||||
/**
|
||||
* Opens a file.
|
||||
* \param fileName full file name including path
|
||||
@@ -69,7 +74,7 @@ namespace AZ
|
||||
/// Closes a file, if file already close it has no effect.
|
||||
void Close();
|
||||
/// Seek in current file.
|
||||
void Seek(SizeType offset, SeekMode mode);
|
||||
void Seek(SeekSizeType offset, SeekMode mode);
|
||||
/// Get the cursor position in the current file.
|
||||
SizeType Tell();
|
||||
/// Is the cursor at the end of the file?
|
||||
@@ -87,7 +92,7 @@ namespace AZ
|
||||
/// Return disc offset if possible, otherwise 0
|
||||
SizeType DiskOffset() const;
|
||||
/// Return file name or NULL if file is not open.
|
||||
AZ_FORCE_INLINE const char* Name() const { return m_fileName; }
|
||||
AZ_FORCE_INLINE const char* Name() const { return m_fileName.c_str(); }
|
||||
bool IsOpen() const;
|
||||
|
||||
/// Return native handle to the file.
|
||||
@@ -124,12 +129,12 @@ namespace AZ
|
||||
|
||||
private:
|
||||
static void CreatePath(const char * fileName);
|
||||
|
||||
|
||||
bool PlatformOpen(int mode, int platformFlags);
|
||||
void PlatformClose();
|
||||
|
||||
FileHandleType m_handle;
|
||||
char m_fileName[AZ_MAX_PATH_LEN];
|
||||
|
||||
FileHandleType m_handle;
|
||||
AZ::IO::FixedMaxPathString m_fileName;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace AZ
|
||||
// the min and max of each part and sum them to get the min and max co-ordinate of the transformed box. For a given new axis,
|
||||
// the coefficients for what proportion of each original axis is rotated onto that new axis are the same as the components we
|
||||
// would get by performing the inverse rotation on the new axis, so we need to take the conjugate to get the inverse rotation.
|
||||
axisCoeffs = transform.GetScale() * (transform.GetRotation().GetConjugate().TransformVector(axis));
|
||||
axisCoeffs = transform.GetUniformScale() * (transform.GetRotation().GetConjugate().TransformVector(axis));
|
||||
a = axisCoeffs * m_min;
|
||||
b = axisCoeffs * m_max;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace AZ
|
||||
return Obb::CreateFromPositionRotationAndHalfLengths(
|
||||
transform.TransformPoint(obb.GetPosition()),
|
||||
transform.GetRotation() * obb.GetRotation(),
|
||||
transform.GetScale() * obb.GetHalfLengths()
|
||||
transform.GetUniformScale() * obb.GetHalfLengths()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ namespace AZ
|
||||
const Transform* transform = reinterpret_cast<const Transform*>(classPtr);
|
||||
float data[NumFloats];
|
||||
transform->GetRotation().StoreToFloat4(data);
|
||||
transform->GetScale().StoreToFloat3(&data[4]);
|
||||
transform->GetTranslation().StoreToFloat3(&data[7]);
|
||||
data[4] = transform->GetUniformScale();
|
||||
transform->GetTranslation().StoreToFloat3(&data[5]);
|
||||
|
||||
for (int i = 0; i < NumFloats; i++)
|
||||
{
|
||||
@@ -159,8 +159,8 @@ namespace AZ
|
||||
|
||||
size_t TransformSerializer::TextToData(const char* text, unsigned int textVersion, IO::GenericStream& stream, bool isDataBigEndian)
|
||||
{
|
||||
const size_t dataBufferSize = AZStd::max(NumFloatsVersion0, NumFloats);
|
||||
const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : NumFloats;
|
||||
const size_t dataBufferSize = AZStd::max(AZStd::max(NumFloatsVersion1, NumFloatsVersion0), NumFloats);
|
||||
const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : (textVersion == 1 ? NumFloatsVersion1 : NumFloats);
|
||||
|
||||
size_t nextNumberIndex = 0;
|
||||
AZStd::array<float, dataBufferSize> data;
|
||||
@@ -201,7 +201,34 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise load as a separate rotation, scale and translation
|
||||
// version 1 had a quaternion rotation, vector3 scale and vector3 translation
|
||||
else if (version == 1)
|
||||
{
|
||||
float data[NumFloatsVersion1];
|
||||
if (stream.GetLength() < sizeof(data))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.Read(sizeof(data), reinterpret_cast<void*>(data));
|
||||
|
||||
for (unsigned int i = 0; i < AZ_ARRAY_SIZE(data); ++i)
|
||||
{
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(data[i], isDataBigEndian);
|
||||
}
|
||||
|
||||
Quaternion rotation = Quaternion::CreateFromFloat4(data);
|
||||
Vector3 vectorScale = Vector3::CreateFromFloat3(&data[4]);
|
||||
Vector3 translation = Vector3::CreateFromFloat3(&data[7]);
|
||||
|
||||
float uniformScale = vectorScale.GetMaxElement();
|
||||
|
||||
*reinterpret_cast<Transform*>(classPtr) =
|
||||
Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(uniformScale);
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise load as a quaternion rotation, float scale and vector3 translation
|
||||
float data[NumFloats];
|
||||
if (stream.GetLength() < sizeof(data))
|
||||
{
|
||||
@@ -216,11 +243,11 @@ namespace AZ
|
||||
}
|
||||
|
||||
Quaternion rotation = Quaternion::CreateFromFloat4(data);
|
||||
Vector3 scale = Vector3::CreateFromFloat3(&data[4]);
|
||||
Vector3 translation = Vector3::CreateFromFloat3(&data[7]);
|
||||
float scale = data[4];
|
||||
Vector3 translation = Vector3::CreateFromFloat3(&data[5]);
|
||||
|
||||
*reinterpret_cast<Transform*>(classPtr) =
|
||||
Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateScale(scale);
|
||||
Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(scale);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -237,7 +264,7 @@ namespace AZ
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<Transform>()
|
||||
->Version(1)
|
||||
->Version(2)
|
||||
->Serializer<TransformSerializer>();
|
||||
}
|
||||
|
||||
@@ -250,7 +277,7 @@ namespace AZ
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::TransformDefaultConstructor)->
|
||||
Constructor<const Vector3&, const Quaternion&, const Vector3&>()->
|
||||
Constructor<const Vector3&, const Quaternion&, float>()->
|
||||
Method("GetBasis", &Transform::GetBasis)->
|
||||
Method("GetBasisX", &Transform::GetBasisX)->
|
||||
Method("GetBasisY", &Transform::GetBasisY)->
|
||||
@@ -283,15 +310,10 @@ namespace AZ
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Method("GetRotation", &Transform::GetRotation)->
|
||||
Method<void (Transform::*)(const Quaternion&)>("SetRotation", &Transform::SetRotation)->
|
||||
Method("GetScale", &Transform::GetScale)->
|
||||
Method("GetUniformScale", &Transform::GetUniformScale)->
|
||||
Method("SetScale", &Transform::SetScale)->
|
||||
Method("SetUniformScale", &Transform::SetUniformScale)->
|
||||
Method("ExtractScale", &Transform::ExtractScale)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Method("ExtractUniformScale", &Transform::ExtractUniformScale)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Method("MultiplyByScale", &Transform::MultiplyByScale)->
|
||||
Method("MultiplyByUniformScale", &Transform::MultiplyByUniformScale)->
|
||||
Method("GetInverse", &Transform::GetInverse)->
|
||||
Method("Invert", &Transform::Invert)->
|
||||
@@ -310,7 +332,6 @@ namespace AZ
|
||||
Method("CreateFromQuaternionAndTranslation", &Transform::CreateFromQuaternionAndTranslation)->
|
||||
Method("CreateFromMatrix3x3", &Transform::CreateFromMatrix3x3)->
|
||||
Method("CreateFromMatrix3x3AndTranslation", &Transform::CreateFromMatrix3x3AndTranslation)->
|
||||
Method("CreateScale", &Transform::CreateScale)->
|
||||
Method("CreateUniformScale", &Transform::CreateUniformScale)->
|
||||
Method("CreateTranslation", &Transform::CreateTranslation)->
|
||||
Method("ConstructFromValuesNumeric", &Internal::ConstructTransformFromValues);
|
||||
@@ -321,7 +342,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
Matrix3x3 tmp = value;
|
||||
result.m_scale = tmp.ExtractScale();
|
||||
result.m_scale = tmp.ExtractScale().GetMaxElement();
|
||||
result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp);
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
@@ -331,7 +352,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
Matrix3x3 tmp = value;
|
||||
result.m_scale = tmp.ExtractScale();
|
||||
result.m_scale = tmp.ExtractScale().GetMaxElement();
|
||||
result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp);
|
||||
result.m_translation = p;
|
||||
return result;
|
||||
@@ -341,7 +362,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
Matrix3x4 tmp = value;
|
||||
result.m_scale = tmp.ExtractScale();
|
||||
result.m_scale = tmp.ExtractScale().GetMaxElement();
|
||||
result.m_rotation = Quaternion::CreateFromMatrix3x4(tmp);
|
||||
result.m_translation = value.GetTranslation();
|
||||
return result;
|
||||
|
||||
@@ -25,10 +25,13 @@ namespace AZ
|
||||
: public SerializeContext::IDataSerializer
|
||||
{
|
||||
public:
|
||||
// number of floats in the serialized representation, 4 for rotation, 3 for scale and 3 for translation
|
||||
static constexpr int NumFloats = 10;
|
||||
// number of floats in the serialized representation, 4 for rotation, 1 for scale and 3 for translation
|
||||
static constexpr int NumFloats = 8;
|
||||
|
||||
// number of floats in the old format, which stored a 3x4 matrix
|
||||
// number of floats in version 1, which used 4 for rotation, 3 for scale and 3 for translation
|
||||
static constexpr int NumFloatsVersion1 = 10;
|
||||
|
||||
// number of floats in version 0, which stored a 3x4 matrix
|
||||
static constexpr int NumFloatsVersion0 = 12;
|
||||
|
||||
size_t Save(const void* classPtr, IO::GenericStream& stream, bool isDataBigEndian) override;
|
||||
@@ -45,7 +48,7 @@ namespace AZ
|
||||
static constexpr float MaxTransformScale = 1e9f;
|
||||
//! @}
|
||||
|
||||
//! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation.
|
||||
//! The basic transformation class, represented using a quaternion rotation, float scale and vector translation.
|
||||
//! By design, cannot represent skew transformations.
|
||||
class Transform
|
||||
{
|
||||
@@ -63,7 +66,7 @@ namespace AZ
|
||||
Transform() = default;
|
||||
|
||||
//! Construct a transform from components.
|
||||
Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
|
||||
Transform(const Vector3& translation, const Quaternion& rotation, float scale);
|
||||
|
||||
//! Creates an identity transform.
|
||||
static Transform CreateIdentity();
|
||||
@@ -82,16 +85,20 @@ namespace AZ
|
||||
static Transform CreateFromQuaternionAndTranslation(const class Quaternion& q, const Vector3& p);
|
||||
|
||||
//! Constructs from a Matrix3x3, translation is set to zero.
|
||||
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
|
||||
//! the largest matrix scale value will be used to uniformly scale the Transform.
|
||||
static Transform CreateFromMatrix3x3(const class Matrix3x3& value);
|
||||
|
||||
//! Constructs from a Matrix3x3, translation is set to zero.
|
||||
//! Constructs from a Matrix3x3 and translation Vector3.
|
||||
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
|
||||
//! the largest matrix scale value will be used to uniformly scale the Transform.
|
||||
static Transform CreateFromMatrix3x3AndTranslation(const class Matrix3x3& value, const Vector3& p);
|
||||
|
||||
//! Constructs from a Matrix3x4.
|
||||
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
|
||||
//! the largest matrix scale value will be used to uniformly scale the Transform.
|
||||
static Transform CreateFromMatrix3x4(const Matrix3x4& value);
|
||||
|
||||
//! Sets the transform to apply scale only, no rotation or translation.
|
||||
static Transform CreateScale(const AZ::Vector3& scale);
|
||||
|
||||
//! Sets the transform to apply (uniform) scale only, no rotation or translation.
|
||||
static Transform CreateUniformScale(const float scale);
|
||||
|
||||
@@ -122,18 +129,12 @@ namespace AZ
|
||||
const Quaternion& GetRotation() const;
|
||||
void SetRotation(const Quaternion& rotation);
|
||||
|
||||
Vector3 GetScale() const;
|
||||
float GetUniformScale() const;
|
||||
void SetScale(const Vector3& v);
|
||||
void SetUniformScale(const float scale);
|
||||
|
||||
//! Sets the transform's scale to a unit value and returns the previous scale value.
|
||||
Vector3 ExtractScale();
|
||||
|
||||
//! Sets the transform's scale to a unit value and returns the previous scale value.
|
||||
float ExtractUniformScale();
|
||||
|
||||
void MultiplyByScale(const AZ::Vector3& scale);
|
||||
void MultiplyByUniformScale(float scale);
|
||||
|
||||
Transform operator*(const Transform& rhs) const;
|
||||
@@ -168,7 +169,7 @@ namespace AZ
|
||||
private:
|
||||
|
||||
Quaternion m_rotation;
|
||||
Vector3 m_scale;
|
||||
float m_scale;
|
||||
Vector3 m_translation;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale)
|
||||
AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, float scale)
|
||||
: m_translation(translation)
|
||||
, m_rotation(rotation)
|
||||
, m_scale(scale)
|
||||
@@ -25,7 +25,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = Vector3::CreateOne();
|
||||
result.m_scale = 1.0f;
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = q;
|
||||
result.m_scale = Vector3::CreateOne();
|
||||
result.m_scale = 1.0f;
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
}
|
||||
@@ -58,26 +58,16 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = q;
|
||||
result.m_scale = Vector3::CreateOne();
|
||||
result.m_scale = 1.0f;
|
||||
result.m_translation = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::CreateScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "CreateScale is deprecated, please use CreateUniformScale instead.");
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = scale;
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::CreateUniformScale(float scale)
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = Vector3(scale);
|
||||
result.m_scale = scale;
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
}
|
||||
@@ -86,7 +76,7 @@ namespace AZ
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = Vector3::CreateOne();
|
||||
result.m_scale = 1.0f;
|
||||
result.m_translation = translation;
|
||||
return result;
|
||||
}
|
||||
@@ -114,17 +104,17 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::GetBasisX() const
|
||||
{
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale.GetX()));
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale));
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::GetBasisY() const
|
||||
{
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale.GetY()));
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale));
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::GetBasisZ() const
|
||||
{
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale.GetZ()));
|
||||
return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale));
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::GetBasisAndTranslation(Vector3* basisX, Vector3* basisY, Vector3* basisZ, Vector3* pos) const
|
||||
@@ -160,49 +150,23 @@ namespace AZ
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::GetScale() const
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "GetScale is deprecated, please use GetUniformScale instead.");
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE float Transform::GetUniformScale() const
|
||||
{
|
||||
return m_scale.GetMaxElement();
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::SetScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "SetScale is deprecated, please use SetUniformScale instead.");
|
||||
m_scale = scale;
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::SetUniformScale(const float scale)
|
||||
{
|
||||
m_scale = Vector3(scale);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::ExtractScale()
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "ExtractScale is deprecated, please use ExtractUniformScale instead.");
|
||||
const Vector3 scale = m_scale;
|
||||
m_scale = Vector3::CreateOne();
|
||||
return scale;
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE float Transform::ExtractUniformScale()
|
||||
{
|
||||
const float scale = m_scale.GetMaxElement();
|
||||
m_scale = Vector3::CreateOne();
|
||||
const float scale = m_scale;
|
||||
m_scale = 1.0f;
|
||||
return scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::MultiplyByScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "MultiplyByScale is deprecated, please use MultiplyByUniformScale instead.");
|
||||
m_scale *= scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::MultiplyByUniformScale(float scale)
|
||||
{
|
||||
m_scale *= scale;
|
||||
@@ -240,10 +204,9 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::GetInverse() const
|
||||
{
|
||||
// note - need to be careful about how to calculate inverse when there is non-uniform scale
|
||||
Transform out;
|
||||
out.m_rotation = m_rotation.GetConjugate();
|
||||
out.m_scale = m_scale.GetReciprocal();
|
||||
out.m_scale = 1.0f / m_scale;
|
||||
out.m_translation = -out.m_scale * (out.m_rotation.TransformVector(m_translation));
|
||||
return out;
|
||||
}
|
||||
@@ -255,27 +218,27 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE bool Transform::IsOrthogonal(float tolerance) const
|
||||
{
|
||||
return m_scale.IsClose(Vector3::CreateOne(), tolerance);
|
||||
return AZ::IsClose(m_scale, 1.0f, tolerance);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::GetOrthogonalized() const
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = m_rotation;
|
||||
result.m_scale = Vector3::CreateOne();
|
||||
result.m_scale = 1.0f;
|
||||
result.m_translation = m_translation;
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::Orthogonalize()
|
||||
{
|
||||
m_scale = Vector3::CreateOne();
|
||||
m_scale = 1.0f;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE bool Transform::IsClose(const Transform& rhs, float tolerance) const
|
||||
{
|
||||
return m_rotation.IsClose(rhs.m_rotation, tolerance)
|
||||
&& m_scale.IsClose(rhs.m_scale, tolerance)
|
||||
&& AZ::IsClose(m_scale, rhs.m_scale, tolerance)
|
||||
&& m_translation.IsClose(rhs.m_translation, tolerance);
|
||||
}
|
||||
|
||||
@@ -304,21 +267,21 @@ namespace AZ
|
||||
AZ_MATH_INLINE void Transform::SetFromEulerDegrees(const Vector3& eulerDegrees)
|
||||
{
|
||||
m_translation = Vector3::CreateZero();
|
||||
m_scale = Vector3::CreateOne();
|
||||
m_scale = 1.0f;
|
||||
m_rotation.SetFromEulerDegrees(eulerDegrees);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::SetFromEulerRadians(const Vector3& eulerRadians)
|
||||
{
|
||||
m_translation = Vector3::CreateZero();
|
||||
m_scale = Vector3::CreateOne();
|
||||
m_scale = 1.0f;
|
||||
m_rotation.SetFromEulerRadians(eulerRadians);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE bool Transform::IsFinite() const
|
||||
{
|
||||
return m_rotation.IsFinite()
|
||||
&& m_scale.IsFinite()
|
||||
&& AZ::IsFiniteFloat(m_scale)
|
||||
&& m_translation.IsFinite();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace AZ
|
||||
|
||||
result.Combine(loadResult);
|
||||
|
||||
transformInstance->SetScale(AZ::Vector3(scale));
|
||||
transformInstance->SetUniformScale(scale);
|
||||
}
|
||||
|
||||
return context.Report(
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace AZ
|
||||
// Load DLLs specified in the application descriptor
|
||||
for (const auto& moduleDescriptor : modules)
|
||||
{
|
||||
// For each module that is loaded, attempt to set the module's folder as a path for dependent module resolution
|
||||
// For each module that is loaded, attempt to set the module's folder as a path for dependent module resolution
|
||||
moduleSearchPathHelper.SetModuleSearchPath(moduleDescriptor);
|
||||
|
||||
LoadModuleOutcome result = LoadDynamicModule(moduleDescriptor.m_dynamicLibraryPath.c_str(), lastStepToPerform, maintainReferences);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformAndroid, PlatformIOS, PlatformMac, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
@@ -31,11 +31,11 @@ namespace AZ
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::ES3:
|
||||
case AZ::ANDROID_ID:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
return "iOS";
|
||||
case AZ::OSX:
|
||||
case AZ::MAC_ID:
|
||||
return "Mac";
|
||||
case AZ::PROVO:
|
||||
return "Provo";
|
||||
@@ -66,11 +66,11 @@ namespace AZ
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
return PlatformMac;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
return PlatformAndroid;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
@@ -207,13 +207,13 @@ namespace AZ
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
case PlatformId::ANDROID_ID:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
case PlatformId::MAC_ID:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
|
||||
@@ -27,9 +27,9 @@ namespace AZ
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformAndroid[] = "android";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformMac[] = "mac";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
@@ -54,9 +54,9 @@ namespace AZ
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
ANDROID_ID,
|
||||
IOS,
|
||||
OSX,
|
||||
MAC_ID,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
@@ -73,9 +73,9 @@ namespace AZ
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_ANDROID = 1 << PlatformId::ANDROID_ID,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_MAC = 1 << PlatformId::MAC_ID,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
@@ -87,7 +87,7 @@ namespace AZ
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
AllNamedPlatforms = Platform_PC | Platform_ANDROID | Platform_IOS | Platform_MAC | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace AZ
|
||||
return "Android64";
|
||||
case PlatformID::PLATFORM_APPLE_IOS:
|
||||
return "iOS";
|
||||
case PlatformID::PLATFORM_APPLE_OSX:
|
||||
return "OSX";
|
||||
case PlatformID::PLATFORM_APPLE_MAC:
|
||||
return "Mac";
|
||||
#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
|
||||
case PlatformID::PLATFORM_##PUBLICNAME:\
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AZ
|
||||
PLATFORM_WINDOWS_64,
|
||||
PLATFORM_LINUX_64,
|
||||
PLATFORM_APPLE_IOS,
|
||||
PLATFORM_APPLE_OSX,
|
||||
PLATFORM_APPLE_MAC,
|
||||
PLATFORM_ANDROID_64, // ARMv8 / 64-bit
|
||||
#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -937,7 +937,7 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection)
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_LINUX_64)>("Linux")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_ANDROID_64)>("Android64")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_APPLE_IOS)>("iOS")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_APPLE_OSX)>("OSX")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_APPLE_MAC)>("Mac")
|
||||
#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_##PUBLICNAME)>(#CodeName)
|
||||
|
||||
@@ -127,13 +127,14 @@ namespace AZ
|
||||
*/
|
||||
class EditContext
|
||||
{
|
||||
public:
|
||||
/// @cond EXCLUDE_DOCS
|
||||
class ClassBuilder;
|
||||
class EnumBuilder;
|
||||
using ClassInfo = ClassBuilder; ///< @deprecated Use EditContext::ClassBuilder
|
||||
using EnumInfo = EnumBuilder; ///< @deprecated Use EditContext::EnumBuilder
|
||||
/// @endcond
|
||||
public:
|
||||
|
||||
AZ_CLASS_ALLOCATOR(EditContext, SystemAllocator, 0);
|
||||
|
||||
/**
|
||||
@@ -186,6 +187,7 @@ namespace AZ
|
||||
* look at the unit tests and example to see use cases.
|
||||
*
|
||||
*/
|
||||
public:
|
||||
class ClassBuilder
|
||||
{
|
||||
friend EditContext;
|
||||
@@ -399,6 +401,7 @@ namespace AZ
|
||||
EnumBuilder* Value(const char* name, E value);
|
||||
};
|
||||
|
||||
private:
|
||||
typedef AZStd::list<Edit::ClassData> ClassDataListType;
|
||||
typedef AZStd::unordered_map<AZ::Uuid, Edit::ElementData> EnumDataMapType;
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ namespace AZ
|
||||
|
||||
const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab);
|
||||
const static AZ::Crc32 AssetPickerTitle = AZ_CRC_CE("AssetPickerTitle");
|
||||
const static AZ::Crc32 HideProductFilesInAssetPicker = AZ_CRC_CE("HideProductFilesInAssetPicker");
|
||||
const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909);
|
||||
//! Container attribute that is used to override labels for its elements given the index of the element
|
||||
const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2);
|
||||
|
||||
@@ -28,7 +28,13 @@ namespace AZ
|
||||
{
|
||||
namespace IdUtils
|
||||
{
|
||||
template<typename IdType>
|
||||
/**
|
||||
* \param AllowDuplicates - If true allows the same id to be registered multiple times,
|
||||
with the newer value overwriting the stored value. If false, duplicates are not allowed and
|
||||
the first stored value is kept.The default is false.
|
||||
*/
|
||||
|
||||
template<typename IdType, bool AllowDuplicates = false>
|
||||
struct Remapper
|
||||
{
|
||||
/**
|
||||
@@ -138,14 +144,18 @@ namespace AZ
|
||||
* \param context - The serialize context for enumerating the @classPtr elements
|
||||
*/
|
||||
template<typename T, typename MapType>
|
||||
static void GenerateNewIdsAndFixRefs(T* object, MapType& newIdMap, AZ::SerializeContext* context = nullptr)
|
||||
static void GenerateNewIdsAndFixRefs(
|
||||
T* object, MapType& newIdMap, AZ::SerializeContext* context = nullptr)
|
||||
{
|
||||
if (!context)
|
||||
{
|
||||
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
if (!context)
|
||||
{
|
||||
AZ_Error("Serialization", false, "No serialize context provided! Failed to get component application default serialize context! ComponentApp is not started or input serialize context should not be null!");
|
||||
AZ_Error(
|
||||
"Serialization", false,
|
||||
"No serialize context provided! Failed to get component application default serialize context! ComponentApp is "
|
||||
"not started or input serialize context should not be null!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -156,8 +166,16 @@ namespace AZ
|
||||
{
|
||||
if (idGenerator)
|
||||
{
|
||||
auto it = newIdMap.emplace(originalId, idGenerator());
|
||||
return it.first->second;
|
||||
if constexpr(AllowDuplicates)
|
||||
{
|
||||
auto it = newIdMap.insert_or_assign(originalId, idGenerator());
|
||||
return it.first->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = newIdMap.emplace(originalId, idGenerator());
|
||||
return it.first->second;
|
||||
}
|
||||
}
|
||||
return originalId;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,10 @@ namespace AZ
|
||||
bool m_isModifiedContainer;
|
||||
};
|
||||
|
||||
template<typename IdType>
|
||||
unsigned int Remapper<IdType>::RemapIds(void* classPtr, const AZ::Uuid& classUuid, const typename Remapper<IdType>::IdMapper& mapper, AZ::SerializeContext* context, bool replaceId)
|
||||
template<typename IdType, bool AllowDuplicates>
|
||||
unsigned int Remapper<IdType, AllowDuplicates>::RemapIds(
|
||||
void* classPtr, const AZ::Uuid& classUuid, const typename Remapper<IdType, AllowDuplicates>::IdMapper& mapper,
|
||||
AZ::SerializeContext* context, bool replaceId)
|
||||
{
|
||||
if (!context)
|
||||
{
|
||||
@@ -152,16 +154,18 @@ namespace AZ
|
||||
return replaced;
|
||||
}
|
||||
|
||||
template<typename IdType>
|
||||
unsigned int Remapper<IdType>::ReplaceIdsAndIdRefs(void* classPtr, const AZ::Uuid& classUuid, const IdMapper& mapper, AZ::SerializeContext* context /*= nullptr*/)
|
||||
template<typename IdType, bool AllowDuplicates>
|
||||
unsigned int Remapper<IdType, AllowDuplicates>::ReplaceIdsAndIdRefs(void* classPtr, const AZ::Uuid& classUuid, const IdMapper& mapper, AZ::SerializeContext* context /*= nullptr*/)
|
||||
{
|
||||
unsigned int replaced = RemapIds(classPtr, classUuid, mapper, context, true);
|
||||
replaced += RemapIds(classPtr, classUuid, mapper, context, false);
|
||||
return replaced;
|
||||
}
|
||||
|
||||
template<typename IdType>
|
||||
unsigned int Remapper<IdType>::RemapIdsAndIdRefs(void* classPtr, const AZ::Uuid& classUuid, const typename Remapper<IdType>::IdReplacer& mapper, AZ::SerializeContext* context)
|
||||
template<typename IdType, bool AllowDuplicates>
|
||||
unsigned int Remapper<IdType, AllowDuplicates>::RemapIdsAndIdRefs(
|
||||
void* classPtr, const AZ::Uuid& classUuid, const typename Remapper<IdType, AllowDuplicates>::IdReplacer& mapper,
|
||||
AZ::SerializeContext* context)
|
||||
{
|
||||
if (!context)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -101,6 +101,9 @@ namespace AZ
|
||||
class SerializeContext
|
||||
: public ReflectContext
|
||||
{
|
||||
static const unsigned int VersionClassDeprecated = (unsigned int)-1;
|
||||
|
||||
public:
|
||||
/// @cond EXCLUDE_DOCS
|
||||
friend class EditContext;
|
||||
class ClassBuilder;
|
||||
@@ -108,9 +111,6 @@ namespace AZ
|
||||
/// @endcond
|
||||
class EnumBuilder;
|
||||
|
||||
static const unsigned int VersionClassDeprecated = (unsigned int)-1;
|
||||
|
||||
public:
|
||||
class ClassData;
|
||||
struct EnumerateInstanceCallContext;
|
||||
struct ClassElement;
|
||||
@@ -1131,6 +1131,7 @@ namespace AZ
|
||||
* ->Version(3,&MyVersionConverter)
|
||||
* ->Field("data",&MyStruct::m_data);
|
||||
*/
|
||||
public:
|
||||
class ClassBuilder
|
||||
{
|
||||
friend class SerializeContext;
|
||||
@@ -1330,7 +1331,8 @@ namespace AZ
|
||||
AZStd::vector<AttributeSharedPair, AZStdFunctorAllocator>* m_currentAttributes = nullptr;
|
||||
};
|
||||
|
||||
EditContext* m_editContext; ///< Pointer to optional edit context.
|
||||
private:
|
||||
EditContext* m_editContext; ///< Pointer to optional edit context.
|
||||
UuidToClassMap m_uuidMap; ///< Map for all class in this serialize context
|
||||
AZStd::unordered_multimap<AZ::Crc32, AZ::Uuid> m_classNameToUuid; /// Map all class names to their uuid
|
||||
AZStd::unordered_multimap<Uuid, GenericClassInfo*> m_uuidGenericMap; ///< Uuid to ClassData map of reflected classes with GenericTypeInfo
|
||||
|
||||
@@ -88,6 +88,35 @@ namespace AZ::Internal
|
||||
m_enginePaths.emplace_back(EngineInfo{AZ::IO::FixedMaxPath{value}.LexicallyNormal(), {}});
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::VisitResponse Traverse(
|
||||
[[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName,
|
||||
AZ::SettingsRegistryInterface::VisitAction action, AZ::SettingsRegistryInterface::Type type) override
|
||||
{
|
||||
auto response = AZ::SettingsRegistryInterface::VisitResponse::Continue;
|
||||
if (action == AZ::SettingsRegistryInterface::VisitAction::Begin)
|
||||
{
|
||||
if (type == AZ::SettingsRegistryInterface::Type::Array)
|
||||
{
|
||||
if (valueName.compare("engines") != 0)
|
||||
{
|
||||
response = AZ::SettingsRegistryInterface::VisitResponse::Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action == AZ::SettingsRegistryInterface::VisitAction::Value)
|
||||
{
|
||||
if (type == AZ::SettingsRegistryInterface::Type::String)
|
||||
{
|
||||
if (valueName.compare("path") != 0)
|
||||
{
|
||||
response = AZ::SettingsRegistryInterface::VisitResponse::Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
AZStd::vector<EngineInfo> m_enginePaths{};
|
||||
};
|
||||
|
||||
@@ -612,6 +641,8 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the default ProjectUserPath to the <engine-root>/user directory
|
||||
registry.Set(FilePathKey_ProjectUserPath, (engineRoot / "user").LexicallyNormal().Native());
|
||||
AZ_TracePrintf("SettingsRegistryMergeUtils",
|
||||
R"(Project path isn't set in the Settings Registry at "%.*s". Project-related filepaths will not be set)" "\n",
|
||||
aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
|
||||
|
||||
@@ -971,6 +971,10 @@ namespace AZ
|
||||
*/
|
||||
void RestoreCachedInstances();
|
||||
|
||||
/// Returns data flags for use when instantiating an instance of this slice.
|
||||
/// These data flags include those harvested from the entire slice ancestry.
|
||||
const DataFlagsPerEntity& GetDataFlagsForInstances() const;
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1004,9 +1008,6 @@ namespace AZ
|
||||
DataFlagsPerEntity* GetCorrectBundleOfDataFlags(EntityId entityId);
|
||||
const DataFlagsPerEntity* GetCorrectBundleOfDataFlags(EntityId entityId) const;
|
||||
|
||||
/// Returns data flags for use when instantiating an instance of this slice.
|
||||
/// These data flags include those harvested from the entire slice ancestry.
|
||||
const DataFlagsPerEntity& GetDataFlagsForInstances() const;
|
||||
void BuildDataFlagsForInstances();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,11 +21,15 @@ namespace AZStd
|
||||
using std::asin;
|
||||
using std::atan;
|
||||
using std::atan2;
|
||||
using std::ceil;
|
||||
using std::cos;
|
||||
using std::exp2;
|
||||
using std::floor;
|
||||
using std::fmod;
|
||||
using std::pow;
|
||||
using std::round;
|
||||
using std::sin;
|
||||
using std::sqrt;
|
||||
using std::tan;
|
||||
using std::trunc;
|
||||
} // namespace AZStd
|
||||
|
||||
@@ -101,7 +101,7 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
|
||||
createPath = (mode & SF_OPEN_CREATE_PATH) == SF_OPEN_CREATE_PATH;
|
||||
}
|
||||
|
||||
bool isApkFile = AZ::Android::Utils::IsApkPath(m_fileName);
|
||||
bool isApkFile = AZ::Android::Utils::IsApkPath(m_fileName.c_str());
|
||||
|
||||
if (createPath)
|
||||
{
|
||||
@@ -111,19 +111,19 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
|
||||
return false;
|
||||
}
|
||||
|
||||
CreatePath(m_fileName);
|
||||
CreatePath(m_fileName.c_str());
|
||||
}
|
||||
|
||||
int errorCode = 0;
|
||||
if (isApkFile)
|
||||
{
|
||||
AZ::u64 size = 0;
|
||||
m_handle = AZ::Android::APKFileHandler::Open(m_fileName, openMode, size);
|
||||
m_handle = AZ::Android::APKFileHandler::Open(m_fileName.c_str(), openMode, size);
|
||||
errorCode = EACCES; // general error when a file can't be opened from inside the APK
|
||||
}
|
||||
else
|
||||
{
|
||||
m_handle = fopen(m_fileName, openMode);
|
||||
m_handle = fopen(m_fileName.c_str(), openMode);
|
||||
errorCode = errno;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace Platform
|
||||
}
|
||||
}
|
||||
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
|
||||
{
|
||||
if (handle != PlatformSpecificInvalidHandle)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <AzCore/std/typetraits/underlying_type.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -23,6 +26,7 @@ namespace AZ
|
||||
namespace Internal
|
||||
{
|
||||
using SizeType = AZ::u64;
|
||||
using SeekSizeType = AZ::s64;
|
||||
using FileHandleType = FILE*;
|
||||
}
|
||||
|
||||
@@ -37,7 +41,7 @@ namespace AZ
|
||||
#else
|
||||
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
|
||||
#endif
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
|
||||
// Note: The TRUNC flag destroys the contents of the specified file.
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <sys/syslimits.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <AzCore/std/typetraits/underlying_type.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -22,9 +25,10 @@ namespace AZ
|
||||
namespace Internal
|
||||
{
|
||||
using SizeType = AZ::u64;
|
||||
using SeekSizeType = AZ::s64;
|
||||
using FileHandleType = int;
|
||||
}
|
||||
|
||||
|
||||
namespace PosixInternal
|
||||
{
|
||||
enum class OpenFlags : int
|
||||
@@ -36,7 +40,7 @@ namespace AZ
|
||||
#else
|
||||
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
|
||||
#endif
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
|
||||
// Note: The TRUNC flag destroys the contents of the specified file.
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <AzCore/std/typetraits/underlying_type.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -21,6 +24,7 @@ namespace AZ
|
||||
namespace Internal
|
||||
{
|
||||
using SizeType = AZ::u64;
|
||||
using SeekSizeType = AZ::s64;
|
||||
using FileHandleType = int;
|
||||
}
|
||||
|
||||
@@ -35,7 +39,7 @@ namespace AZ
|
||||
#else
|
||||
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
|
||||
#endif
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
|
||||
// Note: The TRUNC flag destroys the contents of the specified file.
|
||||
|
||||
|
||||
+16
-7
@@ -13,9 +13,10 @@
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
|
||||
@@ -61,10 +62,11 @@ namespace AZ
|
||||
// If it doesn't attempt to append the path to the executable path
|
||||
if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str()))
|
||||
{
|
||||
auto candidatePath = Platform::GetModulePath() / fullFilePath;
|
||||
AZ::IO::FixedMaxPath candidatePath = Platform::GetModulePath() / fullFilePath;
|
||||
if (AZ::IO::SystemFile::Exists(candidatePath.c_str()))
|
||||
{
|
||||
fullFilePath = candidatePath;
|
||||
m_fileName.assign(candidatePath.Native().c_str(), candidatePath.Native().size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,19 +76,26 @@ namespace AZ
|
||||
{
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if(AZ::IO::FixedMaxPath projectModulePath;
|
||||
if (AZ::IO::FixedMaxPath projectModulePath;
|
||||
settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
projectModulePath /= fullFilePath;
|
||||
if (AZ::IO::SystemFile::Exists(projectModulePath.c_str()))
|
||||
{
|
||||
fullFilePath = projectModulePath;
|
||||
m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_fileName = AZStd::string_view{fullFilePath.Native()};
|
||||
else
|
||||
{
|
||||
// The module does exist (in 'cwd'), but still needs to be an absolute path for the module to be loaded.
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> absPathOptional = AZ::Utils::ConvertToAbsolutePath(m_fileName);
|
||||
if (absPathOptional.has_value())
|
||||
{
|
||||
m_fileName.assign(absPathOptional->c_str(), absPathOptional->size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~DynamicModuleHandleUnixLike() override
|
||||
|
||||
+3
-3
@@ -86,9 +86,9 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
|
||||
|
||||
if (createPath)
|
||||
{
|
||||
CreatePath(m_fileName);
|
||||
CreatePath(m_fileName.c_str());
|
||||
}
|
||||
m_handle = open(m_fileName, desiredAccess, permissions);
|
||||
m_handle = open(m_fileName.c_str(), desiredAccess, permissions);
|
||||
|
||||
if (m_handle == PlatformSpecificInvalidHandle)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ namespace Platform
|
||||
{
|
||||
using FileHandleType = AZ::IO::SystemFile::FileHandleType;
|
||||
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
|
||||
{
|
||||
if (handle != PlatformSpecificInvalidHandle)
|
||||
{
|
||||
|
||||
@@ -209,19 +209,19 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
|
||||
|
||||
if (createPath)
|
||||
{
|
||||
CreatePath(m_fileName);
|
||||
CreatePath(m_fileName.c_str());
|
||||
}
|
||||
|
||||
# ifdef _UNICODE
|
||||
wchar_t fileNameW[AZ_MAX_PATH_LEN];
|
||||
size_t numCharsConverted;
|
||||
m_handle = INVALID_HANDLE_VALUE;
|
||||
if (mbstowcs_s(&numCharsConverted, fileNameW, m_fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0)
|
||||
if (mbstowcs_s(&numCharsConverted, fileNameW, m_fileName.c_str(), AZ_ARRAY_SIZE(fileNameW) - 1) == 0)
|
||||
{
|
||||
m_handle = CreateFileW(fileNameW, dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
|
||||
}
|
||||
# else //!_UNICODE
|
||||
m_handle = CreateFile(m_fileName, dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
|
||||
m_handle = CreateFile(m_fileName.c_str(), dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
|
||||
# endif // !_UNICODE
|
||||
|
||||
if (m_handle == INVALID_HANDLE_VALUE)
|
||||
@@ -261,7 +261,7 @@ namespace Platform
|
||||
{
|
||||
using FileHandleType = AZ::IO::SystemFile::FileHandleType;
|
||||
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
|
||||
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
|
||||
{
|
||||
if (handle != PlatformSpecificInvalidHandle)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <corecrt_io.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <AzCore/std/typetraits/underlying_type.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -21,6 +24,7 @@ namespace AZ
|
||||
namespace Internal
|
||||
{
|
||||
using SizeType = AZ::u64;
|
||||
using SeekSizeType = AZ::s64;
|
||||
using FileHandleType = void*;
|
||||
}
|
||||
|
||||
@@ -31,7 +35,7 @@ namespace AZ
|
||||
Append = _O_APPEND, // Moves the file pointer to the end of the file before every write operation.
|
||||
Create = _O_CREAT, // Creates a file and opens it for writing. Has no effect if the file specified by filename exists. PermissionMode is required.
|
||||
Temporary = _O_TEMPORARY, // Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
|
||||
Exclusive = _O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Exclusive = _O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
|
||||
Truncate = _O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
|
||||
// Note: The TRUNC flag destroys the contents of the specified file.
|
||||
|
||||
|
||||
+13
-3
@@ -24,9 +24,9 @@ namespace AZ
|
||||
: public DynamicModuleHandle
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(DynamicModuleHandleWindows, OSAllocator, 0)
|
||||
AZ_CLASS_ALLOCATOR(DynamicModuleHandleWindows, OSAllocator, 0);
|
||||
|
||||
DynamicModuleHandleWindows(const char* fullFileName)
|
||||
DynamicModuleHandleWindows(const char* fullFileName)
|
||||
: DynamicModuleHandle(fullFileName)
|
||||
, m_handle(nullptr)
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace AZ
|
||||
if (AZ::IO::SystemFile::Exists(candidatePath.c_str()))
|
||||
{
|
||||
m_fileName.assign(candidatePath.Native().c_str(), candidatePath.Native().size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +66,7 @@ namespace AZ
|
||||
// Therefore an existence check is needed
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
if(AZ::IO::FixedMaxPath projectModulePath;
|
||||
if (AZ::IO::FixedMaxPath projectModulePath;
|
||||
settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
projectModulePath /= AZStd::string_view(m_fileName);
|
||||
@@ -76,6 +77,15 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The module does exist (in 'cwd'), but still needs to be an absolute path for the module to be loaded.
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> absPathOptional = AZ::Utils::ConvertToAbsolutePath(m_fileName);
|
||||
if (absPathOptional.has_value())
|
||||
{
|
||||
m_fileName.assign(absPathOptional->c_str(), absPathOptional->size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~DynamicModuleHandleWindows() override
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_OSX;
|
||||
static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_MAC;
|
||||
}
|
||||
|
||||
@@ -1914,7 +1914,7 @@ namespace UnitTest
|
||||
TEST_F(String, StringView_CompareIsConstexpr)
|
||||
{
|
||||
using TypeParam = char;
|
||||
auto MakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
auto ThisTestMakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
{
|
||||
return "HelloWorld";
|
||||
};
|
||||
@@ -1922,7 +1922,7 @@ namespace UnitTest
|
||||
{
|
||||
return "HelloPearl";
|
||||
};
|
||||
constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString2 = MakeCompileTimeString2();
|
||||
constexpr basic_string_view<TypeParam> lhsView(compileTimeString1);
|
||||
constexpr basic_string_view<TypeParam> rhsView(compileTimeString2);
|
||||
@@ -1937,11 +1937,11 @@ namespace UnitTest
|
||||
TEST_F(String, StringView_CompareOperatorsAreConstexpr)
|
||||
{
|
||||
using TypeParam = char;
|
||||
auto MakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
auto TestMakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
{
|
||||
return "HelloWorld";
|
||||
};
|
||||
constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString1 = TestMakeCompileTimeString1();
|
||||
constexpr basic_string_view<TypeParam> compareView(compileTimeString1);
|
||||
static_assert(compareView == "HelloWorld", "string_view operator== comparison has failed");
|
||||
static_assert(compareView != "MadWorld", "string_view operator!= comparison has failed");
|
||||
@@ -1955,7 +1955,7 @@ namespace UnitTest
|
||||
{
|
||||
auto swap_test_func = []() constexpr -> basic_string_view<TypeParam>
|
||||
{
|
||||
constexpr auto MakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
constexpr auto ThisTestMakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<TypeParam, char>)
|
||||
{
|
||||
@@ -1977,7 +1977,7 @@ namespace UnitTest
|
||||
return L"InuWorld";
|
||||
}
|
||||
};
|
||||
constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString2 = MakeCompileTimeString2();
|
||||
basic_string_view<TypeParam> lhsView(compileTimeString1);
|
||||
basic_string_view<TypeParam> rhsView(compileTimeString2);
|
||||
@@ -2001,7 +2001,7 @@ namespace UnitTest
|
||||
|
||||
TYPED_TEST(BasicStringViewConstexprFixture, HashString_FunctionIsConstexpr)
|
||||
{
|
||||
auto MakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
auto ThisTestMakeCompileTimeString1 = []() constexpr -> const TypeParam*
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<TypeParam, char>)
|
||||
{
|
||||
@@ -2012,7 +2012,7 @@ namespace UnitTest
|
||||
return L"HelloWorld";
|
||||
}
|
||||
};
|
||||
constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();
|
||||
constexpr const TypeParam* compileTimeString1 = ThisTestMakeCompileTimeString1();
|
||||
constexpr basic_string_view<TypeParam> hashView(compileTimeString1);
|
||||
constexpr size_t compileHash = AZStd::hash<basic_string_view<TypeParam>>{}(hashView);
|
||||
static_assert(compileHash != 0, "Hash of \"HelloWorld\" should not be 0");
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace AZ
|
||||
return os
|
||||
<< "translation: " << transform.GetTranslation()
|
||||
<< " rotation: " << transform.GetRotation()
|
||||
<< " scale: " << transform.GetScale();
|
||||
<< " scale: " << transform.GetUniformScale();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Color& color)
|
||||
|
||||
@@ -395,7 +395,8 @@ namespace UnitTest
|
||||
}
|
||||
else
|
||||
{
|
||||
int result1, result2;
|
||||
int result1 = 0;
|
||||
int result2 = 0;
|
||||
Job* job1 = aznew FibonacciJob2(m_n - 1, &result1, m_context);
|
||||
Job* job2 = aznew FibonacciJob2(m_n - 2, &result2, m_context);
|
||||
StartAsChild(job1);
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace UnitTest
|
||||
|
||||
TEST(MATH_Matrix4x4, TestCreateFrom)
|
||||
{
|
||||
float testFloats[] =
|
||||
float thisTestFloats[] =
|
||||
{
|
||||
1.0f, 2.0f, 3.0f, 4.0f,
|
||||
5.0f, 6.0f, 7.0f, 8.0f,
|
||||
@@ -67,20 +67,20 @@ namespace UnitTest
|
||||
13.0f, 14.0f, 15.0f, 16.0f
|
||||
};
|
||||
float testFloatMtx[16];
|
||||
Matrix4x4 m1 = Matrix4x4::CreateFromRowMajorFloat16(testFloats);
|
||||
Matrix4x4 m1 = Matrix4x4::CreateFromRowMajorFloat16(thisTestFloats);
|
||||
AZ_TEST_ASSERT(m1.GetRow(0) == Vector4(1.0f, 2.0f, 3.0f, 4.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(1) == Vector4(5.0f, 6.0f, 7.0f, 8.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(2) == Vector4(9.0f, 10.0f, 11.0f, 12.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(3) == Vector4(13.0f, 14.0f, 15.0f, 16.0f));
|
||||
m1.StoreToRowMajorFloat16(testFloatMtx);
|
||||
AZ_TEST_ASSERT(memcmp(testFloatMtx, testFloats, sizeof(testFloatMtx)) == 0);
|
||||
m1 = Matrix4x4::CreateFromColumnMajorFloat16(testFloats);
|
||||
AZ_TEST_ASSERT(memcmp(testFloatMtx, thisTestFloats, sizeof(testFloatMtx)) == 0);
|
||||
m1 = Matrix4x4::CreateFromColumnMajorFloat16(thisTestFloats);
|
||||
AZ_TEST_ASSERT(m1.GetRow(0) == Vector4(1.0f, 5.0f, 9.0f, 13.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(1) == Vector4(2.0f, 6.0f, 10.0f, 14.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(2) == Vector4(3.0f, 7.0f, 11.0f, 15.0f));
|
||||
AZ_TEST_ASSERT(m1.GetRow(3) == Vector4(4.0f, 8.0f, 12.0f, 16.0f));
|
||||
m1.StoreToColumnMajorFloat16(testFloatMtx);
|
||||
AZ_TEST_ASSERT(memcmp(testFloatMtx, testFloats, sizeof(testFloatMtx)) == 0);
|
||||
AZ_TEST_ASSERT(memcmp(testFloatMtx, thisTestFloats, sizeof(testFloatMtx)) == 0);
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestCreateFromMatrix3x4)
|
||||
|
||||
@@ -119,10 +119,10 @@ namespace UnitTest
|
||||
|
||||
TEST(MATH_Obb, Contains)
|
||||
{
|
||||
const Vector3 position(1.0f, 2.0f, 3.0f);
|
||||
const Quaternion rotation = Quaternion::CreateRotationZ(DegToRad(30.0f));
|
||||
const Vector3 halfLengths(2.0f, 1.0f, 2.5f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
|
||||
const Vector3 testPosition(1.0f, 2.0f, 3.0f);
|
||||
const Quaternion testRotation = Quaternion::CreateRotationZ(DegToRad(30.0f));
|
||||
const Vector3 testHalfLengths(2.0f, 1.0f, 2.5f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
|
||||
// test some pairs of points which should be just either side of the Obb boundary
|
||||
EXPECT_TRUE(obb.Contains(Vector3(1.35f, 3.35f, 3.5f)));
|
||||
EXPECT_FALSE(obb.Contains(Vector3(1.35f, 3.4f, 3.5f)));
|
||||
@@ -134,10 +134,10 @@ namespace UnitTest
|
||||
|
||||
TEST(MATH_Obb, GetDistance)
|
||||
{
|
||||
const Vector3 position(5.0f, 3.0f, 2.0f);
|
||||
const Quaternion rotation = Quaternion::CreateRotationX(DegToRad(60.0f));
|
||||
const Vector3 halfLengths(0.5f, 2.0f, 1.5f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
|
||||
const Vector3 testPosition(5.0f, 3.0f, 2.0f);
|
||||
const Quaternion testRotation = Quaternion::CreateRotationX(DegToRad(60.0f));
|
||||
const Vector3 testHalfLengths(0.5f, 2.0f, 1.5f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
|
||||
EXPECT_NEAR(obb.GetDistance(Vector3(5.3f, 3.2f, 1.8f)), 0.0f, 1e-3f);
|
||||
EXPECT_NEAR(obb.GetDistance(Vector3(5.1f, 1.1f, 3.7f)), 0.9955f, 1e-3f);
|
||||
EXPECT_NEAR(obb.GetDistance(Vector3(4.7f, 4.5f, 4.2f)), 0.6553f, 1e-3f);
|
||||
@@ -146,10 +146,10 @@ namespace UnitTest
|
||||
|
||||
TEST(MATH_Obb, GetDistanceSq)
|
||||
{
|
||||
const Vector3 position(1.0f, 4.0f, 3.0f);
|
||||
const Quaternion rotation = Quaternion::CreateRotationY(DegToRad(45.0f));
|
||||
const Vector3 halfLengths(1.5f, 3.0f, 1.0f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
|
||||
const Vector3 testPosition(1.0f, 4.0f, 3.0f);
|
||||
const Quaternion testRotation = Quaternion::CreateRotationY(DegToRad(45.0f));
|
||||
const Vector3 testHalfLengths(1.5f, 3.0f, 1.0f);
|
||||
const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
|
||||
EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 4.3f, 2.7f)), 0.0f, 1e-3f);
|
||||
EXPECT_NEAR(obb.GetDistanceSq(Vector3(-0.7f, 3.5f, 2.0f)), 0.8266f, 1e-3f);
|
||||
EXPECT_NEAR(obb.GetDistanceSq(Vector3(2.4f, 0.5f, 1.5f)), 0.5532f, 1e-3f);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace JsonSerializationTests
|
||||
AZStd::shared_ptr<AZ::Transform> CreateFullySetInstance() override
|
||||
{
|
||||
return AZStd::make_shared<AZ::Transform>(
|
||||
AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), AZ::Vector3(9.0f));
|
||||
AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), 9.0f);
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForFullySetInstance() override
|
||||
@@ -95,7 +95,7 @@ namespace JsonSerializationTests
|
||||
AZ::Transform expectedTransform(
|
||||
AZ::Vector3(2.25f, 3.5f, 4.75f),
|
||||
AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f),
|
||||
AZ::Vector3(5.5f));
|
||||
5.5f);
|
||||
|
||||
rapidjson::Document json;
|
||||
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })");
|
||||
|
||||
@@ -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
|
||||
@@ -372,15 +372,15 @@ mac_remote_filesystem=0
|
||||
-- We need to know this before we establish VFS because different platform assets
|
||||
-- are stored in different root folders in the cache. These correspond to the names
|
||||
-- In the asset processor config file. This value also controls what config file is read
|
||||
-- when you read system_xxxx_xxxx.cfg (for example, system_windows_pc.cfg or system_android_es3.cfg)
|
||||
-- when you read system_xxxx_xxxx.cfg (for example, system_windows_pc.cfg or system_android_android.cfg)
|
||||
-- by default, pc assets (in the 'pc' folder) are used, with RC being fed 'pc' as the platform
|
||||
-- by default on console we use the default assets=pc for better iteration times
|
||||
-- we should turn on console specific assets only when in release and/or testing assets and/or loading performance
|
||||
-- that way most people will not need to have 3 different caches taking up disk space
|
||||
assets = pc
|
||||
android_assets = es3
|
||||
android_assets = android
|
||||
ios_assets = ios
|
||||
mac_assets = osx_gl
|
||||
mac_assets = mac
|
||||
|
||||
-- Add the IP address of your console to the white list that will connect to the asset processor here
|
||||
-- You can list addresses or CIDR's. CIDR's are helpful if you are using DHCP. A CIDR looks like an ip address with
|
||||
@@ -438,9 +438,9 @@ mac_wait_for_connect=0
|
||||
ConfigFileParams::SettingsKeyValuePair{"/ios_remote_filesystem", AZ::s64{0}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/mac_remote_filesystem", AZ::s64{0}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/assets", AZStd::string_view{"pc"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/android_assets", AZStd::string_view{"es3"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/android_assets", AZStd::string_view{"android"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/ios_assets", AZStd::string_view{"ios"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/mac_assets", AZStd::string_view{"osx_gl"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/mac_assets", AZStd::string_view{"mac"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/connect_to_remote", AZ::s64{0}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/windows_connect_to_remote", AZ::s64{1}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/android_connect_to_remote", AZ::s64{0}},
|
||||
@@ -478,20 +478,20 @@ test_asset_processor_tag = test_value
|
||||
[Platform pc]
|
||||
tags=tools,renderer,dx12,vulkan
|
||||
|
||||
[Platform es3]
|
||||
[Platform android]
|
||||
tags=android,mobile,renderer,vulkan ; With Comments at the end
|
||||
|
||||
[Platform ios]
|
||||
tags=mobile,renderer,metal
|
||||
|
||||
[Platform osx_gl]
|
||||
[Platform mac]
|
||||
tags=tools,renderer,metal)"
|
||||
, AZStd::fixed_vector<ConfigFileParams::SettingsKeyValuePair, 20>{
|
||||
ConfigFileParams::SettingsKeyValuePair{"/test_asset_processor_tag", AZStd::string_view{"test_value"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform pc/tags", AZStd::string_view{"tools,renderer,dx12,vulkan"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform es3/tags", AZStd::string_view{"android,mobile,renderer,vulkan"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform android/tags", AZStd::string_view{"android,mobile,renderer,vulkan"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform ios/tags", AZStd::string_view{"mobile,renderer,metal"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform osx_gl/tags", AZStd::string_view{"tools,renderer,metal"}},
|
||||
ConfigFileParams::SettingsKeyValuePair{"/Platform mac/tags", AZStd::string_view{"tools,renderer,metal"}},
|
||||
}}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -711,8 +711,8 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath projectUserPath;
|
||||
if (m_settingsRegistry->Get(projectUserPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath))
|
||||
if (AZ::IO::FixedMaxPath projectUserPath;
|
||||
m_settingsRegistry->Get(projectUserPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath))
|
||||
{
|
||||
fileIoBase->SetAlias("@user@", projectUserPath.c_str());
|
||||
AZ::IO::FixedMaxPath projectLogPath = projectUserPath / "log";
|
||||
@@ -721,6 +721,15 @@ namespace AzFramework
|
||||
|
||||
CreateUserCache(projectUserPath, *fileIoBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::IO::FixedMaxPath fallbackLogPath = GetEngineRoot();
|
||||
fallbackLogPath /= "user";
|
||||
fileIoBase->SetAlias("@user@", fallbackLogPath.c_str());
|
||||
fallbackLogPath /= "log";
|
||||
fileIoBase->SetAlias("@log@", fallbackLogPath.c_str());
|
||||
fileIoBase->CreatePath(fallbackLogPath.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,18 +1694,16 @@ 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
|
||||
{
|
||||
if (AZStd::wildcard_match(pWildcardIn, fileIterator.m_filename))
|
||||
{
|
||||
AZStd::string foundFilename{ fileIterator.m_filename };
|
||||
AZStd::to_lower(foundFilename.begin(), foundFilename.end());
|
||||
files.emplace_back(AZStd::move(foundFilename));
|
||||
}
|
||||
} while (fileIterator = FindNext(fileIterator));
|
||||
AZStd::string foundFilename{ fileIterator.m_filename };
|
||||
AZStd::to_lower(foundFilename.begin(), foundFilename.end());
|
||||
files.emplace_back(AZStd::move(foundFilename));
|
||||
}
|
||||
while (fileIterator = FindNext(fileIterator));
|
||||
|
||||
// Open files in alphabet order.
|
||||
AZStd::sort(files.begin(), files.end());
|
||||
@@ -2008,13 +2024,12 @@ namespace AZ::IO
|
||||
// if no bind root is specified, compute one:
|
||||
strBindRoot = !bindRoot.empty() ? bindRoot : szFullPath->ParentPath().Native();
|
||||
|
||||
// Check if archive file disk exist on disk or inside of pak.
|
||||
bool bFileExists = IsFileExist(szFullPath->Native());
|
||||
|
||||
if (!bFileExists && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY))
|
||||
// Check if archive file disk exist on disk.
|
||||
const bool pakOnDisk = FileIOBase::GetDirectInstance()->Exists(szFullPath->c_str());
|
||||
if (!pakOnDisk && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY))
|
||||
{
|
||||
// Archive file not found.
|
||||
AZ_TracePrintf("Archive", "Cannot open Archive file %s\n", szFullPath->c_str());
|
||||
AZ_TracePrintf("Archive", "Archive file %s does not exist\n", szFullPath->c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2492,8 +2507,6 @@ namespace AZ::IO
|
||||
|
||||
void Archive::FindCompressionInfo(bool& found, AZ::IO::CompressionInfo& info, const AZStd::string_view filename)
|
||||
{
|
||||
constexpr uint32_t s_compressionTag = static_cast<uint32_t>('Z') << 24 | static_cast<uint32_t>('C') << 16 | static_cast<uint32_t>('R') << 8 | static_cast<uint32_t>('Y');
|
||||
|
||||
if (!found)
|
||||
{
|
||||
auto correctedFilename = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(filename);
|
||||
@@ -2519,7 +2532,6 @@ namespace AZ::IO
|
||||
found = true;
|
||||
|
||||
info.m_archiveFilename.InitFromRelativePath(archive->GetFilePath());
|
||||
info.m_compressionTag.m_code = s_compressionTag;
|
||||
info.m_offset = pFileData->GetFileDataOffset();
|
||||
info.m_compressedSize = entry->desc.lSizeCompressed;
|
||||
info.m_uncompressedSize = entry->desc.lSizeUncompressed;
|
||||
@@ -2539,9 +2551,8 @@ namespace AZ::IO
|
||||
break;
|
||||
}
|
||||
|
||||
info.m_decompressor = [&s_compressionTag]([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool
|
||||
info.m_decompressor = []([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool
|
||||
{
|
||||
AZ_Assert(info.m_compressionTag.m_code == s_compressionTag, "Provided compression info isn't supported by this decompressor.");
|
||||
size_t nSizeUncompressed = uncompressedBufferSize;
|
||||
return ZipDir::ZipRawUncompress(uncompressed, &nSizeUncompressed, compressed, compressedSize) == 0;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace AZ::IO
|
||||
, tWrite{ writeTime }
|
||||
{
|
||||
}
|
||||
|
||||
ArchiveFileIterator::ArchiveFileIterator(FindData* findData, AZStd::string_view filename, const FileDesc& fileDesc)
|
||||
: m_findData{ findData }
|
||||
, m_filename{ filename }
|
||||
@@ -76,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
|
||||
@@ -86,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);
|
||||
@@ -108,36 +115,33 @@ namespace AZ::IO
|
||||
AZ::StringFunc::Path::GetFullPath(directory.c_str(), searchDirectory);
|
||||
AZ::StringFunc::Path::GetFullFileName(directory.c_str(), pattern);
|
||||
}
|
||||
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool
|
||||
{
|
||||
AZ::IO::FileDesc fileDesc;
|
||||
|
||||
AZStd::string fullFilePath;
|
||||
AZ::StringFunc::Path::GetFullFileName(filePath, fullFilePath);
|
||||
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(fullFilePath), fileDesc);
|
||||
AZ_Assert(result.second, "Failed to insert FindData entry for %s", fullFilePath.c_str());
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -167,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);
|
||||
@@ -180,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 });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -249,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
|
||||
@@ -265,20 +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();
|
||||
fileIterator.m_filename = pakFileIter->first;
|
||||
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
|
||||
|
||||
@@ -308,6 +308,56 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
GenerateRelativeSourcePathRequest::GenerateRelativeSourcePathRequest(const AZ::OSString& sourcePath)
|
||||
{
|
||||
AZ_Assert(!sourcePath.empty(), "GenerateRelativeSourcePathRequest: asset path is empty");
|
||||
m_sourcePath = sourcePath;
|
||||
}
|
||||
|
||||
unsigned int GenerateRelativeSourcePathRequest::GetMessageType() const
|
||||
{
|
||||
return MessageType;
|
||||
}
|
||||
|
||||
void GenerateRelativeSourcePathRequest::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<GenerateRelativeSourcePathRequest, BaseAssetProcessorMessage>()
|
||||
->Version(1)
|
||||
->Field("SourcePath", &GenerateRelativeSourcePathRequest::m_sourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
GenerateRelativeSourcePathResponse::GenerateRelativeSourcePathResponse(
|
||||
bool resolved, const AZ::OSString& relativeSourcePath, const AZ::OSString& rootFolder)
|
||||
{
|
||||
m_relativeSourcePath = relativeSourcePath;
|
||||
m_resolved = resolved;
|
||||
m_rootFolder = rootFolder;
|
||||
}
|
||||
|
||||
unsigned int GenerateRelativeSourcePathResponse::GetMessageType() const
|
||||
{
|
||||
return GenerateRelativeSourcePathRequest::MessageType;
|
||||
}
|
||||
|
||||
void GenerateRelativeSourcePathResponse::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<GenerateRelativeSourcePathResponse, BaseAssetProcessorMessage>()
|
||||
->Version(1)
|
||||
->Field("RelativeSourcePath", &GenerateRelativeSourcePathResponse::m_relativeSourcePath)
|
||||
->Field("RootFolder", &GenerateRelativeSourcePathResponse::m_rootFolder)
|
||||
->Field("Resolved", &GenerateRelativeSourcePathResponse::m_resolved);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
GetFullSourcePathFromRelativeProductPathRequest::GetFullSourcePathFromRelativeProductPathRequest(const AZ::OSString& relativeProductPath)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -288,6 +288,45 @@ namespace AzFramework
|
||||
bool m_resolved;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GenerateRelativeSourcePathRequest : public BaseAssetProcessorMessage
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(GenerateRelativeSourcePathRequest, AZ::OSAllocator, 0);
|
||||
AZ_RTTI(GenerateRelativeSourcePathRequest, "{B3865033-F5A3-4749-8147-7B1AB04D5F6D}",
|
||||
BaseAssetProcessorMessage);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
// For people that are debugging the network messages and just see MessageType as a value,
|
||||
// the CRC value below is 739777771 (0x2C181CEB)
|
||||
static constexpr unsigned int MessageType =
|
||||
AZ_CRC_CE("AssetSystem::GenerateRelativeSourcePathRequest");
|
||||
|
||||
GenerateRelativeSourcePathRequest() = default;
|
||||
GenerateRelativeSourcePathRequest(const AZ::OSString& sourcePath);
|
||||
unsigned int GetMessageType() const override;
|
||||
|
||||
AZ::OSString m_sourcePath;
|
||||
};
|
||||
|
||||
class GenerateRelativeSourcePathResponse : public BaseAssetProcessorMessage
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(GenerateRelativeSourcePathResponse, AZ::OSAllocator, 0);
|
||||
AZ_RTTI(GenerateRelativeSourcePathResponse, "{938D33DB-C8F6-4FA4-BC81-2F139A9BE1D7}",
|
||||
BaseAssetProcessorMessage);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
GenerateRelativeSourcePathResponse() = default;
|
||||
GenerateRelativeSourcePathResponse(
|
||||
bool resolved, const AZ::OSString& relativeSourcePath, const AZ::OSString& rootFolder);
|
||||
unsigned int GetMessageType() const override;
|
||||
|
||||
AZ::OSString m_relativeSourcePath;
|
||||
AZ::OSString m_rootFolder; ///< This is the folder it was found in (the watched/scanned folder, such as gems /assets/ folder)
|
||||
bool m_resolved;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class GetFullSourcePathFromRelativeProductPathRequest
|
||||
: public BaseAssetProcessorMessage
|
||||
|
||||
@@ -202,6 +202,7 @@ namespace AzFramework
|
||||
// Requests
|
||||
GetUnresolvedDependencyCountsRequest::Reflect(context);
|
||||
GetRelativeProductPathFromFullSourceOrProductPathRequest::Reflect(context);
|
||||
GenerateRelativeSourcePathRequest::Reflect(context);
|
||||
GetFullSourcePathFromRelativeProductPathRequest::Reflect(context);
|
||||
SourceAssetInfoRequest::Reflect(context);
|
||||
AssetInfoRequest::Reflect(context);
|
||||
@@ -234,6 +235,7 @@ namespace AzFramework
|
||||
// Responses
|
||||
GetUnresolvedDependencyCountsResponse::Reflect(context);
|
||||
GetRelativeProductPathFromFullSourceOrProductPathResponse::Reflect(context);
|
||||
GenerateRelativeSourcePathResponse::Reflect(context);
|
||||
GetFullSourcePathFromRelativeProductPathResponse::Reflect(context);
|
||||
SourceAssetInfoResponse::Reflect(context);
|
||||
AssetInfoResponse::Reflect(context);
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
* 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/Component/Component.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -64,15 +64,13 @@ namespace AzFramework
|
||||
the EditContext. TController can friend itself to the editor component to make this work if required.
|
||||
*/
|
||||
template<typename TController, typename TConfiguration = AZ::ComponentConfig>
|
||||
class ComponentAdapter
|
||||
: public AZ::Component
|
||||
class ComponentAdapter : public AZ::Component
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_RTTI((ComponentAdapter, "{644A9187-4FDB-42C1-9D59-DD75304B551A}", TController, TConfiguration), AZ::Component);
|
||||
|
||||
ComponentAdapter() = default;
|
||||
ComponentAdapter(const TConfiguration& configuration);
|
||||
explicit ComponentAdapter(const TConfiguration& configuration);
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
@@ -85,7 +83,6 @@ namespace AzFramework
|
||||
void Deactivate() override;
|
||||
|
||||
protected:
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
// AZ::Component overrides ...
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
* 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 <AzFramework/Components/ComponentAdapterHelpers.h>
|
||||
|
||||
@@ -32,10 +32,12 @@ namespace AzFramework
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
// clang-format off
|
||||
serializeContext->Class<ComponentAdapter, Component>()
|
||||
->Version(1)
|
||||
->Field("Controller", &ComponentAdapter::m_controller)
|
||||
;
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +68,6 @@ namespace AzFramework
|
||||
GetDependentServicesHelper<TController>(services, typename AZ::HasComponentDependentServices<TController>::type());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component interface implementation
|
||||
|
||||
template<typename TController, typename TConfiguration>
|
||||
void ComponentAdapter<TController, TConfiguration>::Init()
|
||||
{
|
||||
@@ -78,7 +77,7 @@ namespace AzFramework
|
||||
template<typename TController, typename TConfiguration>
|
||||
void ComponentAdapter<TController, TConfiguration>::Activate()
|
||||
{
|
||||
m_controller.Activate(GetEntityId());
|
||||
ComponentActivateHelper<TController>::Activate(m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
}
|
||||
|
||||
template<typename TController, typename TConfiguration>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/EntityBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -27,18 +28,43 @@ namespace AzFramework
|
||||
template<typename T, typename = void>
|
||||
struct ComponentInitHelper
|
||||
{
|
||||
static void Init(T& common)
|
||||
static void Init([[maybe_unused]] T& controller)
|
||||
{
|
||||
AZ_UNUSED(common);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ComponentInitHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Init())>>
|
||||
{
|
||||
static void Init(T& common)
|
||||
static void Init(T& controller)
|
||||
{
|
||||
common.Init();
|
||||
controller.Init();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct ComponentActivateHelper
|
||||
{
|
||||
static void Activate([[maybe_unused]] T& controller, [[maybe_unused]] const AZ::EntityComponentIdPair& entityComponentIdPair)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ComponentActivateHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Activate(AZ::EntityId()))>>
|
||||
{
|
||||
static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair)
|
||||
{
|
||||
controller.Activate(entityComponentIdPair.GetEntityId());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ComponentActivateHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Activate(AZ::EntityComponentIdPair()))>>
|
||||
{
|
||||
static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair)
|
||||
{
|
||||
controller.Activate(entityComponentIdPair);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -327,99 +327,13 @@ namespace AzFramework
|
||||
return localZ;
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotation(const AZ::Vector3& eulerAnglesRadian)
|
||||
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetRotation is deprecated, please use SetLocalRotation");
|
||||
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::ConvertEulerRadiansToQuaternion(eulerAnglesRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetRotationQuaternion is deprecated, please use SetLocalRotationQuaternion");
|
||||
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(quaternion);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationX(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetRotationX is deprecated, please use SetLocalRotation");
|
||||
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationX(eulerAngleRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationY(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetRotationY is deprecated, please use SetLocalRotation");
|
||||
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationY(eulerAngleRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationZ(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetRotationZ is deprecated, please use SetLocalRotation");
|
||||
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationZ(eulerAngleRadian));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByX(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "RotateByX is deprecated, please use RotateAroundLocalX");
|
||||
RotateAroundLocalX(eulerAngleRadian);
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByY(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "RotateByY is deprecated, please use RotateAroundLocalY");
|
||||
RotateAroundLocalY(eulerAngleRadian);
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByZ(float eulerAngleRadian)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "RotateByZ is deprecated, please use RotateAroundLocalZ");
|
||||
RotateAroundLocalZ(eulerAngleRadian);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetRotationEulerRadians()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetRotationEulerRadians is deprecated, please use GetWorldRotation");
|
||||
return m_worldTM.GetRotation().GetEulerRadians();
|
||||
}
|
||||
|
||||
AZ::Quaternion TransformComponent::GetRotationQuaternion()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetRotationQuaternion is deprecated, please use GetWorldRotationQuaternion");
|
||||
return m_worldTM.GetRotation();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationX()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetRotationX is deprecated, please use GetWorldRotation");
|
||||
return GetRotationEulerRadians().GetX();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationY()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetRotationY is deprecated, please use GetWorldRotation");
|
||||
return GetRotationEulerRadians().GetY();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationZ()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetRotationZ is deprecated, please use GetWorldRotation");
|
||||
return GetRotationEulerRadians().GetZ();
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetWorldRotation()
|
||||
{
|
||||
return m_worldTM.GetRotation().GetEulerRadians();
|
||||
@@ -492,21 +406,10 @@ namespace AzFramework
|
||||
return m_localTM.GetRotation();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetScale(scale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetLocalScale()
|
||||
{
|
||||
return m_localTM.GetScale();
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetWorldScale()
|
||||
{
|
||||
return m_worldTM.GetScale();
|
||||
AZ_WarningOnce("TransformComponent", false, "GetLocalScale is deprecated, please use GetLocalUniformScale instead");
|
||||
return AZ::Vector3(m_localTM.GetUniformScale());
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalUniformScale(float scale)
|
||||
@@ -830,45 +733,7 @@ namespace AzFramework
|
||||
->Event("GetLocalX", &AZ::TransformBus::Events::GetLocalX)
|
||||
->Event("GetLocalY", &AZ::TransformBus::Events::GetLocalY)
|
||||
->Event("GetLocalZ", &AZ::TransformBus::Events::GetLocalZ)
|
||||
->Event("RotateByX", &AZ::TransformBus::Events::RotateByX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("RotateByY", &AZ::TransformBus::Events::RotateByY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("RotateByZ", &AZ::TransformBus::Events::RotateByZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetEulerRotation", &AZ::TransformBus::Events::SetRotation)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetRotationQuaternion", &AZ::TransformBus::Events::SetRotationQuaternion)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetRotationX", &AZ::TransformBus::Events::SetRotationX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetRotationY", &AZ::TransformBus::Events::SetRotationY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetRotationZ", &AZ::TransformBus::Events::SetRotationZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetEulerRotation", &AZ::TransformBus::Events::GetRotationEulerRadians)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetRotationQuaternion", &AZ::TransformBus::Events::GetRotationQuaternion)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetRotationX", &AZ::TransformBus::Events::GetRotationX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetRotationY", &AZ::TransformBus::Events::GetRotationY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetRotationZ", &AZ::TransformBus::Events::GetRotationZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetWorldRotationQuaternion", &AZ::TransformBus::Events::SetWorldRotationQuaternion)
|
||||
->Event("GetWorldRotation", &AZ::TransformBus::Events::GetWorldRotation)
|
||||
->Event("GetWorldRotationQuaternion", &AZ::TransformBus::Events::GetWorldRotationQuaternion)
|
||||
->Event("SetLocalRotation", &AZ::TransformBus::Events::SetLocalRotation)
|
||||
@@ -880,11 +745,11 @@ namespace AzFramework
|
||||
->Event("GetLocalRotationQuaternion", &AZ::TransformBus::Events::GetLocalRotationQuaternion)
|
||||
->Attribute("Rotation", AZ::Edit::Attributes::PropertyRotation)
|
||||
->VirtualProperty("Rotation", "GetLocalRotationQuaternion", "SetLocalRotationQuaternion")
|
||||
->Event("SetLocalScale", &AZ::TransformBus::Events::SetLocalScale)
|
||||
->Event("GetLocalScale", &AZ::TransformBus::Events::GetLocalScale)
|
||||
->Attribute("Scale", AZ::Edit::Attributes::PropertyScale)
|
||||
->VirtualProperty("Scale", "GetLocalScale", "SetLocalScale")
|
||||
->Event("GetWorldScale", &AZ::TransformBus::Events::GetWorldScale)
|
||||
->Event("SetLocalUniformScale", &AZ::TransformBus::Events::SetLocalUniformScale)
|
||||
->Event("GetLocalUniformScale", &AZ::TransformBus::Events::GetLocalUniformScale)
|
||||
->VirtualProperty("Uniform Scale", "GetLocalUniformScale", "SetLocalUniformScale")
|
||||
->Event("GetChildren", &AZ::TransformBus::Events::GetChildren)
|
||||
->Event("GetAllDescendants", &AZ::TransformBus::Events::GetAllDescendants)
|
||||
->Event("GetEntityAndAllDescendants", &AZ::TransformBus::Events::GetEntityAndAllDescendants)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user