Merge branch 'main' into cgalvan/EntityHelperRefactor

This commit is contained in:
Chris Galvan
2021-04-19 13:18:27 -05:00
1385 changed files with 16306 additions and 25761 deletions
+3 -1
View File
@@ -1675,9 +1675,11 @@ bool C3DEngine::IsTessellationAllowedForShadowMap(const SRenderingPassInfo& pass
default:
return false;
}
#endif //#ifdef MESH_TESSELLATION_ENGINE
#else
return false;
#endif //#ifdef MESH_TESSELLATION_ENGINE
}
void C3DEngine::SetPhysMaterialEnumerator(IPhysMaterialEnumerator* pPhysMaterialEnumerator)
@@ -127,10 +127,6 @@ bool CZBufferCuller::IsBoxVisible(const AABB& objBox, [[maybe_unused]] uint32* c
return Rasterize<2>(Verts, 8);
}
return Rasterize<0>(Verts, 8);
++m_ObjectsTestedAndRejected;
return false;
}
static int sh = 8;
@@ -197,4 +193,4 @@ void CZBufferCuller::GetMemoryUsage(ICrySizer* pSizer) const
{
SIZER_COMPONENT_NAME(pSizer, "CoverageBuffer");
pSizer->AddObject(m_ZBuffer, sizeof(TZBZexel) * m_SizeX * m_SizeY);
}
}
+16 -4
View File
@@ -97,7 +97,10 @@ protected:
{
return true;
}
MinX = 0;
else
{
MinX = 0;
}
}
if (MaxX > m_SizeX)
{
@@ -105,7 +108,10 @@ protected:
{
return true;
}
MaxX = m_SizeX;
else
{
MaxX = m_SizeX;
}
}
if (MinY < 0)
{
@@ -113,7 +119,10 @@ protected:
{
return true;
}
MinY = 0;
else
{
MinY = 0;
}
}
if (MaxY > m_SizeY)
{
@@ -121,7 +130,10 @@ protected:
{
return true;
}
MaxY = m_SizeY;
else
{
MaxY = m_SizeY;
}
}
if constexpr (ROTATE == 2)
{
@@ -844,7 +844,6 @@ void MaterialHelpers::MigrateXmlLegacyData(SInputShaderResources& pShaderResourc
CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Material %s has had legacy GlowAmount automatically converted to Emissive Intensity. The material parameters related to Emittance should be manually adjusted for this material.", materialName.c_str());
}
// In Lumberyard version 1.9 BlendLayer2Specular became a color instead of a single float, so it needs to be updated
XmlNodeRef publicParamsNode = node->findChild("PublicParams");
if (publicParamsNode && publicParamsNode->haveAttr("BlendLayer2Specular"))
{
+1 -1
View File
@@ -214,7 +214,7 @@ CTimeOfDay::CTimeOfDay()
// fill local var list so, sandbox can access var list without level being loaded
// Cryengine supports the notion of environment presets which are set in code that is currently not
// in lumberyard. Therefore, create a default preset here that is used as the only one.
// in Open 3D Engine. Therefore, create a default preset here that is used as the only one.
m_defaultPreset = new CEnvironmentPreset;
for (int i = 0; i < PARAM_TOTAL; ++i)
{
+1 -1
View File
@@ -922,7 +922,7 @@ void CVars::Init()
"Will not render CGFs past the given amount of drawcalls\n"
"(<=0 off (default), >0 draw calls limit)");
REGISTER_CVAR(e_CheckOctreeObjectsBoxSize, 1, VF_NULL, "CryWarning for crazy sized COctreeNode m_objectsBoxes");
REGISTER_CVAR(e_CheckOctreeObjectsBoxSize, 1, VF_NULL, "Warning for crazy sized COctreeNode m_objectsBoxes");
REGISTER_CVAR(e_DebugGeomPrep, 0, VF_NULL, "enable logging of Geom preparation");
DefineConstIntCVar(e_GeomCaches, 1, VF_NULL, "Activates drawing of geometry caches");
REGISTER_CVAR(e_GeomCacheBufferSize, 128, VF_CHEAT, "Geometry cache stream buffer upper limit size in MB. Default: 128");
+1 -1
View File
@@ -323,7 +323,7 @@ void CryAssertTrace(const char* _pszFormat, ...)
//-----------------------------------------------------------------------------------------------------
static const char* gs_strRegSubKey = "Software\\Amazon\\Lumberyard\\AssertWindow";
static const char* gs_strRegSubKey = "Software\\O3DE\\AssertWindow";
static const char* gs_strRegXValue = "AssertInfoX";
static const char* gs_strRegYValue = "AssertInfoY";
@@ -26,7 +26,7 @@
#define REG_SOFTWARE L"Software\\"
#define REG_COMPANY_NAME L"Amazon\\"
#define REG_PRODUCT_NAME L"Lumberyard\\"
#define REG_PRODUCT_NAME L"Open 3D Engine\\"
#define REG_SETTING L"Settings\\"
#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING
@@ -181,7 +181,7 @@ bool CEngineSettingsBackendWin32::SetModuleSpecificBoolEntry(const char* key, co
bool CEngineSettingsBackendWin32::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path)
{
RegKey key(REG_BASE_SETTING_KEY L"LumberyardExport\\ProjectBuilds", false);
RegKey key(REG_BASE_SETTING_KEY L"O3DEExport\\ProjectBuilds", false);
if (key.pKey)
{
DWORD type;
+1 -1
View File
@@ -61,7 +61,7 @@ namespace AZ
///
/// Attempt to initialize this device. If initialization is initially successful (device exists and is able to startup) then this device should connect to the
/// HMDDeviceRequestBus in order to be used as an HMD from the main Lumberyard system.
/// HMDDeviceRequestBus in order to be used as an HMD from the main Open 3D Engine system.
///
/// @return If true, initialization fully succeeded.
///
+12 -2
View File
@@ -19,6 +19,7 @@
#include <AzCore/Component/EntityId.h>
#include <AzCore/Math/Crc.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Range.h>
#include <AnimKey.h>
@@ -914,9 +915,18 @@ struct IAnimStringTable
*/
struct IAnimSequence
{
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}")
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}");
AZ_CLASS_ALLOCATOR(IAnimSequence, AZ::SystemAllocator, 0);
static const int kSequenceVersion = 4;
static const int kSequenceVersion = 5;
static void Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
{
serializeContext->Class<IAnimSequence>();
}
}
//! Flags used for SetFlags(),GetFlags(),SetParentFlags(),GetParentFlags() methods.
enum EAnimSequenceFlags
+1 -1
View File
@@ -1470,7 +1470,7 @@ struct ISystem
virtual int GetApplicationInstance() = 0;
// Summary:
// Get log index of the currently running lumberyard application. (0 = first instance, 1 = second instance, etc)
// Get log index of the currently running Open 3D Engine application. (0 = first instance, 1 = second instance, etc)
virtual int GetApplicationLogInstance(const char* logFilePath) = 0;
// Summary:
+4 -1
View File
@@ -111,7 +111,10 @@ int32 CFFont::Release()
m_pCryFont = nullptr;
}
gEnv->pRenderer->DeleteFont(this);
if (gEnv->pRenderer)
{
gEnv->pRenderer->DeleteFont(this);
}
return 0;
}
return nRef;
@@ -35,7 +35,7 @@ namespace AZ
}
AZ::OSString msgBoxMessage;
msgBoxMessage.append("CrySystem could not initialize correctly for the following reason(s):");
msgBoxMessage.append("O3DE could not initialize correctly for the following reason(s):");
for (const AZ::OSString& errMsg : m_errorStringsCollected)
{
@@ -47,7 +47,7 @@ namespace AZ
Trace::Output(nullptr, msgBoxMessage.c_str());
Trace::Output(nullptr, "\n==================================================================\n");
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "CrySystem Initialization Failed", msgBoxMessage.c_str(), false);
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "O3DE Initialization Failed", msgBoxMessage.c_str(), false);
}
} // namespace Debug
} // namespace AZ
+1 -1
View File
@@ -85,7 +85,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Save",IDB_CONFIRM_SAVE,4,96,68,20
PUSHBUTTON "Cancel",IDB_DONT_SAVE,206,96,68,20
LTEXT "Lumberyard has encountered an error and needs to close.\n\nA backup has been saved to the '_savebackup' subfolder.\n\nIf you are unable to save your file, you can recover by copying the contents of the _savebackup folder over the broken files.",IDC_STATIC,60,8,210,61
LTEXT "Open 3D Engine has encountered an error and needs to close.\n\nA backup has been saved to the '_savebackup' subfolder.\n\nIf you are unable to save your file, you can recover by copying the contents of the _savebackup folder over the broken files.",IDC_STATIC,60,8,210,61
LTEXT "Attempt save?",IDC_STATIC,60,72,180,21
CONTROL 128,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,8,8,48,40
END
+16
View File
@@ -4871,7 +4871,9 @@ static void* tmalloc_small(mstate m, size_t nb)
}
CORRUPTION_ERROR_ACTION(m);
#if PROCEED_ON_ERROR
return 0;
#endif
}
/* --------------------------- realloc support --------------------------- */
@@ -4930,7 +4932,9 @@ static void* internal_realloc(mstate m, void* oldmem, size_t bytes)
{
USAGE_ERROR_ACTION(m, oldmem);
POSTACTION(m);
#if PROCEED_ON_ERROR
return 0;
#endif
}
#if DEBUG
if (newp != 0)
@@ -5884,7 +5888,9 @@ void* mspace_malloc(mspace msp, size_t bytes)
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
if (!PREACTION(ms))
{
@@ -6150,7 +6156,9 @@ void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size)
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
if (n_elements != 0)
{
@@ -6193,7 +6201,9 @@ void* mspace_realloc(mspace msp, void* oldmem, size_t bytes)
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
return internal_realloc(ms, oldmem, bytes);
}
@@ -6205,7 +6215,9 @@ void* mspace_memalign(mspace msp, size_t alignment, size_t bytes)
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
return internal_memalign(ms, alignment, bytes);
}
@@ -6218,7 +6230,9 @@ void** mspace_independent_calloc(mspace msp, size_t n_elements,
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
return ialloc(ms, n_elements, &sz, 3, chunks);
}
@@ -6230,7 +6244,9 @@ void** mspace_independent_comalloc(mspace msp, size_t n_elements,
if (!ok_magic(ms))
{
USAGE_ERROR_ACTION(ms, ms);
#if PROCEED_ON_ERROR
return 0;
#endif
}
return ialloc(ms, n_elements, sizes, 0, chunks);
}
+1 -1
View File
@@ -226,7 +226,7 @@ void IDebugCallStack::FatalError(const char* description)
bShowDebugScreen = bShowDebugScreen && gEnv->mMainThreadId == CryGetCurrentThreadId();
if (bShowDebugScreen)
{
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Lumberyard Fatal Error", description, false);
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Open 3D Engine Fatal Error", description, false);
}
#endif
+14 -6
View File
@@ -98,14 +98,18 @@ bool CCryMemoryManager::GetProcessMemInfo(SProcessMemInfo& minfo)
}
return false;
#else
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION MEMORYMANAGER_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(MemoryManager_cpp)
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION MEMORYMANAGER_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(MemoryManager_cpp)
#endif
bool retVal = true;
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(LINUX)
MEMORYSTATUS MemoryStatus;
@@ -143,11 +147,15 @@ bool CCryMemoryManager::GetProcessMemInfo(SProcessMemInfo& minfo)
return false;
}
minfo.WorkingSetSize = kTaskInfo.resident_size;
#else
return false;
retVal = false;
#endif
return true;
return retVal;
#endif
}
//////////////////////////////////////////////////////////////////////////
+1 -11
View File
@@ -1451,20 +1451,12 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
//bool bPause = false;
bool bNoUpdate = false;
#ifndef EXCLUDE_UPDATE_ON_CONSOLE
//check what is the current process
IProcess* pProcess = GetIProcess();
if (!pProcess)
{
return (true); //should never happen
}
if (m_sysNoUpdate && m_sysNoUpdate->GetIVal())
{
bNoUpdate = true;
updateFlags = ESYSUPDATE_IGNORE_PHYSICS;
}
//if ((pProcess->GetFlags() & PROC_MENU) || (m_sysNoUpdate && m_sysNoUpdate->GetIVal()))
// bPause = true;
m_bNoUpdate = bNoUpdate;
#endif //EXCLUDE_UPDATE_ON_CONSOLE
@@ -1537,7 +1529,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
}
//////////////////////////////////////////////////////////////////////////
if (m_env.pRenderer->GetIStereoRenderer()->IsRenderingToHMD())
if (m_env.pRenderer && m_env.pRenderer->GetIStereoRenderer()->IsRenderingToHMD())
{
EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, UpdateInternalState);
}
@@ -2860,8 +2852,6 @@ bool CSystem::HandleMessage([[maybe_unused]] HWND hWnd, UINT uMsg, WPARAM wParam
default:
return false;
}
return true;
}
#endif
+5 -5
View File
@@ -248,7 +248,7 @@ CUNIXConsole* pUnixConsole;
#define LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME "Libs/Localization/localization.xml"
#define LOAD_LEGACY_RENDERER_FOR_EDITOR true // If you set this to false you must for now also set 'ed_useAtomNativeViewport' to true (see /Code/Sandbox/Editor/ViewManager.cpp)
#define LOAD_LEGACY_RENDERER_FOR_LAUNCHER true
#define LOAD_LEGACY_RENDERER_FOR_LAUNCHER false
//////////////////////////////////////////////////////////////////////////
// Where possible, these are defaults used to initialize cvars
@@ -1256,7 +1256,7 @@ bool CSystem::OpenRenderLibrary(int type, const SSystemInitParams& initParams)
if (allowPrompts)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue...");
const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedGPU(gpuName, gpuVendorId, gpuDeviceId).c_str(), L"Lumberyard", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY);
const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedGPU(gpuName, gpuVendorId, gpuDeviceId).c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY);
if (mbRes == IDCANCEL)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup due to unsupported GPU.");
@@ -2093,7 +2093,7 @@ static bool CheckCPURequirements([[maybe_unused]] CCpuFeatures* pCpu, [[maybe_un
if (allowPrompts)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue...");
const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedCPU().c_str(), L"Lumberyard", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY);
const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedCPU().c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY);
if (mbRes == IDCANCEL)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup.");
@@ -2305,7 +2305,7 @@ AZ_POP_DISABLE_WARNING
if (!bIsWindowsXPorLater)
{
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Lumberyard requires an OS version of Windows XP or later.");
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Open 3D Engine requires an OS version of Windows XP or later.");
return false;
}
}
@@ -2420,7 +2420,7 @@ AZ_POP_DISABLE_WARNING
azstrcpy(
headerString,
AZ_ARRAY_SIZE(headerString),
"Lumberyard - "
"Open 3D Engine - "
#if defined(LINUX)
"Linux "
#elif defined(MAC)
+1 -1
View File
@@ -626,7 +626,7 @@ void CSystem::RenderStats()
float nTextPosX = 101 - 20, nTextPosY = -2, nTextStepY = 3;
m_env.p3DEngine->DisplayInfo(nTextPosX, nTextPosY, nTextStepY, iDisplayInfo != 1);
// Dump Lumberyard CPU and GPU memory statistics to screen
// Dump Open 3D Engine CPU and GPU memory statistics to screen
m_env.p3DEngine->DisplayMemoryStatistics();
#if defined(ENABLE_LW_PROFILERS)
+4 -4
View File
@@ -605,7 +605,7 @@ void CSystem::DebugStats([[maybe_unused]] bool checkpoint, [[maybe_unused]] bool
{
if (!dbgmodules[i].handle)
{
CryLogAlways("WARNING: <CrySystem> CSystem::DebugStats: NULL handle for %s", dbgmodules[i].name.c_str());
CryLogAlways("WARNING: CSystem::DebugStats: NULL handle for %s", dbgmodules[i].name.c_str());
nolib++;
continue;
}
@@ -642,7 +642,7 @@ void CSystem::DebugStats([[maybe_unused]] bool checkpoint, [[maybe_unused]] bool
}
else
{
CryLogAlways("WARNING: <CrySystem> CSystem::DebugStats: could not retrieve function from DLL %s", dbgmodules[i].name.c_str());
CryLogAlways("WARNING: CSystem::DebugStats: could not retrieve function from DLL %s", dbgmodules[i].name.c_str());
nolib++;
};
#endif
@@ -1066,7 +1066,7 @@ void CSystem::FatalError(const char* format, ...)
if (szSysErrorMessage)
{
CryLogAlways("<CrySystem> Last System Error: %s", szSysErrorMessage);
CryLogAlways("Last System Error: %s", szSysErrorMessage);
}
if (GetUserCallback())
@@ -1091,7 +1091,7 @@ void CSystem::FatalError(const char* format, ...)
{
::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE);
}
::MessageBox(NULL, szBuffer, "Lumberyard Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
::MessageBox(NULL, szBuffer, "Open 3D Engine Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
}
// Dump callstack.
+1 -23
View File
@@ -193,34 +193,12 @@ bool IsOptionalReadXML(const SParseParams& parseParams, XmlNodeRef& definition)
return optional;
}
bool CheckEnum([[maybe_unused]] const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data)
bool CheckEnum([[maybe_unused]] const SParseParams& parseParams, [[maybe_unused]] const char* name, XmlNodeRef& definition, [[maybe_unused]] XmlNodeRef& data)
{
if (XmlNodeRef enumNode = definition->findChild("Enum"))
{
// If strict mode is off, then no need to check the enum value
return true;
// if restrictive attribute set to false, check always succeeds
if (enumNode->haveAttr("restrictive"))
{
bool res = true;
enumNode->getAttr("restrictive", res);
if (!res)
{
return true;
}
}
// else check enum values
const char* val = data->getAttr(name);
for (int i = 0; i < enumNode->getChildCount(); ++i)
{
if (0 == strcmp(enumNode->getChild(i)->getContent(), val))
{
return true;
}
}
return false;
}
return true;
}
@@ -274,6 +274,10 @@ void PerInstanceConstantBufferPool::SetConstantBuffer(SRendItem* renderItem)
deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex);
deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex);
#else
AZ::u32 itemIndex = directId % SPI_NUM_INSTS_PER_CB;
AZ::u32 first[1] = {itemIndex * static_cast<AZ::u32>(sizeof(HLSL_PerInstanceConstantBuffer))};
AZ::u32 count[1] = {static_cast<AZ::u32>(sizeof(HLSL_PerInstanceConstantBuffer))};
deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]);
deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]);
#endif
@@ -755,6 +755,7 @@ lSysUpdate:
buffer_handle_t nVB = ~0u;
# if BUFFER_ENABLE_DIRECT_ACCESS && !defined(NULL_RENDERER)
nVB = MS->m_nID;
int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID;
if ((nVB != ~0u && (MS->m_nFrameCreate != nFrame || MS->m_nElements != m_nVerts)) || !CRenderer::CV_r_buffer_enable_lockless_updates)
# endif
goto lSysCreate;
@@ -711,6 +711,7 @@ bool SRenderThread::RC_CreateDeviceTexture(CTexture* pTex, const byte* pData[6])
return pTex->RT_CreateDeviceTexture(pData);
}
#if !defined(MULTITHREADED_RESOURCE_CREATION)
if (pTex->IsAsyncDevTexCreation())
{
return !IsFailed();
@@ -727,6 +728,7 @@ bool SRenderThread::RC_CreateDeviceTexture(CTexture* pTex, const byte* pData[6])
FlushAndWait();
return !IsFailed();
#endif
}
void SRenderThread::RC_CopyDataToTexture(
@@ -229,7 +229,7 @@ namespace detail
#if defined(OPENGL) && (defined(DEBUG) || defined(_DEBUG))
#define LY_ENABLE_OPENGL_ERROR_CHECKING
#endif
namespace Lumberyard
namespace O3de
{
namespace OpenGL
{
@@ -776,9 +776,6 @@ static bool sIterateDL(DWORD& dwDL)
else
{
return false;
nLights = 2;
nType[0] = SLMF_DIRECT;
nType[1] = SLMF_POINT;
}
break;
case 2:
@@ -771,7 +771,6 @@ const char* CShaderMan::mfTemplateTexIdToName(int Id)
default:
return "Unknown";
}
return "Unknown";
}
CTexAnim* CShaderMan::mfReadTexSequence(const char* na, int Flags, [[maybe_unused]] bool bFindOnly)
@@ -47,7 +47,7 @@ BEGIN
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "FileDescription", "CryRenderD3D11"
VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates."
VALUE "ProductName", "Lumberyard"
VALUE "ProductName", "Open 3D Engine"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
@@ -47,7 +47,7 @@ BEGIN
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "FileDescription", "CryRenderGL"
VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates."
VALUE "ProductName", "Lumberyard"
VALUE "ProductName", "Open 3D Engine"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
@@ -2909,7 +2909,6 @@ byte CD3D9Renderer::FX_StartQuery(SRendItem* pRI)
return 0;
}
#endif
return 0;
}
void CD3D9Renderer::FX_EndQuery(SRendItem* pRI, byte bStartQ)
@@ -3641,7 +3641,7 @@ case _D3DValue: \
glDrawElements(m_ePrimitiveTopologyMode, uIndexCount, m_eIndexType, pvOffset);
#endif
Lumberyard::OpenGL::CheckError();
O3de::OpenGL::CheckError();
END_TRACE();
}
@@ -3662,7 +3662,7 @@ case _D3DValue: \
CRY_ASSERT(m_ePrimitiveTopologyMode != GL_NONE);
glDrawArrays(m_ePrimitiveTopologyMode, uStartVertexLocation, uVertexCount);
Lumberyard::OpenGL::CheckError();
O3de::OpenGL::CheckError();
END_TRACE();
}
@@ -2422,7 +2422,7 @@ namespace NCryOpenGL
return false;
}
Lumberyard::OpenGL::ClearErrors();
O3de::OpenGL::ClearErrors();
GLint major = 0, minor = 0;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
@@ -2431,7 +2431,7 @@ namespace NCryOpenGL
pAdapter->m_sVersion.m_uMajorVersion = static_cast<uint32>(major);
pAdapter->m_sVersion.m_uMinorVersion = static_cast<uint32>(minor);
return Lumberyard::OpenGL::CheckError() == GL_NO_ERROR;
return O3de::OpenGL::CheckError() == GL_NO_ERROR;
}
bool ParseExtensions(SAdapterPtr& pAdapter)
@@ -2443,7 +2443,7 @@ namespace NCryOpenGL
int num = 0, index;
bool result = true;
Lumberyard::OpenGL::ClearErrors();
O3de::OpenGL::ClearErrors();
glGetIntegerv(GL_NUM_EXTENSIONS, &num);
for (index = 0; index < num; ++index)
{
@@ -2458,7 +2458,7 @@ namespace NCryOpenGL
pAdapter->AddExtension(extension);
}
return result && Lumberyard::OpenGL::CheckError() == GL_NO_ERROR;
return result && O3de::OpenGL::CheckError() == GL_NO_ERROR;
}
bool DetectAdapters(std::vector<SAdapterPtr>& kAdapters)
@@ -2971,7 +2971,7 @@ namespace NCryOpenGL
#endif //DXGL_CHECK_ERRORS
} // namespace NCryOpenGL
namespace Lumberyard
namespace O3de
{
namespace OpenGL
{
@@ -2994,4 +2994,4 @@ namespace Lumberyard
}
#endif
} // namespace OpenGL
} // namespace Lumberyard
} // namespace O3de
@@ -4914,7 +4914,6 @@ bool CD3D9Renderer::ScreenShotInternal([[maybe_unused]] const char* filename, [[
// ignore invalid file access for screenshots
CDebugAllowFileAccess ignoreInvalidFileAccess;
bool bRet = true;
#if !defined(_RELEASE) || defined(WIN32) || defined(WIN64) || defined(ENABLE_LW_PROFILERS)
if (m_pRT && !m_pRT->IsRenderThread())
{
@@ -5041,8 +5040,11 @@ bool CD3D9Renderer::ScreenShotInternal([[maybe_unused]] const char* filename, [[
return CaptureFrameBufferToFile(path);
#else
return true;
#endif//_RELEASE
return bRet;
}
bool CD3D9Renderer::ScreenShot(const char* filename, int iPreWidth)
@@ -5656,8 +5658,6 @@ bool CD3D9Renderer::CaptureFrameBufferFast([[maybe_unused]] unsigned char* pDstR
}
SAFE_RELEASE(pSourceTexture);
return bStatus;
#endif
return bStatus;
@@ -5710,8 +5710,6 @@ bool CD3D9Renderer::CopyFrameBufferFast([[maybe_unused]] unsigned char* pDstRGBA
GetDeviceContext().Unmap(pCopyTexture, 0);
bStatus = true;
}
return bStatus;
#endif
return bStatus;
@@ -105,8 +105,9 @@ bool CD3DProfilingGPUTimer::Init()
{
#ifdef ENABLE_PROFILING_GPU_TIMERS
return CD3DGPUTimer::Init();
#endif
#else
return false;
#endif
}
CD3DGPUTimer::CD3DGPUTimer()
@@ -264,4 +265,4 @@ bool CD3DGPUTimer::Init()
#endif
return m_bInitialized;
}
}
@@ -90,7 +90,7 @@ bool MultiLayerAlphaBlendPass::IsSupported()
}
#else
m_supported = SupportLevel::NOT_SUPPORTED;
AZ_Warning("Rendering", false, "Multi-Layer Alpha Blending requires Lumberyard to have been built with the Windows 10 SDK or higher.");
AZ_Warning("Rendering", false, "Multi-Layer Alpha Blending requires Open 3D Engine to have been built with the Windows 10 SDK or higher.");
#endif
}
@@ -84,7 +84,7 @@ BEGIN
VALUE "CompanyName", "Amazon.com, Inc."
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates."
VALUE "ProductName", "Lumberyard"
VALUE "ProductName", "Open 3D Engine"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
@@ -111,7 +111,7 @@ namespace AZ
bool loadFileToMemory = Get().ShouldLoadFileToMemory(filename);
int assetMode = loadFileToMemory ? AASSET_MODE_BUFFER : AASSET_MODE_UNKNOWN;
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename), assetMode);
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename).c_str(), assetMode);
if (asset != nullptr)
{
@@ -192,7 +192,7 @@ namespace AZ
{
buf->m_offset = buf->m_totalSize - offset;
}
if (buf->m_offset > buf->m_totalSize)
{
buf->m_offset = buf->m_totalSize;
@@ -320,12 +320,19 @@ namespace AZ
bool APKFileHandler::DirectoryOrFileExists(const char* path)
{
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileexists");
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileExists");
AZ::IO::PathView insideApkPathView(Utils::StripApkPrefix(path));
AZ::IO::FixedMaxPath insideApkPath(Utils::StripApkPrefix(path));
AZ::IO::FixedMaxPathString filename{ insideApkPathView.Filename().Native() };
AZ::IO::FixedMaxPathString pathToFile{ insideApkPathView.ParentPath().Native() };
// Check for the case where the input path is equal to the APK Assets Prefix of /APK
// In that case the directory is the "root" of APK assets in which case the directory exist
if (insideApkPath.empty() && Utils::IsApkPath(path))
{
return true;
}
AZ::IO::FixedMaxPathString filename{ insideApkPath.Filename().Native() };
AZ::IO::FixedMaxPathString pathToFile{ insideApkPath.ParentPath().Native() };
bool foundFile = false;
ParseDirectory(pathToFile.c_str(), [&](const char* name)
+9 -14
View File
@@ -17,7 +17,7 @@
#include <AzCore/Debug/Trace.h>
#include <AzCore/Memory/OSAllocator.h>
#include <AzCore/IO/Path/Path.h>
namespace AZ
{
@@ -28,9 +28,9 @@ namespace AZ
namespace
{
////////////////////////////////////////////////////////////////
const char* GetApkAssetsPrefix()
constexpr const char* GetApkAssetsPrefix()
{
return "/APK/";
return "/APK";
}
}
@@ -104,19 +104,14 @@ namespace AZ
////////////////////////////////////////////////////////////////
bool IsApkPath(const char* filePath)
{
return (strncmp(filePath, GetApkAssetsPrefix(), 4) == 0); // +3 for "APK", +1 for '/' starting slash
return AZ::IO::PathView(filePath).IsRelativeTo(AZ::IO::PathView(GetApkAssetsPrefix()));
}
////////////////////////////////////////////////////////////////
const char* StripApkPrefix(const char* filePath)
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath)
{
const int prefixLength = 5; // +3 for "APK", +2 for '/' on either end
if (!IsApkPath(filePath))
{
return filePath;
}
return filePath + prefixLength;
constexpr AZ::IO::PathView apkPrefixView = GetApkAssetsPrefix();
return AZ::IO::PathView(filePath).LexicallyProximate(apkPrefixView);
}
////////////////////////////////////////////////////////////////
@@ -130,7 +125,7 @@ namespace AZ
// first check to see if they are in public storage (application specific)
const char* publicAppStorage = GetAppPublicStoragePath();
OSString path = OSString::format("%s/bootstrap.cfg", publicAppStorage);
OSString path = OSString::format("%s/engine.json", publicAppStorage);
AZ_TracePrintf("Android::Utils", "Searching for %s\n", path.c_str());
FILE* f = fopen(path.c_str(), "r");
@@ -145,7 +140,7 @@ namespace AZ
AAssetManager* mgr = GetAssetManager();
if (mgr)
{
AAsset* asset = AAssetManager_open(mgr, "bootstrap.cfg", AASSET_MODE_UNKNOWN);
AAsset* asset = AAssetManager_open(mgr, "engine.json", AASSET_MODE_UNKNOWN);
if (asset)
{
AAsset_close(asset);
+3 -2
View File
@@ -11,6 +11,7 @@
*/
#pragma once
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/std/string/string.h>
#include <jni.h>
@@ -55,7 +56,7 @@ namespace AZ
const char* GetObbStoragePath();
//! Get the dot separated package name for the current application.
//! e.g. com.lumberyard.samples for SamplesProject
//! e.g. com.o3de.samples for SamplesProject
const char* GetPackageName();
//! Get the app version code (android:versionCode in the manifest).
@@ -70,7 +71,7 @@ namespace AZ
//! Will first check to verify the argument is an apk asset path and if so
//! will strip the prefix from the path.
//! \return The pointer position of the relative asset path
const char* StripApkPrefix(const char* filePath);
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath);
//! Searches application storage and the APK for bootstrap.cfg. Will return nullptr
//! if bootstrap.cfg is not found.
@@ -10,7 +10,7 @@
*
*/
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetJsonSerializer.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/StackedString.h>
@@ -107,7 +107,8 @@ namespace AZ
result = ContinueLoading(&id, azrtti_typeid<AssetId>(), it->value, context);
if (!id.m_guid.IsNull())
{
*instance = Asset<AssetData>(id, instance->GetType());
*instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad);
result.Combine(context.Report(result, "Successfully created Asset<T> with id."));
}
@@ -1117,7 +1117,7 @@ namespace AZ
return asset;
}
void AssetManager::UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset)
void AssetManager::UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
{
if(!m_debugAssetEvents)
{
@@ -358,7 +358,7 @@ namespace AZ
Asset<AssetData> GetAssetInternal(const AssetId& assetId, const AssetType& assetType, AssetLoadBehavior assetReferenceLoadBehavior, const AssetLoadParameters& loadParams = AssetLoadParameters{}, AssetInfo assetInfo = AssetInfo(), bool signalLoaded = false);
void UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset);
void UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset);
/**
* Gets a root asset and dependencies as individual async loads if necessary.
@@ -12,7 +12,7 @@
/** @file
* Header file for the Component base class.
* In Lumberyard's component entity system, each component defines a discrete
* In Open 3D Engine's component entity system, each component defines a discrete
* feature that can be attached to an entity.
*/
@@ -76,7 +76,7 @@ namespace AZ
* practice to access other components through EBuses instead of accessing them directly.
* For more information, see the
* <a href="http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-intro.html">Programmer's Guide to Entities and Components</a>
* in the Lumberyard Developer Guide.
* in the Open 3D Engine Developer Guide.
* @return A pointer to the entity. If the component is not attached to any entity,
* the return value is a null pointer.
*/
@@ -426,7 +426,7 @@ namespace AZ
/**
* Describes the properties of the component descriptor event bus.
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Lumberyard allows only one
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Open 3D Engine allows only one
* descriptor for each component type. When you call functions on the bus for a specific component
* type, you can safely pass only one result variable because aggregating or overwriting results
* is impossible.
@@ -27,7 +27,6 @@
#include <AzCore/Memory/OverrunDetectionAllocator.h>
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Memory/MallocSchema.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/ObjectStream.h>
@@ -174,78 +173,85 @@ namespace AZ
return true;
};
//! SettingsRegistry notifier handler which updates relevant registry settings based
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
struct UpdateProjectSettingsEventHandler
{
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
: m_registry{ registry }
, m_commandLine{ commandLine }
{
}
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
{
UpdateProjectSpecializationInRegistry(path);
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// #1 Update the project settings when the project path is set
const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
AZ::IO::FixedMaxPath newProjectPath;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectPathKey, path)
&& m_registry.Get(newProjectPath.Native(), projectPathKey) && newProjectPath != m_oldProjectPath)
{
UpdateProjectSettingsFromProjectPath(AZ::IO::PathView(newProjectPath));
}
// #2 Update the project specialization when the project name is set
const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
FixedValueString newProjectName;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectNameKey, path)
&& m_registry.Get(newProjectName, projectNameKey) && newProjectName != m_oldProjectName)
{
UpdateProjectSpecializationFromProjectName(newProjectName);
}
// #3 Update the ComponentApplication CommandLine instance when the command line settings are merged into the Settings Registry
if (path == AZ::SettingsRegistryMergeUtils::CommandLineValueChangedKey)
{
UpdateCommandLine();
}
}
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
//! and remove the current project name specialization if one exists.
void UpdateProjectSpecializationInRegistry(AZStd::string_view path)
void UpdateProjectSpecializationFromProjectName(AZStd::string_view newProjectName)
{
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
+ "/project_path";
if (path == projectPathKey)
{
AZ::SettingsRegistryInterface::FixedValueString newProjectPath;
if (m_registry.Get(newProjectPath, path) && !newProjectPath.empty())
{
// Make the path absolute by appending to app root, in case project path is relative.
// If the project path is already absolute it will remain the same.
// If we turn it from a relative path to an absolute path, write-back the absolute path to the registry.
AZ::IO::FixedMaxPath projectPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath;
if (projectPath.Compare(newProjectPath.c_str()))
{
m_registry.Set(path, projectPath.Native());
}
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// Add the project_name as a specialization for loading the build system dependency .setreg files
auto newProjectNameSpecialization = FixedValueString::format("%s/%.*s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
aznumeric_cast<int>(newProjectName.size()), newProjectName.data());
auto oldProjectNameSpecialization = FixedValueString::format("%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
m_oldProjectName.c_str());
m_registry.Remove(oldProjectNameSpecialization);
m_oldProjectName = newProjectName;
m_registry.Set(newProjectNameSpecialization, true);
}
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
AZ::IO::FixedMaxPath projectMetadataFile{ projectPath };
projectMetadataFile /= "project.json";
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
void UpdateProjectSettingsFromProjectPath(AZ::IO::PathView newProjectPath)
{
// Update old Project path before attempting to merge in new Settings Registry values in order to prevent recursive calls
m_oldProjectPath = newProjectPath;
// Get the 'project_name' value from what was in the 'project.json' file...
auto projectNameKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
+ "/project_name";
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
AZ::IO::FixedMaxPath projectMetadataFile{ AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath };
projectMetadataFile /= "project.json";
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString projectSpecialization;
if (m_registry.Get(projectSpecialization, projectNameKey))
{
auto specializationKey = AZ::SettingsRegistryInterface::FixedValueString::format(
"%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey, projectSpecialization.c_str());
if (m_currentSpecialization != specializationKey)
{
m_registry.Set(specializationKey, true);
if (!m_currentSpecialization.empty())
{
// Remove the previous Project Name from the specialization path if it was set.
m_registry.Remove(m_currentSpecialization);
}
m_currentSpecialization = specializationKey;
// Update all the runtime file paths based on the new "project_path" value.
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
// Update all the runtime file paths based on the new "project_path" value.
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
}
}
}
void UpdateCommandLine()
{
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
}
private:
AZ::SettingsRegistryInterface::FixedValueString m_currentSpecialization;
AZ::IO::FixedMaxPath m_oldProjectPath;
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
AZ::SettingsRegistryInterface& m_registry;
AZ::CommandLine& m_commandLine;
};
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
@@ -424,7 +430,13 @@ namespace AZ
// Add the Command Line arguments into the SettingsRegistry
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
// Merge Command Line arguments
// Add a notifier to update the project_settings when
// 1. The 'project_path' key changes
// 2. The project specialization when the 'project-name' key changes
// 3. The ComponentApplication command line when the command line is stored to the registry
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry, m_commandLine });
// Merge Command Line arguments
constexpr bool executeRegDumpCommands = false;
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
@@ -438,10 +450,6 @@ namespace AZ
// for the application root.
CalculateAppRoot();
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
// when the 'project_path' property changes within the SettingsRegistry
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
@@ -918,6 +926,8 @@ namespace AZ
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
#endif
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
}
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
@@ -1395,10 +1405,7 @@ namespace AZ
//=========================================================================
void ComponentApplication::CalculateExecutablePath()
{
Utils::GetExecutableDirectory(m_exeDirectory.data(), m_exeDirectory.capacity());
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string stored within it
m_exeDirectory.resize_no_construct(AZStd::char_traits<char>::length(m_exeDirectory.data()));
m_exeDirectory.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
m_exeDirectory = Utils::GetExecutableDirectory();
}
void ComponentApplication::CalculateAppRoot()
@@ -1406,19 +1413,12 @@ namespace AZ
if (AZStd::optional<AZ::StringFunc::Path::FixedString> appRootPath = Utils::GetDefaultAppRootPath(); appRootPath)
{
m_appRoot = AZStd::move(*appRootPath);
if (!m_appRoot.empty() && !m_appRoot.ends_with(AZ_CORRECT_FILESYSTEM_SEPARATOR))
{
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
}
}
void ComponentApplication::CalculateEngineRoot()
{
if (m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native(); !m_engineRoot.empty())
{
m_engineRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
}
m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native();
}
void ComponentApplication::ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath)
@@ -21,6 +21,7 @@
#include <AzCore/Module/DynamicModuleHandle.h>
#include <AzCore/Module/ModuleManager.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/RTTI/ReflectionManager.h>
@@ -392,9 +393,9 @@ namespace AZ
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
IAllocatorAllocate* m_osAllocator{ nullptr };
EntitySetType m_entities;
AZ::IO::FixedMaxPathString m_exeDirectory;
AZ::IO::FixedMaxPathString m_engineRoot;
AZ::IO::FixedMaxPathString m_appRoot;
AZ::IO::FixedMaxPath m_exeDirectory;
AZ::IO::FixedMaxPath m_engineRoot;
AZ::IO::FixedMaxPath m_appRoot;
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectChangedHandler;
@@ -12,7 +12,7 @@
/** @file
* Header file for the Entity class.
* In Lumberyard's component entity system, an entity is an addressable container for
* In Open 3D Engine's component entity system, an entity is an addressable container for
* a group of components. The entity represents the functionality and properties of an
* object within your game.
*/
@@ -19,9 +19,6 @@ namespace AZ
{
class Vector3;
//! Do not allow the scale to be zero to avoid problems with inverting scale.
static constexpr float MinNonUniformScale = 1e-3f;
using NonUniformScaleChangedEvent = AZ::Event<const AZ::Vector3&>;
//! Requests for working with non-uniform scale.
@@ -26,7 +26,7 @@ namespace AZ
{
class Transform;
using TransformChangedEvent = Event<Transform, Transform>;
using TransformChangedEvent = Event<const Transform&, const Transform&>;
using ParentChangedEvent = Event<EntityId, EntityId>;
@@ -42,9 +42,8 @@ namespace AZ
}
}
#define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
#ifdef AZ_PROFILE_TELEMETRY
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
# define AZ_TRACE_METHOD_NAME(name) \
AZ_TRACE_METHOD_NAME_CATEGORY(name, "") \
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzTrace, name)
@@ -53,6 +52,7 @@ namespace AZ
AZ_TRACE_METHOD_NAME_CATEGORY(AZ_FUNCTION_SIGNATURE, "") \
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzTrace)
#else
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category)
# define AZ_TRACE_METHOD_NAME(name) AZ_TRACE_METHOD_NAME_CATEGORY(name, "")
# define AZ_TRACE_METHOD() AZ_TRACE_METHOD_NAME(AZ_FUNCTION_SIGNATURE)
#endif
+1 -1
View File
@@ -15,7 +15,7 @@
* Header file for internal EBus classes.
* For more information about EBuses, see AZ::EBus and AZ::EBusTraits in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
#pragma once
+5 -5
View File
@@ -13,11 +13,11 @@
/**
* @file
* Header file for event bus (EBus), a general-purpose communication system
* that Lumberyard uses to dispatch notifications and receive requests.
* that Open 3D Engine uses to dispatch notifications and receive requests.
* EBuses are configurable and support many different use cases.
* For more information about %EBuses, see AZ::EBus in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
#pragma once
@@ -70,7 +70,7 @@ namespace AZ
*
* For more information about %EBuses, see EBus in this guide and
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*/
struct EBusTraits
{
@@ -256,7 +256,7 @@ namespace AZ
/**
* Event buses (EBuses) are a general-purpose communication system
* that Lumberyard uses to dispatch notifications and receive requests.
* that Open 3D Engine uses to dispatch notifications and receive requests.
*
* @tparam Interface A class whose virtual functions define the events
* dispatched or received by the %EBus.
@@ -268,7 +268,7 @@ namespace AZ
* For more information about EBuses, see
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
* and [Components and EBuses: Best Practices ](http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-components-ebuses-best-practices.html)
* in the *Lumberyard Developer Guide*.
* in the *Open 3D Engine Developer Guide*.
*
* ## How Components Use EBuses
* Components commonly use EBuses in two ways: to dispatch events or to handle requests.
+11 -11
View File
@@ -96,8 +96,8 @@ namespace AZ::IO
constexpr int Compare(const value_type* pathString) const noexcept;
// decomposition
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
//! "/lumberyard/foo/bar/name.txt"
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
//! "/O3DE/foo/bar/name.txt"
//! The following functions return the following
//! Returns the root name part of the path. if it has one.
@@ -114,10 +114,10 @@ namespace AZ::IO
constexpr PathView RootPath() const;
//! Returns the relative path portion of the path.
//! This contains the path parts after the root path
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
constexpr PathView RelativePath() const;
//! Returns the parent directory of filename contained within the path
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
constexpr PathView ParentPath() const;
@@ -150,7 +150,7 @@ namespace AZ::IO
//! The root portion of the path is made up of root_name() / root_directory()
[[nodiscard]] constexpr bool HasRootPath() const;
//! checks whether the relative part of path is empty
//! (C:\\ lumberyard\dev\)
//! (C:\\ O3DE\dev\)
//! ^ ^
//! root part relative part
[[nodiscard]] constexpr bool HasRelativePath() const;
@@ -485,10 +485,10 @@ namespace AZ::IO
constexpr PathView RootPath() const;
//! Returns the relative path portion of the path.
//! This contains the path parts after the root path
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
constexpr PathView RelativePath() const;
//! Returns the parent directory of filename contained within the path
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
constexpr PathView ParentPath() const;
@@ -521,8 +521,8 @@ namespace AZ::IO
//! The root portion of the path is made up of root_name() / root_directory()
[[nodiscard]] constexpr bool HasRootPath() const;
//! checks whether the relative part of path is empty
//! (C:\\ lumberyard\dev\)
//! ^ ^
//! (C:\\ O3DE\dev\)
//! ^ ^
//! root part relative part
[[nodiscard]] constexpr bool HasRelativePath() const;
//! checks whether the path has a parent path that empty
@@ -544,8 +544,8 @@ namespace AZ::IO
[[nodiscard]] constexpr bool IsRelativeTo(const PathView& base) const;
// decomposition
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
//! "/lumberyard/foo/bar/name.txt"
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
//! "/O3DE/foo/bar/name.txt"
//! The following functions return the following
// query
@@ -147,15 +147,18 @@ namespace AZ
ReadFile(request, args);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -146,15 +146,18 @@ namespace AZ
DestroyDedicatedCache(request, args);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -97,19 +97,22 @@ namespace AZ
CancelRequest(request, args.m_target);
return;
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
else
{
FlushCache(args.m_path);
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
{
FlushCache(args.m_path);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
FlushEntireCache();
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
{
Report(args);
}
StreamStackEntry::QueueRequest(request);
}, request->GetCommand());
}
@@ -374,7 +374,7 @@ namespace AZ
targetForward.Normalize();
// Lumberyard is Z-up and is right-handed.
// Open 3D Engine is Z-up and is right-handed.
Vector3 up = Vector3::CreateAxisZ();
// We have a degenerate case if target forward is parallel to the up axis,
@@ -391,7 +391,7 @@ namespace AZ
up.Normalize();
// Passing in forwardAxis allows you to force a particular local-space axis to look
// at the target point. In Lumberyard, the default is forward is along Y+.
// at the target point. In Open 3D Engine, the default is forward is along Y+.
switch (forwardAxis)
{
case Axis::XPositive:
@@ -426,7 +426,7 @@ namespace AZ
Matrix4x4 Matrix4x4::CreateProjection(float fovY, float aspectRatio, float nearDist, float farDist)
{
// This section contains some notes about camera matrices and field of view, because there are some subtle differences
// between the convention Lumberyard uses and what you might be used to from other software packages.
// between the convention Open 3D Engine uses and what you might be used to from other software packages.
// Our camera space has the camera looking down the *positive* z-axis, the x-axis points towards the left of the screen,
// and the y-axis points towards the top of the screen.
//
+1 -1
View File
@@ -154,7 +154,7 @@ namespace AZ
return Obb::CreateFromPositionRotationAndHalfLengths(
transform.TransformPoint(obb.GetPosition()),
transform.GetRotation() * obb.GetRotation(),
obb.GetHalfLengths()
transform.GetScale() * obb.GetHalfLengths()
);
}
}
@@ -354,7 +354,7 @@ namespace AZ
targetForward.Normalize();
// Lumberyard is Z-up and is right-handed.
// Open 3D Engine is Z-up and is right-handed.
Vector3 up = Vector3::CreateAxisZ();
// We have a degenerate case if target forward is parallel to the up axis,
@@ -371,7 +371,7 @@ namespace AZ
up.Normalize();
// Passing in forwardAxis allows you to force a particular local-space axis to look
// at the target point. In Lumberyard, the default is forward is along Y+.
// at the target point. In Open 3D Engine, the default is forward is along Y+.
switch (forwardAxis)
{
case Axis::XPositive:
@@ -38,6 +38,13 @@ namespace AZ
bool CompareValueData(const void* lhs, const void* rhs) override;
};
//! Limits for transform scale values.
//! The scale should not be zero to avoid problems with inverting.
//! @{
static constexpr float MinTransformScale = 1e-2f;
static constexpr float MaxTransformScale = 1e9f;
//! @}
//! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation.
//! By design, cannot represent skew transformations.
class Transform
@@ -167,14 +167,14 @@ namespace AZ
}
}
AZ_MATH_INLINE Vector2::Vector2(const Vector3& source)
Vector2::Vector2(const Vector3& source)
: m_x(source.GetX())
, m_y(source.GetY())
{
}
AZ_MATH_INLINE Vector2::Vector2(const Vector4& source)
Vector2::Vector2(const Vector4& source)
: m_x(source.GetX())
, m_y(source.GetY())
{
@@ -707,7 +707,7 @@ PoolSchema::GarbageCollect()
// occur exclusively in the destruction of the allocator.
//
// TODO: A better solution needs to be found for integrating back into mainline
// Lumberyard.
// Open 3D Engine.
//m_impl->GarbageCollect();
}
@@ -0,0 +1,340 @@
/*
* 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/Casting/numeric_cast.h>
#include <AzCore/PlatformId/PlatformDefaults.h>
#include <AzCore/StringFunc/StringFunc.h>
namespace AZ
{
inline namespace PlatformDefaults
{
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
{
#ifdef IOS
#define AZ_REDEFINE_IOS_AT_END IOS
#undef IOS
#endif
switch (platform)
{
case AZ::PC:
return "PC";
case AZ::ES3:
return "Android";
case AZ::IOS:
return "iOS";
case AZ::OSX:
return "Mac";
case AZ::PROVO:
return "Provo";
case AZ::SALEM:
return "Salem";
case AZ::JASPER:
return "Jasper";
case AZ::SERVER:
return "Server";
case AZ::ALL:
case AZ::ALL_CLIENT:
case AZ::NumPlatformIds:
case AZ::Invalid:
default:
return "";
}
#ifdef AZ_REDEFINE_IOS_AT_END
#define IOS AZ_REDEFINE_IOS_AT_END
#endif
}
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
{
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
{
return PlatformPC;
}
else if (osPlatform == PlatformCodeNameMac)
{
return PlatformOSX;
}
else if (osPlatform == PlatformCodeNameAndroid)
{
return PlatformES3;
}
else if (osPlatform == PlatformCodeNameiOS)
{
return PlatformIOS;
}
else if (osPlatform == PlatformCodeNameProvo)
{
return PlatformProvo;
}
else if (osPlatform == PlatformCodeNameSalem)
{
return PlatformSalem;
}
else if (osPlatform == PlatformCodeNameJasper)
{
return PlatformJasper;
}
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
return "";
}
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
{
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
{
return PlatformFlags::Platform_NONE;
}
if (platformIndex == PlatformId::ALL)
{
return PlatformFlags::Platform_ALL;
}
if (platformIndex == PlatformId::ALL_CLIENT)
{
return PlatformFlags::Platform_ALL_CLIENT;
}
return static_cast<PlatformFlags>(1 << platformIndex);
}
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
{
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
{
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
if (isAllPlatforms || isAllClientPlatforms
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
{
platforms.push_back(PlatformNames[platformNum]);
}
}
return platforms;
}
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
{
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
}
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
{
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
{
PlatformId index = static_cast<PlatformId>(i);
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
{
platformIndices.emplace_back(index);
}
}
return platformIndices;
}
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
{
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
}
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
{
int platformIndex = GetPlatformIndexFromName(platform);
if (platformIndex == PlatformId::Invalid)
{
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
return PlatformFlags::Platform_NONE;
}
if (platformIndex == PlatformId::ALL)
{
return PlatformFlags::Platform_ALL;
}
if (platformIndex == PlatformId::ALL_CLIENT)
{
return PlatformFlags::Platform_ALL_CLIENT;
}
return static_cast<PlatformFlags>(1 << platformIndex);
}
const char* PlatformHelper::GetPlatformName(PlatformId platform)
{
if (platform < 0 || platform > PlatformId::NumPlatformIds)
{
return "invalid";
}
return PlatformNames[platform];
}
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
{
PlatformId platform = GetPlatformIdFromName(platformId);
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
AppendPlatformCodeNames(platformCodes, platform);
}
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
{
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
#pragma push_macro("IOS")
#undef IOS
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
switch (platformId)
{
case PlatformId::PC:
platformCodes.emplace_back(PlatformCodeNameWindows);
platformCodes.emplace_back(PlatformCodeNameLinux);
break;
case PlatformId::ES3:
platformCodes.emplace_back(PlatformCodeNameAndroid);
break;
case PlatformId::IOS:
platformCodes.emplace_back(PlatformCodeNameiOS);
break;
case PlatformId::OSX:
platformCodes.emplace_back(PlatformCodeNameMac);
break;
case PlatformId::PROVO:
platformCodes.emplace_back(PlatformCodeNameProvo);
break;
case PlatformId::SALEM:
platformCodes.emplace_back(PlatformCodeNameSalem);
break;
case PlatformId::JASPER:
platformCodes.emplace_back(PlatformCodeNameJasper);
break;
case PlatformId::SERVER:
// Server is not a hardware platform
break;
default:
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
break;
}
#pragma pop_macro("IOS")
}
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
{
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
{
if (platformName == PlatformNames[idx])
{
return idx;
}
}
return PlatformId::Invalid;
}
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
{
return aznumeric_caster(GetPlatformIndexFromName(platformName));
}
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
{
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
AssetPlatformCombinedString platformsString;
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
return platformsString;
}
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
{
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
if ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
{
for (int i = 0; i < NumPlatforms; ++i)
{
auto platformId = static_cast<PlatformId>(i);
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
{
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
}
}
}
else if ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
{
for (int i = 0; i < NumPlatforms; ++i)
{
auto platformId = static_cast<PlatformId>(i);
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
{
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
}
}
}
else
{
returnFlags = platformFlags;
}
return returnFlags;
}
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
{
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
}
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
{
return (flags & checkPlatform) == checkPlatform;
}
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
{
// If checkPlatform contains any kind of invalid id, just exit out here
if (checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
{
return false;
}
// ALL_CLIENT + SERVER = ALL
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
{
flags = PlatformFlags::Platform_ALL;
}
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL))
{
// It doesn't matter what checkPlatform is set to in this case, just return true
return true;
}
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
{
return checkPlatform != PlatformId::SERVER;
}
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
}
}
}
@@ -0,0 +1,157 @@
/*
* 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/Preprocessor/Enum.h>
#include <AzCore/std/containers/fixed_vector.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/std/string/string_view.h>
// On IOS builds IOS will be defined and interfere with the below enums
#pragma push_macro("IOS")
#undef IOS
namespace AZ
{
inline namespace PlatformDefaults
{
constexpr char PlatformPC[] = "pc";
constexpr char PlatformES3[] = "es3";
constexpr char PlatformIOS[] = "ios";
constexpr char PlatformOSX[] = "osx_gl";
constexpr char PlatformProvo[] = "provo";
constexpr char PlatformSalem[] = "salem";
constexpr char PlatformJasper[] = "jasper";
constexpr char PlatformServer[] = "server";
constexpr char PlatformCodeNameWindows[] = "Windows";
constexpr char PlatformCodeNameLinux[] = "Linux";
constexpr char PlatformCodeNameAndroid[] = "Android";
constexpr char PlatformCodeNameiOS[] = "iOS";
constexpr char PlatformCodeNameMac[] = "Mac";
constexpr char PlatformCodeNameProvo[] = "Provo";
constexpr char PlatformCodeNameSalem[] = "Salem";
constexpr char PlatformCodeNameJasper[] = "Jasper";
constexpr char PlatformAll[] = "all";
constexpr char PlatformAllClient[] = "all_client";
// Used for the capacity of a fixed vector to store the code names of platforms
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
constexpr size_t MaxPlatformCodeNames = 16;
//! This platform enum have platform values in sequence and can also be used to get the platform count.
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
(Invalid, -1),
PC,
ES3,
IOS,
OSX,
PROVO,
SALEM,
JASPER,
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
ALL,
ALL_CLIENT,
// Add new platforms above this
NumPlatformIds
);
constexpr int NumClientPlatforms = 7;
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
enum class PlatformFlags : AZ::u32
{
Platform_NONE = 0x00,
Platform_PC = 1 << PlatformId::PC,
Platform_ES3 = 1 << PlatformId::ES3,
Platform_IOS = 1 << PlatformId::IOS,
Platform_OSX = 1 << PlatformId::OSX,
Platform_PROVO = 1 << PlatformId::PROVO,
Platform_SALEM = 1 << PlatformId::SALEM,
Platform_JASPER = 1 << PlatformId::JASPER,
Platform_SERVER = 1 << PlatformId::SERVER,
// A special platform that will always correspond to all platforms, even if new ones are added
Platform_ALL = 1ULL << 30,
// 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,
};
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
// 32 characters should be more than enough to store a platform name
using AssetPlatformFixedString = AZStd::fixed_string<32>;
// Fixed string which can store a comma separated list of platforms names
// Additional byte is added to take into account the comma
using AssetPlatformCombinedString = AZStd::fixed_string < (AssetPlatformFixedString{}.max_size() + 1)* PlatformId::NumPlatformIds > ;
const char* PlatformIdToPalFolder(PlatformId platform);
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
//! Platform Helper is an utility class that can be used to retrieve platform related information
class PlatformHelper
{
public:
//! Given a platformIndex returns the platform name
static const char* GetPlatformName(PlatformId platform);
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
//! Given a platform name returns a platform index.
//! If the platform is not found, the method returns -1.
static int GetPlatformIndexFromName(AZStd::string_view platformName);
//! Given a platform name returns a platform id.
//! If the platform is not found, the method returns -1.
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
//! Given a platformIndex returns the platformFlags
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
//! Given a platformFlags returns all the platform identifiers that are set.
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
//! Given a platformFlags return a list of PlatformId indices
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
//! Given a platform identifier returns its corresponding platform flag.
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
//! Given any platformFlags returns a string listing the input platforms
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
//! Returns true if platformFlags contains any special flags
static bool IsSpecialPlatform(PlatformFlags platformFlags);
//! Returns true if platformFlags has checkPlatform flag set.
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
};
}
}
#pragma pop_macro("IOS")
@@ -1600,7 +1600,7 @@ static int Global_Typeid(lua_State* l)
return 1;
}
#ifdef LUA_LUMBERYARD_EXTENSIONS
#ifdef LUA_O3DE_EXTENSIONS
//=========================================================================
// LUA Dummy Node Extension
@@ -1631,7 +1631,7 @@ LUA_API const Node* lua_getDummyNode()
return &(*s_luaDummyNodeVariable);
}
#endif // LUA_LUMBERYARD_EXTENSIONS
#endif // LUA_O3DE_EXTENSIONS
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -103,7 +103,7 @@ namespace AZ
const static AZ::Crc32 ChangeNotify = AZ_CRC("ChangeNotify", 0xf793bc19);
const static AZ::Crc32 ClearNotify = AZ_CRC("ClearNotify", 0x88914c8c);
//! Specifies a function to accept or reject a value changed in the Lumberyard Editor.
//! Specifies a function to accept or reject a value changed in the Open 3D Engine Editor.
//! For example, a component could reject AZ::EntityId values that reference its own entity.
//!
//! Element type to use this with: Any type that you reflect using AZ::EditContext::ClassInfo::DataElement().
@@ -22,9 +22,9 @@ namespace AZ
// JsonBaseContext
//
JsonBaseContext::JsonBaseContext(JsonSerializationMetadata metadata, JsonSerializationResult::JsonIssueCallback reporting,
JsonBaseContext::JsonBaseContext(JsonSerializationMetadata& metadata, JsonSerializationResult::JsonIssueCallback reporting,
StackedString::Format pathFormat, SerializeContext* serializeContext, JsonRegistrationContext* registrationContext)
: m_metadata(AZStd::move(metadata))
: m_metadata(metadata)
, m_serializeContext(serializeContext)
, m_registrationContext(registrationContext)
, m_path(pathFormat)
@@ -126,20 +126,13 @@ namespace AZ
// JsonDeserializerContext
//
JsonDeserializerContext::JsonDeserializerContext(const JsonDeserializerSettings& settings)
JsonDeserializerContext::JsonDeserializerContext(JsonDeserializerSettings& settings)
: JsonBaseContext(settings.m_metadata, settings.m_reporting,
StackedString::Format::JsonPointer, settings.m_serializeContext, settings.m_registrationContext)
, m_clearContainers(settings.m_clearContainers)
{
}
JsonDeserializerContext::JsonDeserializerContext(JsonDeserializerSettings&& settings)
: JsonBaseContext(AZStd::move(settings.m_metadata), AZStd::move(settings.m_reporting),
StackedString::Format::JsonPointer, settings.m_serializeContext, settings.m_registrationContext)
, m_clearContainers(settings.m_clearContainers)
{
}
bool JsonDeserializerContext::ShouldClearContainers() const
{
return m_clearContainers;
@@ -151,7 +144,7 @@ namespace AZ
// JsonSerializerContext
//
JsonSerializerContext::JsonSerializerContext(const JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator)
JsonSerializerContext::JsonSerializerContext(JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator)
: JsonBaseContext(settings.m_metadata, settings.m_reporting, StackedString::Format::ContextPath,
settings.m_serializeContext, settings.m_registrationContext)
, m_jsonAllocator(jsonAllocator)
@@ -159,14 +152,6 @@ namespace AZ
{
}
JsonSerializerContext::JsonSerializerContext(JsonSerializerSettings&& settings, rapidjson::Document::AllocatorType& jsonAllocator)
: JsonBaseContext(AZStd::move(settings.m_metadata), AZStd::move(settings.m_reporting), StackedString::Format::ContextPath,
settings.m_serializeContext, settings.m_registrationContext)
, m_jsonAllocator(jsonAllocator)
, m_keepDefaults(settings.m_keepDefaults)
{
}
rapidjson::Document::AllocatorType& JsonSerializerContext::GetJsonAllocator()
{
return m_jsonAllocator;
@@ -26,7 +26,7 @@ namespace AZ
class JsonBaseContext
{
public:
JsonBaseContext(JsonSerializationMetadata metadata, JsonSerializationResult::JsonIssueCallback reporting,
JsonBaseContext(JsonSerializationMetadata& metadata, JsonSerializationResult::JsonIssueCallback reporting,
StackedString::Format pathFormat, SerializeContext* serializeContext, JsonRegistrationContext* registrationContext);
virtual ~JsonBaseContext() = default;
@@ -71,10 +71,6 @@ namespace AZ
const JsonRegistrationContext* GetRegistrationContext() const;
protected:
//! Metadata that's passed in by the settings as additional configuration options or metadata that's collected
//! during processing for later use.
JsonSerializationMetadata m_metadata;
//! Callback used to report progress and issues. Users of the serialization can update the return code to change
//! the behavior of the serializer.
AZStd::stack<JsonSerializationResult::JsonIssueCallback> m_reporters;
@@ -82,6 +78,10 @@ namespace AZ
//! Path to the element that's currently being operated on.
StackedString m_path;
//! Metadata that's passed in by the settings as additional configuration options or metadata that's collected
//! during processing for later use.
JsonSerializationMetadata& m_metadata;
//! The Serialize Context that can be used to retrieve meta data during processing.
SerializeContext* m_serializeContext = nullptr;
//! The registration context for the json serialization. This can be used to retrieve the handlers for specific types.
@@ -92,8 +92,7 @@ namespace AZ
: public JsonBaseContext
{
public:
explicit JsonDeserializerContext(const JsonDeserializerSettings& settings);
explicit JsonDeserializerContext(JsonDeserializerSettings&& settings);
explicit JsonDeserializerContext(JsonDeserializerSettings& settings);
~JsonDeserializerContext() override = default;
JsonDeserializerContext(const JsonDeserializerContext&) = delete;
@@ -114,8 +113,7 @@ namespace AZ
: public JsonBaseContext
{
public:
explicit JsonSerializerContext(const JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator);
explicit JsonSerializerContext(JsonSerializerSettings&& settings, rapidjson::Document::AllocatorType& jsonAllocator);
JsonSerializerContext(JsonSerializerSettings& settings, rapidjson::Document::AllocatorType& jsonAllocator);
~JsonSerializerContext() override = default;
JsonSerializerContext(const JsonSerializerContext&) = delete;
@@ -0,0 +1,100 @@
/*
* 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 "ByteStreamSerializer.h"
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/StringFunc/StringFunc.h>
namespace AZ
{
namespace ByteSerializerInternal
{
static JsonSerializationResult::Result Load(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
switch (inputValue.GetType())
{
case rapidjson::kStringType: {
JsonByteStream buffer;
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
{
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
*valAsByteStream = AZStd::move(buffer);
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
}
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
}
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kNullType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
return context.Report(
Tasks::ReadField, Outcomes::Unsupported,
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
default:
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
}
}
static JsonSerializationResult::Result StoreWithDefault(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, JsonSerializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
{
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
}
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
}
} // namespace ByteSerializerInternal
AZ_CLASS_ALLOCATOR_IMPL(JsonByteStreamSerializer, SystemAllocator, 0);
JsonSerializationResult::Result JsonByteStreamSerializer::Load(
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
AZ_Assert(
azrtti_typeid<JsonByteStream>() == outputValueTypeId,
"Unable to deserialize AZStd::vector<AZ::u8>> to json because the provided type is %s",
outputValueTypeId.ToString<AZStd::string>().c_str());
return ByteSerializerInternal::Load(outputValue, inputValue, context);
}
JsonSerializationResult::Result JsonByteStreamSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
JsonSerializerContext& context)
{
AZ_Assert(
azrtti_typeid<JsonByteStream>() == valueTypeId,
"Unable to serialize AZStd::vector<AZ::u8> to json because the provided type is %s",
valueTypeId.ToString<AZStd::string>().c_str());
return ByteSerializerInternal::StoreWithDefault(outputValue, inputValue, defaultValue, context);
}
} // namespace AZ
@@ -0,0 +1,38 @@
/*
* 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/Serialization/Json/BaseJsonSerializer.h>
#include <AzCore/std/containers/vector.h>
namespace AZ
{
using JsonByteStream = AZStd::vector<AZ::u8>; //!< Alias for AZStd::vector<AZ::u8>.
//! Serialize a stream of bytes (usually binary data) as a json string value.
//! @note Related to GenericClassByteStream (part of SerializeGenericTypeInfo<AZStd::vector<AZ::u8>> - see AZStdContainers.inl for more
//! details).
class JsonByteStreamSerializer : public BaseJsonSerializer
{
public:
AZ_RTTI(JsonByteStreamSerializer, "{30F0EA5A-CD13-4BA7-BAE1-D50D851CAC45}", 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;
};
} // namespace AZ
@@ -20,7 +20,7 @@ namespace AZ
{
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -122,7 +122,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreatePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, JsonCreatePatchSettings& settings)
{
StackedString element(StackedString::Format::JsonPointer);
return CreatePatchInternal(patch.SetArray(), allocator, source, target, element, settings);
@@ -130,7 +130,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -196,14 +196,14 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreateMergePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, JsonCreatePatchSettings& settings)
{
StackedString element(StackedString::Format::JsonPointer);
return CreateMergePatchInternal(patch, allocator, source, target, element, settings);
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_GetFromValue(rapidjson::Value** fromValue, rapidjson::Pointer& fromPointer,
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, const JsonApplyPatchSettings& settings)
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -242,7 +242,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Add(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -261,7 +261,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_AddValue(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Pointer& path, rapidjson::Value&& newValue,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -347,7 +347,7 @@ namespace AZ
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -399,7 +399,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Replace(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -426,7 +426,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Move(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -445,7 +445,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Copy(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& entry, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings)
StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -463,7 +463,7 @@ namespace AZ
}
JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Test(rapidjson::Value& target, const rapidjson::Value& entry,
const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings)
const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -495,7 +495,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreatePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -633,7 +633,7 @@ namespace AZ
JsonSerializationResult::ResultCode JsonMerger::CreateMergePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings)
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -30,43 +30,43 @@ namespace AZ
//! Implementation of the JSON Patch algorithm: https://tools.ietf.org/html/rfc6902
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings);
JsonApplyPatchSettings& settings);
//! Function to create JSON Patches: https://tools.ietf.org/html/rfc6902
static JsonSerializationResult::ResultCode CreatePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, JsonCreatePatchSettings& settings);
//! Implementation of the JSON Merge Patch algorithm: https://tools.ietf.org/html/rfc7386
static JsonSerializationResult::ResultCode ApplyMergePatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
const JsonApplyPatchSettings& settings);
JsonApplyPatchSettings& settings);
//! Function to create JSON Merge Patches: https://tools.ietf.org/html/rfc7386
static JsonSerializationResult::ResultCode CreateMergePatch(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, JsonCreatePatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_GetFromValue(rapidjson::Value** fromValue, rapidjson::Pointer& fromPointer,
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, const JsonApplyPatchSettings& settings);
rapidjson::Value& target, const rapidjson::Value& entry, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Add(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_AddValue(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Pointer& path, rapidjson::Value&& newValue, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Pointer& path, rapidjson::Value&& newValue, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path,
StackedString& element, const JsonApplyPatchSettings& settings);
StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Replace(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Move(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Copy(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode ApplyPatch_Test(rapidjson::Value& target,
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, const JsonApplyPatchSettings& settings);
const rapidjson::Value& entry, const rapidjson::Pointer& path, StackedString& element, JsonApplyPatchSettings& settings);
static JsonSerializationResult::ResultCode CreatePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings);
static rapidjson::Value CreatePatchInternal_Add(rapidjson::Document::AllocatorType& allocator,
StackedString& path, const rapidjson::Value& value);
static rapidjson::Value CreatePatchInternal_Remove(rapidjson::Document::AllocatorType& allocator, StackedString& path);
@@ -75,6 +75,6 @@ namespace AZ
static JsonSerializationResult::ResultCode CreateMergePatchInternal(rapidjson::Value& patch,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, StackedString& element, const JsonCreatePatchSettings& settings);
const rapidjson::Value& target, StackedString& element, JsonCreatePatchSettings& settings);
};
} // namespace AZ
@@ -97,9 +97,18 @@ namespace AZ
}
} // namespace JsonSerializationInternal
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(
rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonMergeApproach approach,
const JsonApplyPatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonApplyPatchSettings settingsCopy{ settings };
return ApplyPatch(target, allocator, patch, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(rapidjson::Value& target,
rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonMergeApproach approach,
JsonApplyPatchSettings settings)
JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -126,8 +135,17 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& patch, JsonMergeApproach approach, const JsonApplyPatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonApplyPatchSettings settingsCopy{settings};
return ApplyPatch(output, allocator, source, patch, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::ApplyPatch(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings settings)
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -166,9 +184,18 @@ namespace AZ
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, const JsonCreatePatchSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonCreatePatchSettings settingsCopy{settings};
return CreatePatch(patch, allocator, source, target, approach, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings& settings)
{
using namespace JsonSerializationResult;
@@ -194,7 +221,16 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerialization::Load(void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, const JsonDeserializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonDeserializerSettings settingsCopy{settings};
return Load(object, objectType, root, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -212,14 +248,23 @@ namespace AZ
if (result.GetOutcome() == Outcomes::Success)
{
StackedString path(StackedString::Format::JsonPointer);
JsonDeserializerContext context(AZStd::move(settings));
JsonDeserializerContext context(settings);
result = JsonDeserializer::Load(object, objectType, root, context);
}
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::LoadTypeId(
Uuid& typeId, const rapidjson::Value& input, const Uuid* baseClassTypeId, AZStd::string_view jsonPath,
const JsonDeserializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonDeserializerSettings settingsCopy{settings};
return LoadTypeId(typeId, input, baseClassTypeId, jsonPath, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::LoadTypeId(Uuid& typeId, const rapidjson::Value& input,
const Uuid* baseClassTypeId, AZStd::string_view jsonPath, JsonDeserializerSettings settings)
const Uuid* baseClassTypeId, AZStd::string_view jsonPath, JsonDeserializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -236,7 +281,7 @@ namespace AZ
ResultCode result = JsonSerializationInternal::GetContexts(settings, settings.m_serializeContext, settings.m_registrationContext);
if (result.GetOutcome() == Outcomes::Success)
{
JsonDeserializerContext context(AZStd::move(settings));
JsonDeserializerContext context(settings);
context.PushPath(jsonPath);
result = JsonDeserializer::LoadTypeId(typeId, input, context, baseClassTypeId);
@@ -244,8 +289,18 @@ namespace AZ
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const void* object, const void* defaultObject, const Uuid& objectType, JsonSerializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, const JsonSerializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonSerializerSettings settingsCopy{settings};
return Store(output, allocator, object, defaultObject, objectType, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, JsonSerializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -269,15 +324,24 @@ namespace AZ
settings.m_keepDefaults = false;
}
JsonSerializerContext context(AZStd::move(settings), allocator);
JsonSerializerContext context(settings, allocator);
StackedString path(StackedString::Format::ContextPath);
result = JsonSerializer::Store(output, object, defaultObject, objectType, context);
}
return result;
}
JsonSerializationResult::ResultCode JsonSerialization::StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId, AZStd::string_view elementPath,
const JsonSerializerSettings& settings)
{
// Explicitly make a copy to call the correct overloaded version and avoid infinite recursion on this function.
JsonSerializerSettings settingsCopy{settings};
return StoreTypeId(output, allocator, typeId, elementPath, settingsCopy);
}
JsonSerializationResult::ResultCode JsonSerialization::StoreTypeId(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const Uuid& typeId, AZStd::string_view elementPath, JsonSerializerSettings settings)
const Uuid& typeId, AZStd::string_view elementPath, JsonSerializerSettings& settings)
{
using namespace JsonSerializationResult;
@@ -294,7 +358,7 @@ namespace AZ
ResultCode result = JsonSerializationInternal::GetContexts(settings, settings.m_serializeContext, settings.m_registrationContext);
if (result.GetOutcome() == Outcomes::Success)
{
JsonSerializerContext context(AZStd::move(settings), allocator);
JsonSerializerContext context(settings, allocator);
context.PushPath(elementPath);
result = JsonSerializer::StoreTypeName(output, typeId, context);
}
@@ -48,14 +48,25 @@ namespace AZ
//! Merges two json values together by applying "patch" to "target" using the selected merge algorithm.
//! This version of ApplyPatch is destructive to "target". If the patch can't be correctly applied it will
//! leave target in a partially patched state. Use the over version of ApplyPatch if target should be copied.
//! leave target in a partially patched state. Use the other version of ApplyPatch if target should be copied.
//! @param target The value where the patch will be applied to.
//! @param allocator The allocator associated with the document that holds the target.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Optional additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings settings = JsonApplyPatchSettings{});
const rapidjson::Value& patch, JsonMergeApproach approach, const JsonApplyPatchSettings& settings = JsonApplyPatchSettings{});
//! Merges two json values together by applying "patch" to "target" using the selected merge algorithm.
//! This version of ApplyPatch is destructive to "target". If the patch can't be correctly applied it will
//! leave target in a partially patched state. Use the other version of ApplyPatch if target should be copied.
//! @param target The value where the patch will be applied to.
//! @param allocator The allocator associated with the document that holds the target.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(
rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch,
JsonMergeApproach approach, JsonApplyPatchSettings& settings);
//! Merges two json values together by applying "patch" to a copy of "output" and written to output using the
//! selected merge algorithm. This version of ApplyPatch is non-destructive to "source". If the patch couldn't be
@@ -68,7 +79,19 @@ namespace AZ
//! @param settings Optional additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& patch, JsonMergeApproach approach,
JsonApplyPatchSettings settings = JsonApplyPatchSettings{});
const JsonApplyPatchSettings& settings = JsonApplyPatchSettings{});
//! Merges two json values together by applying "patch" to a copy of "output" and written to output using the
//! selected merge algorithm. This version of ApplyPatch is non-destructive to "source". If the patch couldn't be
//! fully applied "output" will be left set to an empty (default) object.
//! @param source A copy of source with the patch applied to it or an empty object if the patch couldn't be applied.
//! @param allocator The allocator associated with the document that holds the source.
//! @param target The value where the patch will be applied to.
//! @param patch The value holding the patch information.
//! @param approach The merge algorithm that will be used to apply the patch on top of the target.
//! @param settings Additional settings to control the way the patch is applied.
static JsonSerializationResult::ResultCode ApplyPatch(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& patch, JsonMergeApproach approach, JsonApplyPatchSettings& settings);
//! Creates a patch using the selected merge algorithm such that when applied to source it results in target.
//! @param patch The value containing the differences between source and target.
@@ -79,22 +102,46 @@ namespace AZ
//! @param settings Optional additional settings to control the way the patch is created.
static JsonSerializationResult::ResultCode CreatePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator,
const rapidjson::Value& source, const rapidjson::Value& target, JsonMergeApproach approach,
JsonCreatePatchSettings settings = JsonCreatePatchSettings{});
const JsonCreatePatchSettings& settings = JsonCreatePatchSettings{});
//! Creates a patch using the selected merge algorithm such that when applied to source it results in target.
//! @param patch The value containing the differences between source and target.
//! @param allocator The allocator associated with the document that will hold the patch.
//! @param source The value used as a starting point.
//! @param target The value that will result if the patch is applied to the source.
//! @param approach The algorithm that will be used when the patch is applied to the source.
//! @param settings Additional settings to control the way the patch is created.
static JsonSerializationResult::ResultCode CreatePatch(
rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source,
const rapidjson::Value& target, JsonMergeApproach approach, JsonCreatePatchSettings& settings);
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Object where the data will be loaded into.
//! @param root The Value or Document where the deserializer will start reading data from.
//! @param settings The settings used during deserialization. Use the value passed in from Load.
//! @param settings Optional additional settings to control the way document is deserialized.
template<typename T>
static JsonSerializationResult::ResultCode Load(T& object, const rapidjson::Value& root,
JsonDeserializerSettings settings = JsonDeserializerSettings{});
static JsonSerializationResult::ResultCode Load(
T& object, const rapidjson::Value& root, const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Object where the data will be loaded into.
//! @param root The Value or Document where the deserializer will start reading data from.
//! @param settings Additional settings to control the way document is deserialized.
template<typename T>
static JsonSerializationResult::ResultCode Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings& settings);
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Pointer to the object where the data will be loaded into.
//! @param objectType Type id of the object passed in.
//! @param root The Value or Document from where the deserializer will start reading data.
//! @param settings The settings used during deserialization. Use the value passed in from Load.
static JsonSerializationResult::ResultCode Load(void* object, const Uuid& objectType, const rapidjson::Value& root,
JsonDeserializerSettings settings = JsonDeserializerSettings{});
//! @param settings Optional additional settings to control the way document is deserialized.
static JsonSerializationResult::ResultCode Load(
void* object, const Uuid& objectType, const rapidjson::Value& root,
const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the data from the provided json value into the supplied object. The object is expected to be created before calling load.
//! @param object Pointer to the object where the data will be loaded into.
//! @param objectType Type id of the object passed in.
//! @param root The Value or Document from where the deserializer will start reading data.
//! @param settings Additional settings to control the way document is deserialized.
static JsonSerializationResult::ResultCode Load(
void* object, const Uuid& objectType, const rapidjson::Value& root, JsonDeserializerSettings& settings);
//! Loads the type id from the provided input.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the internal
@@ -105,20 +152,44 @@ namespace AZ
//! references multiple types then the baseClassTypeId will be used to disambiguate between the different types by looking
//! if exactly one of the types inherits from the base class that baseClassTypeId points to.
//! @param jsonPath An optional path to the json node. This will be used for reporting.
//! @param settings An optional settings object to change where this function collects information from. This can be same settings
//! @param settings Optional settings object to change where this function collects information from. This can be same settings
//! as used for the other Load functions.
static JsonSerializationResult::ResultCode LoadTypeId(Uuid& typeId, const rapidjson::Value& input,
const Uuid* baseClassTypeId = nullptr, AZStd::string_view jsonPath = AZStd::string_view{},
JsonDeserializerSettings settings = JsonDeserializerSettings{});
const JsonDeserializerSettings& settings = JsonDeserializerSettings{});
//! Loads the type id from the provided input.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the
//! internal type structure and is therefore harder to use.
//! @param typeId The uuid where the loaded data will be written to. If loading fails this will be a null uuid.
//! @param input The json node to load from. The node is expected to contain a string.
//! @param baseClassTypeId. An optional type id for the base class, if known. If a type name is stored in the string which
//! references multiple types then the baseClassTypeId will be used to disambiguate between the different types by looking
//! if exactly one of the types inherits from the base class that baseClassTypeId points to.
//! @param jsonPath An optional path to the json node. This will be used for reporting.
//! @param settings Settings object to change where this function collects information from. This can be same settings
//! as used for the other Load functions.
static JsonSerializationResult::ResultCode LoadTypeId(
Uuid& typeId, const rapidjson::Value& input, const Uuid* baseClassTypeId,
AZStd::string_view jsonPath, JsonDeserializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param settings The settings used during serialization. Use the value passed in from Store.
//! @param settings Optional additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object,
const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param settings Additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object,
JsonSerializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
@@ -127,10 +198,23 @@ namespace AZ
//! @param defaultObject Default object used to compare the object to in order to determine if values are
//! defaulted or not. If this is argument is provided m_keepDefaults in the settings will automatically
//! be set to true.
//! @param settings The settings used during serialization. Use the value passed in from Store.
//! @param settings Optional additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, const T& defaultObject, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object The object that will be read from for values to convert.
//! @param defaultObject Default object used to compare the object to in order to determine if values are
//! defaulted or not. If this is argument is provided m_keepDefaults in the settings will automatically
//! be set to true.
//! @param settings Additional settings to control the way document is serialized.
template<typename T>
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
JsonSerializerSettings& settings);
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
@@ -140,10 +224,22 @@ namespace AZ
//! defaulted or not. This argument can be null, in which case a temporary default may be created if required by
//! the settings. If this is argument is provided m_keepDefaults in the settings will automatically be set to true.
//! @param objectType The type id of the object and default object.
//! @param settings The settings used during serialization. Use the value passed in from Store.
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const void* object, const void* defaultObject, const Uuid& objectType,
JsonSerializerSettings settings = JsonSerializerSettings{});
//! @param settings Optional additional settings to control the way document is serialized.
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores the data in the provided object as json values starting at the provided value.
//! @param output The Value or Document where the converted data will start writing to.
//! @param allocator The memory allocator used by RapidJSON to create the json document.
//! @param object Pointer to the object that will be read from for values to convert.
//! @param defaultObject Pointer to a default object used to compare the object to in order to determine if values are
//! defaulted or not. This argument can be null, in which case a temporary default may be created if required by
//! the settings. If this is argument is provided m_keepDefaults in the settings will automatically be set to true.
//! @param objectType The type id of the object and default object.
//! @param settings Additional settings to control the way document is serialized.
static JsonSerializationResult::ResultCode Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const void* object, const void* defaultObject,
const Uuid& objectType, JsonSerializerSettings& settings);
//! Stores a name for the type id in the provided output. The name can be safely used to reference a type such as a class during loading.
//! Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of the internal
@@ -152,10 +248,25 @@ namespace AZ
//! @param allocator The allocator associated with the document that will or already holds the output.
//! @param typeId The type id to store.
//! @param elementPath An optional path to the element. This will be used for reporting.
//! @param settings An optional settings object to change where this function collects information from. This can be same settings
//! @param settings Optional settings to change where this function collects information from. This can be the same settings
//! as used for the other Store functions.
static JsonSerializationResult::ResultCode StoreTypeId(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const Uuid& typeId, AZStd::string_view elementPath = AZStd::string_view{}, JsonSerializerSettings settings = JsonSerializerSettings{});
static JsonSerializationResult::ResultCode StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId,
AZStd::string_view elementPath = AZStd::string_view{}, const JsonSerializerSettings& settings = JsonSerializerSettings{});
//! Stores a name for the type id in the provided output. The name can be safely used to reference a type such as a class during
//! loading. Note: it's not recommended to use this function (frequently) as it requires users of the json file to have knowledge of
//! the internal
//! type structure and is therefore harder to use.
//! @param output The json value the result will be written to. If successful this will contain a string object otherwise a default
//! object.
//! @param allocator The allocator associated with the document that will or already holds the output.
//! @param typeId The type id to store.
//! @param elementPath The path to the element. This will be used for reporting.
//! @param settings Settings to change where this function collects information from. This can be the same settings
//! as used for the other Store functions.
static JsonSerializationResult::ResultCode StoreTypeId(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const Uuid& typeId,
AZStd::string_view elementPath, JsonSerializerSettings& settings);
//! Compares two json values of any type and determines if the left is less, equal or greater than the right.
//! @param lhs The left hand side value for the compare.
@@ -180,22 +291,43 @@ namespace AZ
};
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, const JsonDeserializerSettings& settings)
{
return Load(&object, azrtti_typeid(object), root, settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, JsonSerializerSettings settings)
JsonSerializationResult::ResultCode JsonSerialization::Load(T& object, const rapidjson::Value& root, JsonDeserializerSettings& settings)
{
return Load(&object, azrtti_typeid(object), root, settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, nullptr, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, nullptr, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator,
const T& object, const T& defaultObject, JsonSerializerSettings settings)
const T& object, const T& defaultObject, const JsonSerializerSettings& settings)
{
return Store(output, allocator, &object,& defaultObject, azrtti_typeid(object), settings);
}
template<typename T>
JsonSerializationResult::ResultCode JsonSerialization::Store(
rapidjson::Value& output, rapidjson::Document::AllocatorType& allocator, const T& object, const T& defaultObject,
JsonSerializerSettings& settings)
{
return Store(output, allocator, &object, &defaultObject, azrtti_typeid(object), settings);
}
} // namespace AZ
@@ -22,14 +22,20 @@ namespace AZ
class JsonSerializationMetadata final
{
public:
//! Creates a new settings object in the metadata collection.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT, typename... Args>
bool Create(Args&&... args);
//! Adds a new settings object to the metadata collection.
//! Only one object of the same type can be added.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT>
bool Add(MetadataT&& data);
//! Adds a new settings object to the metadata collection.
//! Only one object of the same type can be added.
//! Only one object of the same type can be added or created.
//! Returns false if an object of this type was already added.
template<typename MetadataT>
bool Add(const MetadataT& data);
@@ -16,19 +16,31 @@
namespace AZ
{
template<typename MetadataT>
bool JsonSerializationMetadata::Add(MetadataT&& data)
template<typename MetadataT, typename... Args>
bool JsonSerializationMetadata::Create(Args&&... args)
{
auto typeId = azrtti_typeid<MetadataT>();
auto iter = m_data.find(typeId);
if (iter != m_data.end())
const Uuid& typeId = azrtti_typeid<MetadataT>();
if (m_data.find(typeId) != m_data.end())
{
AZ_Warning("JsonSerializationMetadata", false, "Metadata object of type %s already added",
typeId.template ToString<AZStd::string>().c_str());
AZ_Assert(false, "Metadata object of type %s already added", typeId.template ToString<AZStd::string>().c_str());
return false;
}
m_data[typeId] = AZStd::any{ AZStd::forward<MetadataT>(data) };
m_data.emplace(typeId, MetadataT{AZStd::forward<Args>(args)...});
return true;
}
template<typename MetadataT>
bool JsonSerializationMetadata::Add(MetadataT&& data)
{
const Uuid& typeId = azrtti_typeid<MetadataT>();
if (m_data.find(typeId) != m_data.end())
{
AZ_Assert(false, "Metadata object of type %s already added", typeId.template ToString<AZStd::string>().c_str());
return false;
}
m_data.emplace(typeId, AZStd::forward<MetadataT>(data));
return true;
}
@@ -41,7 +53,7 @@ namespace AZ
template<typename MetadataT>
MetadataT* JsonSerializationMetadata::Find()
{
const auto& typeId = azrtti_typeid<MetadataT>();
const Uuid& typeId = azrtti_typeid<MetadataT>();
auto iter = m_data.find(typeId);
return iter != m_data.end() ? AZStd::any_cast<MetadataT>(&iter->second) : nullptr;
}
@@ -14,6 +14,7 @@
#include <AzCore/Serialization/Json/ArraySerializer.h>
#include <AzCore/Serialization/Json/BasicContainerSerializer.h>
#include <AzCore/Serialization/Json/BoolSerializer.h>
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
#include <AzCore/Serialization/Json/DoubleSerializer.h>
#include <AzCore/Serialization/Json/IntSerializer.h>
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
@@ -68,6 +69,8 @@ namespace AZ
jsonContext->Serializer<JsonStringSerializer>()->HandlesType<AZStd::string>();
jsonContext->Serializer<JsonOSStringSerializer>()->HandlesType<OSString>();
jsonContext->Serializer<JsonByteStreamSerializer>()->HandlesType<JsonByteStream>();
jsonContext->Serializer<JsonBasicContainerSerializer>()
->HandlesType<AZStd::fixed_vector>()
->HandlesType<AZStd::forward_list>()
@@ -17,6 +17,7 @@
#include <AzCore/JSON/pointer.h>
#include <AzCore/JSON/prettywriter.h>
#include <AzCore/JSON/writer.h>
#include <AzCore/PlatformId/PlatformDefaults.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Settings/CommandLine.h>
#include <AzCore/std/string/conversions.h>
@@ -132,23 +133,14 @@ namespace AZ::Internal
AZ::IO::FixedMaxPath ScanUpRootLocator(AZStd::string_view rootFileToLocate)
{
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
if (AZ::Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
{
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
// stored within it
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
}
AZ::IO::FixedMaxPath engineRootCandidate{ executableDir };
AZ::IO::FixedMaxPath rootCandidate{ AZ::Utils::GetExecutableDirectory() };
bool rootPathVisited = false;
do
{
if (AZ::IO::SystemFile::Exists((engineRootCandidate / rootFileToLocate).c_str()))
if (AZ::IO::SystemFile::Exists((rootCandidate / rootFileToLocate).c_str()))
{
return engineRootCandidate;
return rootCandidate;
}
// Note for posix filesystems the parent directory of '/' is '/' and for windows
@@ -156,38 +148,69 @@ namespace AZ::Internal
// Validate that the parent directory isn't itself, that would imply
// that it is the filesystem root path
AZ::IO::PathView parentPath = engineRootCandidate.ParentPath();
rootPathVisited = (engineRootCandidate == parentPath);
AZ::IO::PathView parentPath = rootCandidate.ParentPath();
rootPathVisited = (rootCandidate == parentPath);
// Recurse upwards one directory
engineRootCandidate = AZStd::move(parentPath);
rootCandidate = AZStd::move(parentPath);
} while (!rootPathVisited);
return {};
}
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value)
{
AZ::CommandLine commandLine;
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
AZ::CommandLine::ParamContainer paramContainer;
commandLine.Dump(paramContainer);
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
commandLine.Parse(paramContainer);
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
}
} // namespace AZ::Internal
namespace AZ::SettingsRegistryMergeUtils
{
constexpr AZStd::string_view InternalScanUpEngineRootKey{ "/O3DE/Settings/Internal/engine_root_scan_up_path" };
constexpr AZStd::string_view InternalScanUpProjectRootKey{ "/O3DE/Settings/Internal/project_root_scan_up_path" };
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry)
{
AZ::IO::FixedMaxPath engineRoot;
// This is the 'external' engine root key, as in passed from command-line or .setreg files.
auto engineRootKey = SettingsRegistryInterface::FixedValueString::format("%s/engine_path", BootstrapSettingsRootKey);
// Step 1 Run the scan upwards logic once to find the location of the engine.json if it exist
// Once this step is run the {InternalScanUpEngineRootKey} is set in the Settings Registry
// to have this scan logic only run once InternalScanUpEngineRootKey the supplied registry
if (settingsRegistry.GetType(InternalScanUpEngineRootKey) == SettingsRegistryInterface::Type::NoType)
{
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
engineRoot = Internal::ScanUpRootLocator("engine.json");
// Set the {InternalScanUpEngineRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpEngineRootKey, engineRoot.Native());
if (!engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.Native());
// Inject the engine root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
return engineRoot;
}
}
// Step 2 check if the engine_path key has been supplied
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
{
return engineRoot;
}
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
if (engineRoot = Internal::ScanUpRootLocator("engine.json"); !engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
return engineRoot;
}
// Step 3 locate the project root and attempt to find the engine root using the registered engine
// for the project in the project.json file
AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
if (projectRoot.empty())
{
@@ -207,16 +230,30 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry)
{
AZ::IO::FixedMaxPath projectRoot;
// This is the 'external' project root key, as in passed from command-line or .setreg files.
auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
const auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
// Step 1 Run the scan upwards logic once to find the location of the project.json if it exist
// Once this step is run the {InternalScanUpProjectRootKey} is set in the Settings Registry
// to have this scan logic only run once for the supplied registry
// SettingsRegistryInterface::GetType is used to check if a key is set
if (settingsRegistry.GetType(InternalScanUpProjectRootKey) == SettingsRegistryInterface::Type::NoType)
{
return projectRoot;
projectRoot = Internal::ScanUpRootLocator("project.json");
// Set the {InternalScanUpProjectRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpProjectRootKey, projectRoot.Native());
if (!projectRoot.empty())
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
// Inject the project root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
return projectRoot;
}
}
if (projectRoot = Internal::ScanUpRootLocator("project.json"); !projectRoot.empty())
// Step 2 Check the project-path key
// This is the project path root key, as in passed from command-line or .setreg files.
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
return projectRoot;
}
@@ -463,24 +500,13 @@ namespace AZ::SettingsRegistryMergeUtils
void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry)
{
ConfigParserSettings parserSettings;
parserSettings.m_commentPrefixFunc = [](AZStd::string_view line) -> AZStd::string_view
{
constexpr AZStd::string_view commentPrefixes[]{ "--", ";","#" };
for (AZStd::string_view commentPrefix : commentPrefixes)
{
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
{
return line.substr(0, commentOffset);
}
}
return line;
};
parserSettings.m_registryRootPointerPath = BootstrapSettingsRootKey;
MergeSettingsToRegistry_ConfigFile(registry, "bootstrap.cfg", parserSettings);
}
void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry)
{
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// Binary folder
AZ::IO::FixedMaxPath path = AZ::Utils::GetExecutableDirectory();
registry.Set(FilePathKey_BinaryFolder, path.LexicallyNormal().Native());
@@ -489,27 +515,25 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath engineRoot = FindEngineRoot(registry);
registry.Set(FilePathKey_EngineRootFolder, engineRoot.LexicallyNormal().Native());
constexpr size_t bufferSize = 64;
auto buffer = AZStd::fixed_string<bufferSize>::format("%s/project_path", BootstrapSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString projectPathKey(buffer);
auto projectPathKey = FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
SettingsRegistryInterface::FixedValueString projectPathValue;
if (registry.Get(projectPathValue, projectPathKey))
{
// Cache folder
// Get the name of the asset platform assigned by the bootstrap. First check for platform version such as "windows_assets"
// and if that's missing just get "assets".
constexpr char platformName[] = AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER;
SettingsRegistryInterface::FixedValueString assetPlatform;
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
AZStd::string_view assetPlatformKey(buffer);
if (!registry.Get(assetPlatform, assetPlatformKey))
FixedValueString assetPlatform;
if (auto assetPlatformKey = FixedValueString::format("%s/%s_assets", BootstrapSettingsRootKey, AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER);
!registry.Get(assetPlatform, assetPlatformKey))
{
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
assetPlatformKey = AZStd::string_view(buffer);
assetPlatformKey = FixedValueString::format("%s/assets", BootstrapSettingsRootKey);
registry.Get(assetPlatform, assetPlatformKey);
}
if (assetPlatform.empty())
{
// Use the platform codename to retrieve the default asset platform value
assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
}
// Project path - corresponds to the @devassets@ alias
// NOTE: Here we append to engineRoot, but if projectPathValue is absolute then engineRoot is discarded.
@@ -549,8 +573,7 @@ namespace AZ::SettingsRegistryMergeUtils
{
// Cache: project root - no corresponding fileIO alias, but this is where the asset database lives.
// A registry override is accepted using the "project_cache_path" key.
buffer = AZStd::fixed_string<bufferSize>::format("%s/project_cache_path", BootstrapSettingsRootKey);
AZStd::string_view projectCacheRootOverrideKey(buffer);
auto projectCacheRootOverrideKey = FixedValueString::format("%s/project_cache_path", BootstrapSettingsRootKey);
// Clear path to make sure that the `project_cache_path` value isn't concatenated to the project path
path.clear();
if (registry.Get(path.Native(), projectCacheRootOverrideKey))
@@ -576,14 +599,32 @@ namespace AZ::SettingsRegistryMergeUtils
aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
}
#if !AZ_TRAIT_USE_ASSET_CACHE_FOLDER
// Setup the cache and user paths for Platforms where the Asset Cache Folder isn't used
#if !AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
// Setup the cache and user paths when to platform specific locations when running on non-host platforms
path = engineRoot;
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
#endif // AZ_TRAIT_USE_ASSET_CACHE_FOLDER
if (AZStd::optional<AZ::IO::FixedMaxPathString> nonHostCacheRoot = Utils::GetDefaultAppRootPath();
nonHostCacheRoot)
{
registry.Set(FilePathKey_CacheProjectRootFolder, *nonHostCacheRoot);
registry.Set(FilePathKey_CacheRootFolder, *nonHostCacheRoot);
}
else
{
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
}
if (AZStd::optional<AZ::IO::FixedMaxPathString> devWriteStorage = Utils::GetDevWriteStoragePath();
devWriteStorage)
{
registry.Set(FilePathKey_DevWriteStorage, *devWriteStorage);
registry.Set(FilePathKey_ProjectUserPath, *devWriteStorage);
}
else
{
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
}
#endif // AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
}
void MergeSettingsToRegistry_TargetBuildDependencyRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
@@ -789,6 +830,11 @@ namespace AZ::SettingsRegistryMergeUtils
++argumentIndex;
commandLinePath.resize(commandLineRootSize);
}
// This key is used allow Notification Handlers to know when the command line has been updated within the
// registry. The value itself is meaningless. The JSON path of {CommandLineValueChangedKey}
// being passed to the Notification Event Handler indicates that the command line has be updated
registry.Set(CommandLineValueChangedKey, true);
}
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
@@ -805,10 +851,16 @@ namespace AZ::SettingsRegistryMergeUtils
}
else if (valueName == "Value" && !value.empty())
{
m_arguments.push_back(value);
// Make sure value types are in quotes in case they start with a command option prefix
m_arguments.push_back(QuoteArgument(value));
}
}
AZStd::string QuoteArgument(AZStd::string_view arg)
{
return !arg.empty() ? AZStd::string::format(R"("%.*s")", aznumeric_cast<int>(arg.size()), arg.data()) : AZStd::string{ arg };
}
// The first parameter is skipped by the ComamndLine::Parse function so initialize
// the container with one empty element
AZ::CommandLine::ParamContainer m_arguments{ 1 };
@@ -986,4 +1038,12 @@ namespace AZ::SettingsRegistryMergeUtils
return visitor.Finalize();
}
bool IsPathAncestorDescendantOrEqual(AZStd::string_view candidatePath, AZStd::string_view inputPath)
{
AZ::IO::PathView candidateView{ candidatePath, AZ::IO::PosixPathSeparator };
AZ::IO::PathView inputView{ inputPath, AZ::IO::PosixPathSeparator };
return inputView.empty() || candidateView.IsRelativeTo(inputView) || inputView.IsRelativeTo(candidateView);
}
}
@@ -57,6 +57,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! Root key for where command line are stored at within the settings registry
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
//! The value of the key has no meaning. Notification Handlers only need to check if the key was supplied
inline static constexpr char CommandLineValueChangedKey[] = "/Amazon/AzCore/Runtime/CommandLineChanged";
//! Root key where raw project settings (project.json) file is merged to settings registry
inline static constexpr char ProjectSettingsRootKey[] = "/Amazon/Project/Settings";
@@ -74,6 +77,20 @@ namespace AZ::SettingsRegistryMergeUtils
//! If it's still not found, attempt to find the project (by similar means) then reconcile the
//! engine root by inspecting project.json and the engine manifest file.
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry);
//! The algorithm that is used to find the project root is as follows
//! 1. The first time this function is it performs a upward scan for a project.json file from
//! the executable directory and if found stores that path to an internal key.
//! In the same step it injects the path into the front of list of command line parameters
//! using the --regset="{BootstrapSettingsRootKey}/project_path=<path>" value
//! 2. Next the "{BootstrapSettingsRootKey}/project_path" is checked to see if it has a project path set
//!
//! The order in which the project path settings are overridden proceeds in the following order
//! 1. project_path set in the <engine-root>/bootstrap.cfg file
//! 2. project_path set in a *.setreg/*.setregpatch file
//! 3. project_path found by scanning upwards from the executable directory to the project.json path
//! 4. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
//! or --project_path=<path>
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
//! Query the specializations that will be used when loading the Settings Registry.
@@ -256,4 +273,22 @@ namespace AZ::SettingsRegistryMergeUtils
aznumeric_cast<int>(keyName.size()), keyName.data());
return registry.Get(result, key);
}
//! Check if the supplied input path is an ancestor, a descendant or exactly equal to the candidate path
//! The can be used to check if a JSON pointer to a settings registry entry has potentially
//! "modified" the object at candidate path or its children in notifications
//! @param candidatePath Path which is being checked for the ancestor/descendant relationship
//! @param inputPath Path which is checked to determine if it is an ancestor or descendant of the candidate path
//! @return true if the input path is an ancestor, descendant or equal to the candidate path
//! Example: input path is ancestor path of candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore") = true
//! Example: input path is equal to candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap") = true
//! Example: input path is descendant of candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap/project_path") = true
//! //! Example: input path is unrelated to candidate path
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/Project/Settings/project_name") = false
//! //! Example: The path "" is the root JSON pointer therefore that is the ancestor of all paths
//! IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "") = true
bool IsPathAncestorDescendantOrEqual(AZStd::string_view candidatePath, AZStd::string_view inputPath);
}
@@ -2900,7 +2900,7 @@ namespace AZ
{
AZ::Data::AssetCatalogRequestBus::BroadcastResult(referencedSliceAssetPath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, slice.GetSliceAsset()->GetId());
}
AZ_Error("Slices", false, "Slice with asset ID %s and path %s has an invalid slice reference to slice with path %s. The Lumberyard editor may be unstable, it is recommended you re-launch the editor.",
AZ_Error("Slices", false, "Slice with asset ID %s and path %s has an invalid slice reference to slice with path %s. The Open 3D Engine editor may be unstable, it is recommended you re-launch the editor.",
!m_myAsset ? "invalid asset" : m_myAsset->GetId().ToString<AZStd::string>().c_str(),
mySliceAssetPath.empty() ? "invalid path" : mySliceAssetPath.c_str(),
referencedSliceAssetPath.empty() ? "invalid path" : referencedSliceAssetPath.c_str());
@@ -769,8 +769,8 @@ namespace AZ
*! This has similar behavior to Python pathlib '/' operator and os.path.join
*! Specifically, that it uses the last absolute path as the anchor for the resulting path
*! https://docs.python.org/3/library/pathlib.html#pathlib.PurePath
*! This means that joining StringFunc::Path::Join("C:\\lumberyard" "F:\\lumberyard") results in "F:\\lumberyard"
*! not "C:\\lumberyard\\F:\\lumberyard"
*! This means that joining StringFunc::Path::Join("C:\\O3DE" "F:\\O3DE") results in "F:\\O3DE"
*! not "C:\\O3DE\\F:\\O3DE"
*! EX: StringFunc::Path::Join("C:\\p4\\game","info\\some.file", a) == true; a== "C:\\p4\\game\\info\\some.file"
*! EX: StringFunc::Path::Join("C:\\p4\\game\\info", "game\\info\\some.file", a) == true; a== "C:\\p4\\game\\info\\game\\info\\some.file"
*! EX: StringFunc::Path::Join("C:\\p4\\game\\info", "\\game\\info\\some.file", a) == true; a== "C:\\game\\info\\some.file"
@@ -0,0 +1,59 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/UnitTest/UnitTest.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <gmock/gmock.h>
namespace AZ
{
class MockSettingsRegistry;
using NiceSettingsRegistrySimpleMock = ::testing::NiceMock<MockSettingsRegistry>;
class MockSettingsRegistry
: public AZ::SettingsRegistryInterface
{
public:
MOCK_CONST_METHOD1(GetType, Type(AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(Visitor&, AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(u64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(double&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(AZStd::string&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(FixedValueString&, AZStd::string_view));
MOCK_CONST_METHOD3(GetObject, bool(void*, Uuid, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, bool));
MOCK_METHOD2(Set, bool(AZStd::string_view, s64));
MOCK_METHOD2(Set, bool(AZStd::string_view, u64));
MOCK_METHOD2(Set, bool(AZStd::string_view, double));
MOCK_METHOD2(Set, bool(AZStd::string_view, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, const char*));
MOCK_METHOD3(SetObject, bool(AZStd::string_view, const void*, Uuid));
MOCK_METHOD1(Remove, bool(AZStd::string_view));
MOCK_METHOD3(MergeCommandLineArgument, bool(AZStd::string_view, AZStd::string_view, const CommandLineArgumentSettings&));
MOCK_METHOD2(MergeSettings, bool(AZStd::string_view, Format));
MOCK_METHOD4(MergeSettingsFile, bool(AZStd::string_view, Format, AZStd::string_view, AZStd::vector<char>*));
MOCK_METHOD5(
MergeSettingsFolder,
bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector<char>*));
};
} // namespace AZ
@@ -278,7 +278,7 @@ namespace UnitTest
#define AZ_TEST_STATIC_ASSERT(_Exp) static_assert(_Exp, "Test Static Assert")
#ifdef AZ_ENABLE_TRACING
/*
* The AZ_TEST_START_ASSERTTEST and AZ_TEST_STOP_ASSERTTEST macros have been deprecated and will be removed in a future Lumberyard release.
* The AZ_TEST_START_ASSERTTEST and AZ_TEST_STOP_ASSERTTEST macros have been deprecated and will be removed in a future Open 3D Engine release.
* The AZ_TEST_START_TRACE_SUPPRESSION and AZ_TEST_STOP_TRACE_SUPPRESSION is the recommend macros
* The reason for the deprecation is that the AZ_TEST_(START|STOP)_ASSERTTEST implies that they should be used to for writing assert unit test
* where the asserts themselves are expected to cause the test process to terminate.
@@ -505,6 +505,8 @@ set(FILES
Serialization/Json/BasicContainerSerializer.cpp
Serialization/Json/BoolSerializer.h
Serialization/Json/BoolSerializer.cpp
Serialization/Json/ByteStreamSerializer.h
Serialization/Json/ByteStreamSerializer.cpp
Serialization/Json/CastingHelpers.h
Serialization/Json/DoubleSerializer.h
Serialization/Json/DoubleSerializer.cpp
@@ -605,6 +607,8 @@ set(FILES
Utils/Utils.h
Script/lua/lua.h
Memory/HeapSchema.cpp
PlatformId/PlatformDefaults.h
PlatformId/PlatformDefaults.cpp
PlatformId/PlatformId.h
PlatformId/PlatformId.cpp
Socket/AzSocket_fwd.h
@@ -15,4 +15,5 @@ set(FILES
UnitTest/UnitTest.h
UnitTest/TestTypes.h
UnitTest/Mocks/MockFileIOBase.h
UnitTest/Mocks/MockSettingsRegistry.h
)
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -193,7 +193,7 @@ namespace Platform::Internal
void FindFilesInApk(const char* filter, const SystemFile::FindFileCB& cb)
{
// Separate the directory from the filename portion of the filter
AZ::IO::PathView filterPath(AZ::Android::Utils::StripApkPrefix(filter));
AZ::IO::FixedMaxPath filterPath(AZ::Android::Utils::StripApkPrefix(filter));
AZ::IO::FixedMaxPathString filterDir{ filterPath.ParentPath().Native() };
AZStd::string_view fileFilter{ filterPath.Filename().Native() };
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -105,7 +105,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 1
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 0
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1
@@ -106,7 +106,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
#define AZ_TRAIT_USE_ASSET_CACHE_FOLDER 0
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
@@ -90,7 +90,7 @@ namespace UnitTest
TEST_F(OptionalFixture, ConstructorInPlaceWithInitializerList)
{
const optional<ConstructibleWithInitializerListClass> opt(in_place, {"Lumberyard"}, 4);
const optional<ConstructibleWithInitializerListClass> opt(in_place, {"O3DE"}, 4);
EXPECT_TRUE(bool(opt)) << "optional constructed with args should be true";
}
+2 -4
View File
@@ -1081,13 +1081,11 @@ namespace UnitTest
AZStd::string filePath;
if (providerId == UserSettings::CT_GLOBAL)
{
filePath.append(static_cast<AZStd::string_view>(m_exeDirectory));
filePath.append("GlobalUserSettings.xml");
filePath = (m_exeDirectory / "GlobalUserSettings.xml").String();
}
else if (providerId == UserSettings::CT_LOCAL)
{
filePath.append(static_cast<AZStd::string_view>(m_exeDirectory));
filePath.append("LocalUserSettings.xml");
filePath = (m_exeDirectory / "LocalUserSettings.xml").String();
}
return filePath;
}
@@ -547,7 +547,7 @@ namespace UnitTest
PathLexicallyNormalParams{ '/', "foo/./bar/..", "foo" },
PathLexicallyNormalParams{ '/', "foo/.///bar/../", "foo" },
PathLexicallyNormalParams{ '/', R"(/foo\./bar\..\)", "/foo" },
PathLexicallyNormalParams{ '\\', R"(C:/lumberyard/dev/Cache\game/../pc)", R"(C:\lumberyard\dev\Cache\pc)" }
PathLexicallyNormalParams{ '\\', R"(C:/O3DE/dev/Cache\game/../pc)", R"(C:\O3DE\dev\Cache\pc)" }
)
);
@@ -756,13 +756,13 @@ namespace UnitTest
PathPrefixParams{ "C:\\foo\\", "C:\\foo", true },
PathPrefixParams{ "C:", "C:\\foo", true },
PathPrefixParams{ "D:\\", "C:\\foo", false },
PathPrefixParams{ "/lumberyard/dev/", "/lumberyard/dev", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/", true },
PathPrefixParams{ "/lumberyard/dev/", "/lumberyard/dev/Cache", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/Cache", true },
PathPrefixParams{ "/lumberyard/dev", "/lumberyard/dev/Cache/", true },
PathPrefixParams{ "lumberyard/dev/", "lumberyard/dev/Cache/", true },
PathPrefixParams{ "lumberyard\\dev/Assets", "lumberyard/dev/Cache/", false }
PathPrefixParams{ "/O3DE/dev/", "/O3DE/dev", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/", true },
PathPrefixParams{ "/O3DE/dev/", "/O3DE/dev/Cache", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/Cache", true },
PathPrefixParams{ "/O3DE/dev", "/O3DE/dev/Cache/", true },
PathPrefixParams{ "O3DE/dev/", "O3DE/dev/Cache/", true },
PathPrefixParams{ "O3DE\\dev/Assets", "O3DE/dev/Cache/", false }
));
struct PathDecompositionParams
@@ -854,7 +854,7 @@ namespace Benchmark
}
protected:
AZStd::fixed_vector<const char*, 20> m_appendPaths{ "foo", "bar", "baz", "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"boo/bar/base", "C:\\path\\to\\lumberyard", "C", "\\\\", "/", R"(test\\path/with\mixed\separators)" };
"boo/bar/base", "C:\\path\\to\\O3DE", "C", "\\\\", "/", R"(test\\path/with\mixed\separators)" };
};
BENCHMARK_F(PathBenchmarkFixture, BM_PathAppendFixedPath)(benchmark::State& state)
@@ -56,6 +56,16 @@ namespace UnitTest
EXPECT_THAT(obb.GetAxisZ(), IsClose(Vector3(1.0f, 0.0f, 0.0f)));
}
TEST(MATH_Obb, TestScaleTransform)
{
Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
Vector3 scaleFactors = Vector3(1.0f, 2.0f, 3.0f);
Transform transform = Transform::CreateScale(scaleFactors);
obb = transform * obb;
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(1.0f, 4.0f, 9.0f)));
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(0.5f, 1.0f, 1.5f)));
}
TEST(MATH_Obb, TestSetPosition)
{
Obb obb;
@@ -0,0 +1,59 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
namespace JsonSerializationTests
{
class ByteStreamSerializerTestDescription : public JsonSerializerConformityTestDescriptor<AZ::JsonByteStream>
{
public:
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
{
return AZStd::make_shared<AZ::JsonByteStreamSerializer>();
}
AZStd::shared_ptr<AZ::JsonByteStream> CreateDefaultInstance() override
{
return AZStd::make_shared<AZ::JsonByteStream>();
}
AZStd::shared_ptr<AZ::JsonByteStream> CreateFullySetInstance() override
{
// create a JsonByteStream (AZStd::vector<u8>) with ten 'a's
return AZStd::make_shared<AZ::JsonByteStream>(10, 'a');
}
AZStd::string_view GetJsonForFullySetInstance() override
{
// Base64 encoded version of 'aaaaaaaaaa' (see CreateFullySetInstance)
return R"("YWFhYWFhYWFhYQ==")";
}
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
{
features.EnableJsonType(rapidjson::kStringType);
features.m_supportsPartialInitialization = false;
features.m_supportsInjection = false;
}
bool AreEqual(const AZ::JsonByteStream& lhs, const AZ::JsonByteStream& rhs) override
{
return lhs == rhs;
}
};
using ByteStreamConformityTestTypes = ::testing::Types<ByteStreamSerializerTestDescription>;
INSTANTIATE_TYPED_TEST_CASE_P(JsonByteStreamSerialzier, JsonSerializerConformityTests, ByteStreamConformityTestTypes);
} // namespace JsonSerializationTests
@@ -93,8 +93,10 @@ namespace JsonSerializationTests
TEST_F(JsonSerializationMetadataTests, Add_MoveDuplicateValue_ReturnsFalse)
{
AZ_TEST_START_TRACE_SUPPRESSION;
m_metadata->Add(TestSettingsA{ 42 });
EXPECT_FALSE(m_metadata->Add(TestSettingsA{ 88 }));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(JsonSerializationMetadataTests, Add_CopyNewValue_ReturnsTrue)
@@ -119,11 +121,13 @@ namespace JsonSerializationTests
TEST_F(JsonSerializationMetadataTests, Find_MultipleValues_ReturnsFirstValue)
{
m_metadata->Add(TestSettingsA{ 42 });
AZ_TEST_START_TRACE_SUPPRESSION;
m_metadata->Add(TestSettingsA{42});
m_metadata->Add(TestSettingsA{ 88 });
TestSettingsA* value = m_metadata->Find<TestSettingsA>();
ASSERT_NE(nullptr, value);
EXPECT_EQ(42, value->m_number);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(JsonSerializationMetadataTests, FindConst_PreviouslyAddedValue_ReturnsConstPointer)
@@ -542,4 +542,14 @@ tags=tools,renderer,metal)"
EXPECT_STREQ("Foo", commandLine.GetMiscValue(1).c_str());
EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str());
}
using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture;
TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds)
{
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore"));
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap"));
EXPECT_TRUE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/AzCore/Bootstrap/project_path"));
EXPECT_FALSE(AZ::SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual("/Amazon/AzCore/Bootstrap", "/Amazon/Project/Settings/project_name"));
}
}
@@ -98,6 +98,7 @@ set(FILES
Serialization/Json/BaseJsonSerializerTests.cpp
Serialization/Json/BasicContainerSerializerTests.cpp
Serialization/Json/BoolSerializerTests.cpp
Serialization/Json/ByteStreamSerializerTests.cpp
Serialization/Json/ColorSerializerTests.cpp
Serialization/Json/DoubleSerializerTests.cpp
Serialization/Json/IntSerializerTests.cpp

Some files were not shown because too many files have changed in this diff Show More