Merge remote-tracking branch 'upstream/development' into nvsickle/GenericDomDocument

This commit is contained in:
Nicholas Van Sickle
2022-01-04 15:41:17 -08:00
464 changed files with 23577 additions and 10203 deletions
@@ -484,6 +484,7 @@ namespace AZ::IO
// as_posix
//! Replicates the behavior of the Python pathlib as_posix method
//! by replacing the Windows Path Separator with the Posix Path Seperator
constexpr string_type AsPosix() const;
AZStd::string StringAsPosix() const;
constexpr AZStd::fixed_string<MaxPathLength> FixedMaxPathStringAsPosix() const noexcept;
@@ -1043,6 +1043,13 @@ namespace AZ::IO
// as_posix
// Returns a copy of the path with the path separators converted to PosixPathSeparator
template <typename StringType>
constexpr auto BasicPath<StringType>::AsPosix() const -> string_type
{
string_type resultPath(m_path.begin(), m_path.end());
AZStd::replace(resultPath.begin(), resultPath.end(), WindowsPathSeparator, PosixPathSeparator);
return resultPath;
}
template <typename StringType>
AZStd::string BasicPath<StringType>::StringAsPosix() const
{
AZStd::string resultPath(m_path.begin(), m_path.end());
@@ -7,6 +7,8 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/functional.h>
@@ -35,10 +37,8 @@ namespace AZ::IO
size_t Save(const void* classPtr, IO::GenericStream& stream, bool) override
{
/// Save paths out using the PosixPathSeparator
PathType path(reinterpret_cast<const PathType*>(classPtr)->Native(), AZ::IO::PosixPathSeparator);
path.MakePreferred();
return static_cast<size_t>(stream.Write(path.Native().size(), path.c_str()));
auto posixPathString{ reinterpret_cast<const PathType*>(classPtr)->AsPosix() };
return static_cast<size_t>(stream.Write(posixPathString.size(), posixPathString.c_str()));
}
bool Load(void* classPtr, IO::GenericStream& stream, unsigned int, bool) override
@@ -73,5 +73,11 @@ namespace AZ::IO
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
;
}
else if (auto jsonContext = azrtti_cast<JsonRegistrationContext*>(context))
{
jsonContext->Serializer<JsonPathSerializer>()
->HandlesType<Path>()
->HandlesType<FixedMaxPath>();
}
}
}
@@ -109,6 +109,7 @@ namespace AZ
*/
static EnvironmentVariable<T*> s_instance;
static AZStd::shared_mutex s_mutex;
static bool s_instanceAssigned;
};
template <typename T>
@@ -117,6 +118,9 @@ namespace AZ
template <typename T>
AZStd::shared_mutex Interface<T>::s_mutex;
template <typename T>
bool Interface<T>::s_instanceAssigned;
template <typename T>
void Interface<T>::Register(T* type)
{
@@ -135,18 +139,19 @@ namespace AZ
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
s_instance = Environment::CreateVariable<T*>(GetVariableName());
s_instance.Get() = type;
s_instanceAssigned = true;
}
template <typename T>
void Interface<T>::Unregister(T* type)
{
if (!s_instance || !s_instance.Get())
if (!s_instanceAssigned)
{
AZ_Assert(false, "Interface '%s' not registered on this module!", AzTypeInfo<T>::Name());
return;
}
if (s_instance.Get() != type)
if (s_instance && s_instance.Get() != type)
{
AZ_Assert(false, "Interface '%s' is not the same instance that was registered! [Expected '%p', Found '%p']", AzTypeInfo<T>::Name(), type, s_instance.Get());
return;
@@ -156,6 +161,7 @@ namespace AZ
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
*s_instance = nullptr;
s_instance.Reset();
s_instanceAssigned = false;
}
template <typename T>
@@ -165,9 +171,9 @@ namespace AZ
// This is the fast path which won't block.
{
AZStd::shared_lock<AZStd::shared_mutex> lock(s_mutex);
if (s_instance)
if (s_instanceAssigned)
{
return s_instance.Get();
return s_instance ? s_instance.Get() : nullptr;
}
}
@@ -175,6 +181,7 @@ namespace AZ
// take the full lock and request it.
AZStd::unique_lock<AZStd::shared_mutex> lock(s_mutex);
s_instance = Environment::FindVariable<T*>(GetVariableName());
s_instanceAssigned = true;
return s_instance ? s_instance.Get() : nullptr;
}
File diff suppressed because it is too large Load Diff
@@ -19,12 +19,14 @@ namespace AZ
AZ_MATH_INLINE Plane Plane::CreateFromNormalAndPoint(const Vector3& normal, const Vector3& point)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
return Plane(Simd::Vec4::ConstructPlane(normal.GetSimdValue(), point.GetSimdValue()));
}
AZ_MATH_INLINE Plane Plane::CreateFromNormalAndDistance(const Vector3& normal, float dist)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
Plane result;
result.Set(normal, dist);
return result;
@@ -33,6 +35,7 @@ namespace AZ
AZ_MATH_INLINE Plane Plane::CreateFromCoefficients(const float a, const float b, const float c, const float d)
{
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
Plane result;
result.Set(a, b, c, d);
return result;
@@ -65,18 +68,21 @@ namespace AZ
AZ_MATH_INLINE void Plane::Set(const Vector3& normal, float d)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
m_plane.Set(normal, d);
}
AZ_MATH_INLINE void Plane::Set(float a, float b, float c, float d)
{
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
m_plane.Set(a, b, c, d);
}
AZ_MATH_INLINE void Plane::SetNormal(const Vector3& normal)
{
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
m_plane.SetX(normal.GetX());
m_plane.SetY(normal.GetY());
m_plane.SetZ(normal.GetZ());
+12 -4
View File
@@ -54,11 +54,11 @@ namespace AZ
//! Sets components using a Vector3 for the imaginary part and a float for the real part.
static Quaternion CreateFromVector3AndValue(const Vector3& v, float w);
//! Sets the quaternion to be a rotation around a specified axis.
//! Sets the quaternion to be a rotation around a specified axis in radians.
//! @{
static Quaternion CreateRotationX(float angle);
static Quaternion CreateRotationY(float angle);
static Quaternion CreateRotationZ(float angle);
static Quaternion CreateRotationX(float angleInRadians);
static Quaternion CreateRotationY(float angleInRadians);
static Quaternion CreateRotationZ(float angleInRadians);
//! @}
//! Creates a quaternion from a Matrix3x3
@@ -168,6 +168,14 @@ namespace AZ
float NormalizeWithLengthEstimate();
//! @}
//! Get the shortest equivalent of the rotation.
//! In case the w component of the quaternion is negative the rotation is > 180° and taking the longer path.
//! The quaternion will be inverted in that case to take the shortest path of rotation.
//! @{
Quaternion GetShortestEquivalent() const;
void ShortestEquivalent();
//! @}
//! Linearly interpolate towards a destination quaternion.
//! @param[in] dest The quaternion to interpolate towards.
//! @param[in] t Normalized interpolation value where 0.0 represents the current and 1.0 the destination value.
@@ -73,27 +73,27 @@ namespace AZ
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationX(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationX(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(sin, 0.0f, 0.0f, cos);
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationY(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationY(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(0.0f, sin, 0.0f, cos);
}
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationZ(float angle)
AZ_MATH_INLINE Quaternion Quaternion::CreateRotationZ(float angleInRadians)
{
const float halfAngle = 0.5f * angle;
const float halfAngle = 0.5f * angleInRadians;
float sin, cos;
SinCos(halfAngle, sin, cos);
return Quaternion(0.0f, 0.0f, sin, cos);
@@ -345,6 +345,23 @@ namespace AZ
}
AZ_MATH_INLINE Quaternion Quaternion::GetShortestEquivalent() const
{
if (GetW() < 0.0f)
{
return -(*this);
}
return *this;
}
AZ_MATH_INLINE void Quaternion::ShortestEquivalent()
{
*this = GetShortestEquivalent();
}
AZ_MATH_INLINE Quaternion Quaternion::Lerp(const Quaternion& dest, float t) const
{
if (Dot(dest) >= 0.0f)
+269 -275
View File
@@ -9,39 +9,38 @@
#include <AzCore/Math/Sfmt.h>
#include <AzCore/Math/Random.h>
#include <AzCore/std/parallel/lock.h>
#include <AzCore/Module/Environment.h>
#include <AzCore/std/parallel/lock.h>
#include <string.h> // for memset
namespace AZ::SfmtInternal
{
static const int N32 = N * 4;
static const int N64 = N * 2;
static const int POS1 = 122;
static const int SL1 = 18;
static const int SR1 = 11;
static const int SL2 = 1;
static const int SR2 = 1;
static const unsigned int MSK1 = 0xdfffffefU;
static const unsigned int MSK2 = 0xddfecb7fU;
static const unsigned int MSK3 = 0xbffaffffU;
static const unsigned int MSK4 = 0xbffffff6U;
static const unsigned int PARITY1 = 0x00000001U;
static const unsigned int PARITY2 = 0x00000000U;
static const unsigned int PARITY3 = 0x00000000U;
static const unsigned int PARITY4 = 0x13c9e684U;
static const int N32 = N * 4;
static const int N64 = N * 2;
static const int POS1 = 122;
static const int SL1 = 18;
static const int SR1 = 11;
static const int SL2 = 1;
static const int SR2 = 1;
static const unsigned int MSK1 = 0xdfffffefU;
static const unsigned int MSK2 = 0xddfecb7fU;
static const unsigned int MSK3 = 0xbffaffffU;
static const unsigned int MSK4 = 0xbffffff6U;
static const unsigned int PARITY1 = 0x00000001U;
static const unsigned int PARITY2 = 0x00000000U;
static const unsigned int PARITY3 = 0x00000000U;
static const unsigned int PARITY4 = 0x13c9e684U;
/** a parity check vector which certificate the period of 2^{MEXP} */
static unsigned int parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
static unsigned int parity[4] = { PARITY1, PARITY2, PARITY3, PARITY4 };
#ifdef ONLY64
# define idxof(_i) (_i ^ 1)
#define idxof(_i) (_i ^ 1)
#else
# define idxof(_i) _i
#define idxof(_i) _i
#endif // ONLY64
#if AZ_TRAIT_USE_PLATFORM_SIMD_SSE
/**
* This function represents the recursion formula.
@@ -52,7 +51,8 @@ namespace AZ::SfmtInternal
* @param mask 128-bit mask
* @return output
*/
AZ_FORCE_INLINE static Simd::Vec4::Int32Type simd_recursion(Simd::Vec4::Int32Type* a, Simd::Vec4::Int32Type* b, Simd::Vec4::Int32Type c, Simd::Vec4::Int32Type d, Simd::Vec4::Int32Type mask)
AZ_FORCE_INLINE static Simd::Vec4::Int32Type simd_recursion(
Simd::Vec4::Int32Type* a, Simd::Vec4::Int32Type* b, Simd::Vec4::Int32Type c, Simd::Vec4::Int32Type d, Simd::Vec4::Int32Type mask)
{
Simd::Vec4::Int32Type v, x, y, z;
x = *a;
@@ -151,7 +151,7 @@ namespace AZ::SfmtInternal
inline void rshift128(w128_t* out, w128_t const* in, int shift)
{
AZ::u64 th, tl, oh, ol;
#ifdef ONLY64
#ifdef ONLY64
th = ((AZ::u64)in->u[2] << 32) | ((AZ::u64)in->u[3]);
tl = ((AZ::u64)in->u[0] << 32) | ((AZ::u64)in->u[1]);
@@ -204,7 +204,7 @@ namespace AZ::SfmtInternal
#endif
}
inline void do_recursion(w128_t* r, w128_t* a, w128_t* b, w128_t* c, w128_t* d)
inline void do_recursion(w128_t* r, w128_t* a, w128_t* b, w128_t* c, w128_t* d)
{
w128_t x;
w128_t y;
@@ -229,7 +229,7 @@ namespace AZ::SfmtInternal
inline void gen_rand_all(Sfmt& g)
{
int i;
w128_t* r1, * r2;
w128_t *r1, *r2;
r1 = &g.m_sfmt[N - 2];
r2 = &g.m_sfmt[N - 1];
@@ -257,7 +257,7 @@ namespace AZ::SfmtInternal
inline void gen_rand_array(Sfmt& g, w128_t* array, int size)
{
int i, j;
w128_t* r1, * r2;
w128_t *r1, *r2;
r1 = &g.m_sfmt[N - 2];
r2 = &g.m_sfmt[N - 1];
@@ -295,82 +295,80 @@ namespace AZ::SfmtInternal
#endif
} // namespace AZ::SfmtInternal
using namespace AZ;
//////////////////////////////////////////////////////////////////////////
// Statics
//////////////////////////////////////////////////////////////////////////
static EnvironmentVariable<AZ::Sfmt> s_sfmt;
static const char* s_globalSfmtName = "GlobalSfmt";
Sfmt& Sfmt::GetInstance()
namespace AZ
{
if (!s_sfmt)
static EnvironmentVariable<AZ::Sfmt> s_sfmt;
static const char* s_globalSfmtName = "GlobalSfmt";
Sfmt& Sfmt::GetInstance()
{
s_sfmt = AZ::Environment::FindVariable<Sfmt>(s_globalSfmtName);
if (!s_sfmt)
{
Sfmt::Create();
s_sfmt = AZ::Environment::FindVariable<Sfmt>(s_globalSfmtName);
if (!s_sfmt)
{
Sfmt::Create();
}
}
return s_sfmt.Get();
}
void Sfmt::Create()
{
if (!s_sfmt)
{
s_sfmt = AZ::Environment::CreateVariable<AZ::Sfmt>(s_globalSfmtName);
}
}
return s_sfmt.Get();
}
void Sfmt::Create()
{
if (!s_sfmt)
void Sfmt::Destroy()
{
s_sfmt = AZ::Environment::CreateVariable<AZ::Sfmt>(s_globalSfmtName);
s_sfmt.Reset();
}
}
void Sfmt::Destroy()
{
s_sfmt.Reset();
}
//=========================================================================
// Sfmt
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt()
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
//=========================================================================
// Sfmt
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt()
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
Seed();
}
Seed();
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt(AZ::u32* keys, int numKeys)
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
Sfmt::Sfmt(AZ::u32* keys, int numKeys)
{
m_psfmt32 = &m_sfmt[0].u[0];
m_psfmt64 = reinterpret_cast<AZ::u64*>(m_psfmt32);
Seed(keys, numKeys);
}
Seed(keys, numKeys);
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void
Sfmt::Seed()
{
// buffer with random values
AZ::u32 buffer[32];
BetterPseudoRandom rnd;
bool result = rnd.GetRandom(buffer, sizeof(buffer));
(void)result;
AZ_Warning("System", result, "Failed to seed properly the Smft generator!");
Seed(buffer, AZ_ARRAY_SIZE(buffer));
}
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void Sfmt::Seed()
{
// buffer with random values
AZ::u32 buffer[32];
BetterPseudoRandom rnd;
bool result = rnd.GetRandom(buffer, sizeof(buffer));
(void)result;
AZ_Warning("System", result, "Failed to seed properly the Smft generator!");
Seed(buffer, AZ_ARRAY_SIZE(buffer));
}
/**
* This function represents a function used in the initialization
@@ -388,226 +386,222 @@ Sfmt::Seed()
*/
#define azsfmt_func2(x) ((x ^ (x >> 27)) * (AZ::u32)1566083941UL)
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void
Sfmt::Seed(AZ::u32* keys, int numKeys)
{
using SfmtInternal::N;
using SfmtInternal::N32;
int i, j, count;
AZ::u32 r;
int lag;
int mid;
int size = N * 4;
//=========================================================================
// Seed
// [4/10/2012]
//=========================================================================
void Sfmt::Seed(AZ::u32* keys, int numKeys)
{
using SfmtInternal::N;
using SfmtInternal::N32;
int i, j, count;
AZ::u32 r;
int lag;
int mid;
int size = N * 4;
if (size >= 623)
{
lag = 11;
}
else if (size >= 68)
{
lag = 7;
}
else if (size >= 39)
{
lag = 5;
}
else
{
lag = 3;
}
mid = (size - lag) / 2;
if (size >= 623)
{
lag = 11;
}
else if (size >= 68)
{
lag = 7;
}
else if (size >= 39)
{
lag = 5;
}
else
{
lag = 3;
}
mid = (size - lag) / 2;
memset(m_sfmt, 0x8b, sizeof(m_sfmt));
if (numKeys + 1 > SfmtInternal::N32)
{
count = numKeys + 1;
}
else
{
count = N32;
}
r = azsfmt_func1((m_psfmt32[idxof(0)] ^ m_psfmt32[idxof(mid)] ^ m_psfmt32[idxof(N32 - 1)]));
m_psfmt32[idxof(mid)] += r;
r += numKeys;
m_psfmt32[idxof(mid + lag)] += r;
m_psfmt32[idxof(0)] = r;
memset(m_sfmt, 0x8b, sizeof(m_sfmt));
if (numKeys + 1 > SfmtInternal::N32)
{
count = numKeys + 1;
}
else
{
count = N32;
}
r = azsfmt_func1((m_psfmt32[idxof(0)] ^ m_psfmt32[idxof(mid)] ^ m_psfmt32[idxof(N32 - 1)]));
m_psfmt32[idxof(mid)] += r;
r += numKeys;
m_psfmt32[idxof(mid + lag)] += r;
m_psfmt32[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < numKeys); j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += keys[j] + i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (; j < count; j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (j = 0; j < N32; j++)
{
r = azsfmt_func2((m_psfmt32[idxof(i)] + m_psfmt32[idxof((i + mid) % N32)] + m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] ^= r;
r -= i;
m_psfmt32[idxof((i + mid + lag) % N32)] ^= r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
count--;
for (i = 1, j = 0; (j < count) && (j < numKeys); j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += keys[j] + i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (; j < count; j++)
{
r = azsfmt_func1((m_psfmt32[idxof(i)] ^ m_psfmt32[idxof((i + mid) % N32)] ^ m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] += r;
r += i;
m_psfmt32[idxof((i + mid + lag) % N32)] += r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (j = 0; j < N32; j++)
{
r = azsfmt_func2((m_psfmt32[idxof(i)] + m_psfmt32[idxof((i + mid) % N32)] + m_psfmt32[idxof((i + N32 - 1) % N32)]));
m_psfmt32[idxof((i + mid) % N32)] ^= r;
r -= i;
m_psfmt32[idxof((i + mid + lag) % N32)] ^= r;
m_psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
m_index = N32;
PeriodCertification();
}
m_index = N32;
PeriodCertification();
}
#undef azsfmt_func1
#undef azsfmt_func2
//=========================================================================
// PeriodCertification
// [4/10/2012]
//=========================================================================
void
Sfmt::PeriodCertification()
{
int inner = 0;
int i, j;
AZ::u32 work;
//=========================================================================
// PeriodCertification
// [4/10/2012]
//=========================================================================
void Sfmt::PeriodCertification()
{
int inner = 0;
int i, j;
AZ::u32 work;
for (i = 0; i < 4; i++)
{
inner ^= m_psfmt32[idxof(i)] & SfmtInternal::parity[i];
}
for (i = 16; i > 0; i >>= 1)
{
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1)
{
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++)
{
work = 1;
for (j = 0; j < 32; j++)
for (i = 0; i < 4; i++)
{
if ((work & SfmtInternal::parity[i]) != 0)
inner ^= m_psfmt32[idxof(i)] & SfmtInternal::parity[i];
}
for (i = 16; i > 0; i >>= 1)
{
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1)
{
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++)
{
work = 1;
for (j = 0; j < 32; j++)
{
m_psfmt32[idxof(i)] ^= work;
return;
if ((work & SfmtInternal::parity[i]) != 0)
{
m_psfmt32[idxof(i)] ^= work;
return;
}
work = work << 1;
}
work = work << 1;
}
}
}
//=========================================================================
// Rand32
// [4/10/2012]
//=========================================================================
AZ::u32 Sfmt::Rand32()
{
int index = m_index.fetch_add(1);
if (index >= SfmtInternal::N32)
//=========================================================================
// Rand32
// [4/10/2012]
//=========================================================================
AZ::u32 Sfmt::Rand32()
{
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 1; // compare against the result of fetch_add(1) above
if (m_index.compare_exchange_strong(index, 0))
int index = m_index.fetch_add(1);
if (index >= SfmtInternal::N32)
{
SfmtInternal::gen_rand_all(*this);
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 1; // compare against the result of fetch_add(1) above
if (m_index.compare_exchange_strong(index, 0))
{
SfmtInternal::gen_rand_all(*this);
}
// try again, with the new table
return Rand32();
}
// try again, with the new table
return Rand32();
return m_psfmt32[index];
}
return m_psfmt32[index];
}
//=========================================================================
// Rand64
// [4/10/2012]
//=========================================================================
AZ::u64 Sfmt::Rand64()
{
int index = m_index.fetch_add(2);
if (index >= (SfmtInternal::N32 - 1))
//=========================================================================
// Rand64
// [4/10/2012]
//=========================================================================
AZ::u64 Sfmt::Rand64()
{
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 2; // compare against the result of fetch_add(2) above
if (m_index.compare_exchange_strong(index, 0))
int index = m_index.fetch_add(2);
if (index >= (SfmtInternal::N32 - 1))
{
SfmtInternal::gen_rand_all(*this);
AZStd::lock_guard<decltype(m_generationMutex)> lock(m_generationMutex);
// if this thread is the one that sets m_index to 0, then this thread
// does the generation
index += 2; // compare against the result of fetch_add(2) above
if (m_index.compare_exchange_strong(index, 0))
{
SfmtInternal::gen_rand_all(*this);
}
// try again, with the new table
return Rand64();
}
// try again, with the new table
return Rand64();
AZ::u64 r;
r = m_psfmt64[index / 2];
return r;
}
AZ::u64 r;
r = m_psfmt64[index / 2];
return r;
}
//=========================================================================
// FillArray32
// [4/10/2012]
//=========================================================================
void Sfmt::FillArray32(AZ::u32* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N32, "Size must be bigger than %d GetMinArray32Size()!", SfmtInternal::N32);
//=========================================================================
// FillArray32
// [4/10/2012]
//=========================================================================
void
Sfmt::FillArray32(AZ::u32* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N32, "Size must be bigger than %d GetMinArray32Size()!", SfmtInternal::N32);
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 4);
m_index = SfmtInternal::N32;
}
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 4);
m_index = SfmtInternal::N32;
}
//=========================================================================
// FillArray64
// [4/10/2012]
//=========================================================================
void Sfmt::FillArray64(AZ::u64* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N64, "Size must be bigger than %d GetMinArray64Size()!", SfmtInternal::N64);
//=========================================================================
// FillArray64
// [4/10/2012]
//=========================================================================
void
Sfmt::FillArray64(AZ::u64* array, int size)
{
AZ_MATH_ASSERT(m_index == SfmtInternal::N32, "Invalid m_index! Reinitialize!");
AZ_MATH_ASSERT(size % 4 == 0, "Size must be multiple of 4!");
AZ_MATH_ASSERT(size >= SfmtInternal::N64, "Size must be bigger than %d GetMinArray64Size()!", SfmtInternal::N64);
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 2);
m_index = SfmtInternal::N32;
}
SfmtInternal::gen_rand_array(*this, (SfmtInternal::w128_t*)array, size / 2);
m_index = SfmtInternal::N32;
}
//=========================================================================
// GetMinArray32Size
// [4/10/2012]
//=========================================================================
int Sfmt::GetMinArray32Size() const
{
return SfmtInternal::N32;
}
//=========================================================================
// GetMinArray32Size
// [4/10/2012]
//=========================================================================
int
Sfmt::GetMinArray32Size() const
{
return SfmtInternal::N32;
}
//=========================================================================
// GetMinArray64Size
// [4/10/2012]
//=========================================================================
int Sfmt::GetMinArray64Size() const
{
return SfmtInternal::N64;
}
//=========================================================================
// GetMinArray64Size
// [4/10/2012]
//=========================================================================
int
Sfmt::GetMinArray64Size() const
{
return SfmtInternal::N64;
}
} // namespace AZ
@@ -1424,7 +1424,8 @@ namespace AZ
}
}
using namespace AZ;
namespace AZ
{
#ifndef AZ_USE_CUSTOM_SCRIPT_BIND
@@ -2254,6 +2255,7 @@ LUA_API const Node* lua_getDummyNode()
}
#endif // AZ_USE_CUSTOM_SCRIPT_BIND
} // namespace AZ
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -5825,7 +5827,6 @@ LUA_API const Node* lua_getDummyNode()
AllocatorWrapper<Internal::LuaSystemAllocator> m_luaAllocator;
AZStd::thread::id m_ownerThreadId; // Check if Lua methods (including EBus handlers) are called from background threads.
};
} // namespace AZ
ScriptContext::ScriptContext(ScriptContextId id, IAllocatorAllocate* allocator, lua_State* nativeContext)
{
@@ -6116,5 +6117,6 @@ LUA_API const Node* lua_getDummyNode()
{
return m_impl->ConstructScriptProperty(sdc, valueIndex, name, restrictToPropertyArrays);
}
} // namespace AZ
#undef AZ_DBG_NAME_FIXER
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_CONTEXT_H
#define AZCORE_SCRIPT_CONTEXT_H
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/function/function_fwd.h>
@@ -1032,4 +1031,3 @@ namespace AZ
}
} // namespace AZ
#endif // AZCORE_SCRIPT_CONTEXT_H
@@ -25,10 +25,8 @@ extern "C" {
namespace AZ
{
void LuaHook(lua_State* l, lua_Debug* ar);
}
using namespace AZ;
/**
* A temp class that will override the current script context error handler and store the error (without any messages)
@@ -599,7 +597,7 @@ static ScriptContextDebug::BreakpointId MakeBreakpointId(const char* sourceName,
// LuaHook
// [6/28/2012]
//=========================================================================
void AZ::LuaHook(lua_State* l, lua_Debug* ar)
void LuaHook(lua_State* l, lua_Debug* ar)
{
// Read contexts
lua_rawgeti(l, LUA_REGISTRYINDEX, AZ_LUA_SCRIPT_CONTEXT_REF);
@@ -1543,4 +1541,6 @@ ScriptContextDebug::SetValue(const DebugValue& sourceValue)
return true;
}
} // namespace AZ
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_CONTEXT_DEBUG_H
#define AZCORE_SCRIPT_CONTEXT_DEBUG_H
#pragma once
#include <AzCore/Script/ScriptContext.h>
#include <AzCore/std/functional.h>
@@ -213,6 +212,3 @@ namespace AZ
ScriptContext& m_context;
};
}
#endif // AZCORE_SCRIPT_CONTEXT_DEBUG_H
#pragma once
@@ -31,7 +31,8 @@
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/std/string/conversions.h>
using namespace AZ;
namespace AZ
{
/**
* Script lifecycle:
@@ -44,8 +45,7 @@ using namespace AZ;
* If the script was loaded by a ScriptComponent, Load will be called once reload is complete.
*/
namespace
{
namespace LocalTU_ScriptSystemComponent {
// Called when a module has already been loaded
static int LuaRequireLoadedModule(lua_State* l)
{
@@ -54,8 +54,10 @@ namespace
return 1;
}
}
//=========================================================================
// ScriptSystemComponent
// [5/29/2012]
@@ -479,7 +481,7 @@ int ScriptSystemComponent::DefaultRequireHook(lua_State* lua, ScriptContext* con
scriptIt->second.m_scriptNames.emplace(module);
// Push the value to a closure that will just return it
lua_rawgeti(lua, LUA_REGISTRYINDEX, scriptIt->second.m_tableReference);
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// If asset reference already populated, just return now. Otherwise, capture reference
if (scriptIt->second.m_scriptAsset.GetId().IsValid())
@@ -519,7 +521,7 @@ int ScriptSystemComponent::DefaultRequireHook(lua_State* lua, ScriptContext* con
}
// Push function returning the result
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// Set asset reference on the loaded script
scriptIt = container->m_loadedScripts.find(scriptId.m_guid);
@@ -565,7 +567,7 @@ int ScriptSystemComponent::InMemoryRequireHook(lua_State* lua, ScriptContext* co
scriptIt->second.m_scriptNames.emplace(module);
// Push the value to a closure that will just return it
lua_rawgeti(lua, LUA_REGISTRYINDEX, scriptIt->second.m_tableReference);
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// If asset reference already populated, just return now. Otherwise, capture reference
if (scriptIt->second.m_scriptAsset.GetId().IsValid())
@@ -591,7 +593,7 @@ int ScriptSystemComponent::InMemoryRequireHook(lua_State* lua, ScriptContext* co
}
// Push function returning the result
lua_pushcclosure(lua, LuaRequireLoadedModule, 1);
lua_pushcclosure(lua, LocalTU_ScriptSystemComponent::LuaRequireLoadedModule, 1);
// Set asset reference on the loaded script
scriptIt = container->m_loadedScripts.find(scriptId.m_guid);
@@ -996,4 +998,5 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection)
}
}
} // namespace AZ
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -5,8 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#define AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/Component/TickBus.h>
@@ -182,6 +181,3 @@ namespace AZ
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
};
}
#endif // AZCORE_SCRIPT_SYSTEM_COMPONENT_H
#pragma once
@@ -150,7 +150,7 @@ namespace AZ
{
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
StoreTypeName(classData, context), context.GetJsonAllocator());
StoreTypeName(classData, classData.m_typeId, context), context.GetJsonAllocator());
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
}
return result.Combine(StoreClass(node, object, defaultObject, classData, context));
@@ -531,7 +531,7 @@ namespace AZ
return ResolvePointerResult::ContinueProcessing;
}
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context)
rapidjson::Value JsonSerializer::StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context)
{
rapidjson::Value result;
AZStd::vector<Uuid> ids = context.GetSerializeContext()->FindClassId(Crc32(classData.m_name));
@@ -544,7 +544,7 @@ namespace AZ
// Only write the Uuid for the class if there are multiple classes sharing the same name.
// In this case it wouldn't be enough to determine which class needs to be used. The
// class name is still added as a comment for be friendlier for users to read.
AZStd::string fullName = classData.m_typeId.ToString<AZStd::string>();
AZStd::string fullName = typeId.ToString<AZStd::string>();
fullName += ' ';
fullName += classData.m_name;
result.SetString(fullName.c_str(), aznumeric_caster(fullName.size()), context.GetJsonAllocator());
@@ -560,7 +560,7 @@ namespace AZ
const SerializeContext::ClassData* data = context.GetSerializeContext()->FindClassData(typeId);
if (data)
{
output = JsonSerializer::StoreTypeName(*data, context);
output = JsonSerializer::StoreTypeName(*data, typeId, context);
return context.Report(Tasks::WriteValue, Outcomes::Success, "Type id successfully stored to json value.");
}
else
@@ -580,7 +580,7 @@ namespace AZ
{
rapidjson::Value insertedObject(rapidjson::kObjectType);
insertedObject.AddMember(
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, context),
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, classData.m_typeId, context),
context.GetJsonAllocator());
for (auto& element : output.GetObject())
@@ -79,7 +79,7 @@ namespace AZ
const void*& object, const void*& defaultObject, AZStd::any& defaultObjectStorage,
const SerializeContext::ClassData*& elementClassData, const AZ::IRttiHelper& rtti, JsonSerializerContext& context);
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, JsonSerializerContext& context);
static rapidjson::Value StoreTypeName(const SerializeContext::ClassData& classData, const Uuid& typeId, JsonSerializerContext& context);
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
const Uuid& typeId, JsonSerializerContext& context);
@@ -0,0 +1,127 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/StackedString.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/Memory/SystemAllocator.h>
namespace AZ::JsonPathSerializerInternal
{
template<typename PathType>
static JsonSerializationResult::Result Load(PathType* pathValue, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
AZ_Assert(pathValue, "Expected a valid pointer to load from json value.");
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
[[fallthrough]];
case rapidjson::kNullType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. String values can't be read from arrays, objects or null.");
case rapidjson::kStringType:
{
size_t pathLength = inputValue.GetStringLength();
if (pathLength <= pathValue->Native().max_size())
{
*pathValue = PathType(AZStd::string_view(inputValue.GetString(), pathLength)).LexicallyNormal();
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read path.");
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::ReadField, JSR::Outcomes::Invalid,
ErrorString::format("Json string value is too large to fit within path type %s. It needs to be less than %zu code points",
azrtti_typeid<PathType>().template ToString<UuidString>().c_str(), pathValue->Native().max_size()));
}
default:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, "Unknown json type encountered for string value.");
}
}
template<typename PathType>
static JsonSerializationResult::Result StoreWithDefault(rapidjson::Value& outputValue, const PathType* pathValue,
const PathType* defaultPathValue, JsonSerializerContext& context)
{
namespace JSR = JsonSerializationResult; // Removes name conflicts in AzCore in uber builds.
if (context.ShouldKeepDefaults() || defaultPathValue == nullptr || *pathValue != *defaultPathValue)
{
auto posixPathString = pathValue->AsPosix();
outputValue.SetString(posixPathString.c_str(), aznumeric_caster(posixPathString.size()), context.GetJsonAllocator());
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Path successfully stored.");
}
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default Path used.");
}
}
namespace AZ
{
AZ_CLASS_ALLOCATOR_IMPL(JsonPathSerializer, SystemAllocator, 0);
JsonSerializationResult::Result JsonPathSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
if (outputValueTypeId == azrtti_typeid<AZ::IO::Path>())
{
return JsonPathSerializerInternal::Load(reinterpret_cast<AZ::IO::Path*>(outputValue), inputValue,
context);
}
else if (outputValueTypeId == azrtti_typeid<AZ::IO::FixedMaxPath>())
{
return JsonPathSerializerInternal::Load(reinterpret_cast<AZ::IO::FixedMaxPath*>(outputValue), inputValue,
context);
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
auto errorTypeIdString = outputValueTypeId.ToString<UuidString>();
AZ_Assert(false, "Unable to serialize json string"
" to a path of type %s", errorTypeIdString.c_str());
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::TypeMismatch,
ErrorString::format("Output value type ID %s is not a valid Path type", errorTypeIdString.c_str()));
}
JsonSerializationResult::Result JsonPathSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context)
{
if (valueTypeId == azrtti_typeid<AZ::IO::Path>())
{
return JsonPathSerializerInternal::StoreWithDefault(outputValue,
reinterpret_cast<const AZ::IO::Path*>(inputValue),
reinterpret_cast<const AZ::IO::Path*>(defaultValue), context);
}
else if (valueTypeId == azrtti_typeid<AZ::IO::FixedMaxPath>())
{
return JsonPathSerializerInternal::StoreWithDefault(outputValue,
reinterpret_cast<const AZ::IO::FixedMaxPath*>(inputValue),
reinterpret_cast<const AZ::IO::FixedMaxPath*>(defaultValue), context);
}
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
auto errorTypeIdString = valueTypeId.ToString<UuidString>();
AZ_Assert(false, "Unable to serialize path type %s to a json string",
errorTypeIdString.c_str());
using ErrorString = AZStd::fixed_string<256>;
return context.Report(JsonSerializationResult::Tasks::WriteValue, JsonSerializationResult::Outcomes::TypeMismatch,
ErrorString::format("Input value type ID %s is not a valid Path type", errorTypeIdString.c_str()));
}
} // namespace AZ
@@ -0,0 +1,26 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
namespace AZ
{
class JsonPathSerializer
: public BaseJsonSerializer
{
public:
AZ_RTTI(JsonPathSerializer, "{F6FBA901-07E0-4F03-A0B6-72A9A6CE1E96}", 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
@@ -537,6 +537,8 @@ set(FILES
Serialization/Json/JsonUtils.cpp
Serialization/Json/MapSerializer.h
Serialization/Json/MapSerializer.cpp
Serialization/Json/PathSerializer.h
Serialization/Json/PathSerializer.cpp
Serialization/Json/RegistrationContext.h
Serialization/Json/RegistrationContext.cpp
Serialization/Json/SmartPointerSerializer.h
@@ -11,6 +11,7 @@
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@@ -453,7 +454,7 @@ namespace UnitTest
AZ::Quaternion backFromScaledAxisAngle = AZ::Quaternion::CreateFromScaledAxisAngle(scaledAxisAngle);
// Compare the original quaternion with the one after the conversion.
EXPECT_TRUE(testQuat.IsClose(backFromScaledAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromScaledAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, AxisAngleQuatRoundtripTests)
@@ -467,7 +468,7 @@ namespace UnitTest
// Convert the axis-angle back into a quaternion and compare the original quaternion with the one after the conversion.
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axis, angle);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareAxisAngleConversionTests)
@@ -506,8 +507,20 @@ namespace UnitTest
}
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axisFromScaledResult, angleFromScaledResult);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
INSTANTIATE_TEST_CASE_P(MATH_Quaternion, QuaternionScaledAxisAngleConversionFixture, ::testing::ValuesIn(RotationRepresentationConversionTestQuats));
TEST(MATH_Quaternion, ShortestEquivalent)
{
const AZ::Quaternion testQuat = AZ::Quaternion::CreateRotationX(AZ::Constants::HalfPi * 3.0f);
AZ::Quaternion absQuat = testQuat;
absQuat.ShortestEquivalent();
EXPECT_THAT(testQuat.GetShortestEquivalent(), IsCloseTolerance(absQuat, 1e-6f));
const float angle = absQuat.GetEulerRadians().GetX();
EXPECT_THAT(angle, testing::FloatEq(-AZ::Constants::HalfPi));
}
}
@@ -0,0 +1,106 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/Path/PathReflect.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
namespace JsonSerializationTests
{
template<typename PathType>
class PathTestDescription
: public JsonSerializerConformityTestDescriptor<PathType>
{
public:
using JsonSerializerConformityTestDescriptor<PathType>::Reflect;
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
{
AZ::IO::PathReflect(serializeContext.get());
}
void Reflect(AZStd::unique_ptr<AZ::JsonRegistrationContext>& jsonContext) override
{
AZ::IO::PathReflect(jsonContext.get());
}
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
{
return AZStd::make_shared<AZ::JsonPathSerializer>();
}
AZStd::shared_ptr<PathType> CreateDefaultInstance() override
{
return AZStd::make_shared<PathType>();
}
AZStd::shared_ptr<PathType> CreateFullySetInstance() override
{
return AZStd::make_shared<PathType>("O3DE/Relative/Path");
}
AZStd::string_view GetJsonForFullySetInstance() override
{
return R"("O3DE/Relative/Path")";
}
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
{
features.EnableJsonType(rapidjson::kStringType);
features.m_supportsPartialInitialization = false;
features.m_supportsInjection = false;
}
bool AreEqual(const PathType& lhs, const PathType& rhs) override
{
return lhs == rhs;
}
};
using PathConformityTestTypes = ::testing::Types<
PathTestDescription<AZ::IO::Path>,
PathTestDescription<AZ::IO::FixedMaxPath>
>;
INSTANTIATE_TYPED_TEST_CASE_P(Path, JsonSerializerConformityTests, PathConformityTestTypes);
class PathSerializerTests
: public BaseJsonSerializerFixture
{
public:
AZStd::unique_ptr<AZ::JsonPathSerializer> m_serializer;
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
m_serializer = AZStd::make_unique<AZ::JsonPathSerializer>();
}
void TearDown() override
{
m_serializer.reset();
BaseJsonSerializerFixture::TearDown();
}
};
TEST_F(PathSerializerTests, LoadingIntoFixedMaxPath_GreaterThanMaxPathLength_Fails)
{
AZ::IO::Path testPath;
// Fill a path greater than the AZ::IO::MaxPathLength in write it to Json
testPath.Native().append(AZ::IO::MaxPathLength + 2, 'a');
rapidjson::Value loadPathValue;
AZ::JsonSerializationResult::ResultCode resultCode = m_serializer->Store(loadPathValue,
&testPath, nullptr, azrtti_typeid<AZ::IO::Path>(), *m_jsonSerializationContext);
EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Success, resultCode.GetOutcome());
AZ::IO::FixedMaxPath resultPath;
AZ::JsonSerializationResult::ResultCode result = m_serializer->Load(&resultPath, azrtti_typeid<AZ::IO::FixedMaxPath>(),
loadPathValue, *m_jsonDeserializationContext);
EXPECT_GE(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::Invalid);
}
} // namespace JsonSerializationTests
@@ -10,6 +10,77 @@
#include <Tests/Serialization/Json/JsonSerializationTests.h>
#include <Tests/Serialization/Json/TestCases_Classes.h>
#include <Tests/Serialization/Json/TestCases_Pointers.h>
#include <AzCore/Asset/AssetCommon.h>
namespace AZ
{
template<typename T>
struct SerializeGenericTypeInfo<JsonSerializationTests::TemplatedClass<T>>
{
using ThisType = JsonSerializationTests::TemplatedClass<T>;
class GenericTemplatedClassInfo : public GenericClassInfo
{
public:
GenericTemplatedClassInfo()
: m_classData{ SerializeContext::ClassData::Create<ThisType>(
"TemplatedClass", "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", nullptr, nullptr) }
{
}
SerializeContext::ClassData* GetClassData() override
{
return &m_classData;
}
size_t GetNumTemplatedArguments() override
{
return 1;
}
const Uuid& GetSpecializedTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetGenericTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetTemplatedTypeId(size_t element) override
{
(void)element;
return SerializeGenericTypeInfo<T>::GetClassTypeId();
}
void Reflect(SerializeContext* serializeContext) override
{
if (serializeContext)
{
serializeContext->RegisterGenericClassInfo(
GetSpecializedTypeId(), this, &AZ::AnyTypeInfoConcept<Data::Asset<Data::AssetData>>::CreateAny);
serializeContext->RegisterGenericClassInfo(
azrtti_typeid<ThisType>(), this,
&AZ::AnyTypeInfoConcept<ThisType>::CreateAny);
}
}
SerializeContext::ClassData m_classData;
};
using ClassInfoType = GenericTemplatedClassInfo;
static ClassInfoType* GetGenericInfo()
{
return GetCurrentSerializeContextModule().CreateGenericClassInfo<ThisType>();
}
static const Uuid& GetClassTypeId()
{
return GetGenericInfo()->GetClassData()->m_typeId;
}
};
} // namespace AZ
namespace JsonSerializationTests
{
@@ -286,4 +357,32 @@ namespace JsonSerializationTests
EXPECT_EQ(Processing::Halted, result.GetProcessing());
EXPECT_EQ(Outcomes::Unknown, result.GetOutcome());
}
TEST_F(JsonSerializationTests, StoreTypeId_TemplatedType_StoresUuidWithName)
{
using namespace AZ;
using namespace AZ::JsonSerializationResult;
m_serializeContext->RegisterGenericType<TemplatedClass<A::Inherited>>();
m_serializeContext->RegisterGenericType<TemplatedClass<BaseClass>>();
Uuid input = azrtti_typeid<TemplatedClass<A::Inherited>>();
ResultCode result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
AZStd::string expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<A::Inherited>>().ToString<AZStd::string>().c_str());
Expect_DocStrEq(expected.c_str(), false);
input = azrtti_typeid<TemplatedClass<BaseClass>>();
result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<BaseClass>>().ToString<AZStd::string>().c_str());
EXPECT_EQ(Processing::Completed, result.GetProcessing());
Expect_DocStrEq(expected.c_str(), false);
}
} // namespace JsonSerializationTests
@@ -76,192 +76,4 @@ namespace UnitTest
int64_t delta = static_cast<int64_t>(timeMs) - static_cast<int64_t>(timeUsToMs);
EXPECT_LT(abs(delta), 1);
}
class TimeSystemTests : public AllocatorsTestFixture
{
public:
void SetUp() override
{
SetupAllocator();
m_controlTime = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
m_timeSystem = AZStd::make_unique<AZ::TimeSystem>();
}
void TearDown() override
{
m_controlTime = AZ::Time::ZeroTimeUs;
m_timeSystem.reset();
TeardownAllocator();
}
AZ::TimeUs GetDiff(AZ::TimeUs time1, AZ::TimeUs time2) const
{
// AZ::TimeUs is unsigned so make sure to not underflow.
return time1 > time2 ? time1 - time2 : time2 - time1;
}
AZ::TimeUs m_controlTime;
AZStd::unique_ptr<AZ::TimeSystem> m_timeSystem;
};
TEST_F(TimeSystemTests, GetRealElapsedTimeUs)
{
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetRealElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetRealElapsedTimeUs();
const AZ::TimeUs diff = GetDiff(baseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, GetElapsedTimeUs)
{
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetElapsedTimeUs();
const AZ::TimeUs diff = GetDiff(baseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, ElapsedTimeScales)
{
// slow down 'time'
m_timeSystem->SetSimulationTickScale(0.5f);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// find the delta for the control and from GetElapsedTimeUs
const AZ::TimeUs baseline = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - m_controlTime;
const AZ::TimeUs elapsedTime = m_timeSystem->GetElapsedTimeUs();
const AZ::TimeUs halfBaseline = (baseline / AZ::TimeUs{ 2 });
// elapsedTime should be about half of the control.
const AZ::TimeUs diff = GetDiff(halfBaseline, elapsedTime);
// elapsedTime should be within 10 microseconds from baseline.
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset time scale
m_timeSystem->SetSimulationTickScale(1.0f);
}
TEST_F(TimeSystemTests, AdvanceTickDeltaTimes)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be close to the baselineDelta.
const AZ::TimeUs diff = GetDiff(delta, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, SimulationAndRealTickDeltaTimesWithNoTimeScale)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be close to the baselineDelta.
AZ::TimeUs diff = GetDiff(delta, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// the delta should be the same as GetSimulationTickDeltaTimeUs and near GetRealTickDeltaTimeUs
const AZ::TimeUs simDeltaTime = m_timeSystem->GetSimulationTickDeltaTimeUs();
EXPECT_EQ(delta, simDeltaTime);
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
diff = GetDiff(delta, realDeltaTime);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
}
TEST_F(TimeSystemTests, SimulationAndRealTickDeltaTimesWithTimeScale)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// slow down 'time';
m_timeSystem->SetSimulationTickScale(0.5f);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
const AZ::TimeUs halfBaselineDelta = (baselineDelta / AZ::TimeUs{ 2 });
// the delta should be half the baselineDelta
AZ::TimeUs diff = GetDiff(delta, halfBaselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// the delta should be the same as GetSimulationTickDeltaTimeUs
const AZ::TimeUs simDeltaTime = m_timeSystem->GetSimulationTickDeltaTimeUs();
EXPECT_EQ(delta, simDeltaTime);
// the delta should be near half the GetRealTickDeltaTimeUs
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
const AZ::TimeUs halfRealDeltaTime = (realDeltaTime / AZ::TimeUs{ 2 });
diff = GetDiff(delta, halfRealDeltaTime);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset time scale
m_timeSystem->SetSimulationTickScale(1.0f);
}
TEST_F(TimeSystemTests, SimulationTickDeltaOverride)
{
// advance the tick delta to get a clean base.
m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineStart = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond());
// set the tick delta override
const AZ::TimeMs tickOverride = AZ::TimeMs{ 3462 };
m_timeSystem->SetSimulationTickDeltaOverride(tickOverride);
// sleep for a bit to advance time.
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(2));
// advance the tick delta.
const AZ::TimeUs delta = m_timeSystem->AdvanceTickDeltaTimes();
const AZ::TimeUs baselineDelta = static_cast<AZ::TimeUs>(AZStd::GetTimeNowMicroSecond()) - baselineStart;
// the delta should be equal to the tickOverride
EXPECT_EQ(delta, AZ::TimeMsToUs(tickOverride));
// real tick delta should be near the baselineDelta
const AZ::TimeUs realDeltaTime = m_timeSystem->GetRealTickDeltaTimeUs();
const AZ::TimeUs diff = GetDiff(realDeltaTime, baselineDelta);
EXPECT_LT(diff, AZ::TimeUs{ 10 });
// reset the tick delta override
m_timeSystem->SetSimulationTickDeltaOverride(AZ::Time::ZeroTimeMs);
}
} // namespace UnitTest
@@ -111,6 +111,7 @@ set(FILES
Serialization/Json/MapSerializerTests.cpp
Serialization/Json/MathVectorSerializerTests.cpp
Serialization/Json/MathMatrixSerializerTests.cpp
Serialization/Json/PathSerializerTests.cpp
Serialization/Json/SmartPointerSerializerTests.cpp
Serialization/Json/StringSerializerTests.cpp
Serialization/Json/TestCases.h
@@ -270,8 +270,6 @@ set(FILES
Physics/WindBus.h
Process/ProcessCommunicator.cpp
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
Process/ProcessWatcher.h
Process/ProcessCommon_fwd.h
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
@@ -83,4 +83,9 @@ namespace AzFramework
{
}
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
{
return AZStd::string{};
}
} //namespace AzFramework
@@ -243,7 +243,7 @@ SliderDoubleCombo::SliderDoubleCombo(QWidget* parent)
InitialiseSliderCombo(this, layout, m_spinbox, m_slider);
connect(m_slider, &SliderDouble::valueChanged, this, &SliderDoubleCombo::setValue);
connect(m_slider, &SliderDouble::valueChanged, this, &SliderDoubleCombo::setValueSlider);
connect(m_spinbox, QOverload<double>::of(&DoubleSpinBox::valueChanged), this, &SliderDoubleCombo::setValue);
connect(m_slider, &SliderDouble::sliderReleased, this, &SliderDoubleCombo::editingFinished);
connect(m_spinbox, &DoubleSpinBox::editingFinished, this, &SliderDoubleCombo::editingFinished);
@@ -254,7 +254,7 @@ SliderDoubleCombo::~SliderDoubleCombo()
{
}
void SliderDoubleCombo::setValue(double value)
void SliderDoubleCombo::setValueSlider(double value)
{
const bool doEmit = m_value != value;
m_value = value;
@@ -264,10 +264,34 @@ void SliderDoubleCombo::setValue(double value)
if (doEmit)
{
// We don't want to update the slider from setValue as this
// causes rounding errors in the tooltip hint.
m_fromSlider = true;
Q_EMIT valueChanged();
}
}
void SliderDoubleCombo::setValue(double value)
{
const bool doEmit = m_value != value;
m_value = value;
updateSpinBox();
if (!m_fromSlider)
{
updateSlider();
if (doEmit)
{
Q_EMIT valueChanged();
}
}
else
{
m_fromSlider = false;
}
}
SliderDouble* SliderDoubleCombo::slider() const
{
return m_slider;
@@ -151,6 +151,8 @@ namespace AzQtComponents
//! Sets the current value.
void setValue(double value);
//! Sets the current value.
void setValueSlider(double value);
//! Return the current value.
Q_REQUIRED_RESULT double value() const;
@@ -235,5 +237,6 @@ namespace AzQtComponents
double m_softMinimum = 0.0;
double m_softMaximum = 100.0;
double m_value = 0.0;
bool m_fromSlider{ false };
};
} // namespace AzQtComponents
@@ -144,7 +144,10 @@ namespace AzToolsFramework
{
emit ClearStringFilter();
emit ClearTypeFilter();
m_sourceFilterModel->FilterUpdatedSlotImmediate();
if (m_sourceFilterModel)
{
m_sourceFilterModel->FilterUpdatedSlotImmediate();
}
}
void AssetBrowserTableView::Update()
@@ -2666,19 +2666,15 @@ namespace AzToolsFramework
if (!isPathSafeForAssets)
{
// Put an error in the console, so the log files have info about this error, or the user can look up the error after dismissing it.
AZStd::string errorMessage = "You can save slices only to your game project folder or the Gems folder. Update the location and try again.\n\n"
"You can also review and update your save locations in the AssetProcessorPlatformConfig.ini file.";
AZStd::string errorMessage = "You can save slices only to your game project folder or the Gems folder. Update the location and try again.\n\n";
AZ_Error("Slice", false, errorMessage.c_str());
QString learnMoreLink(QObject::tr(""));
QString learnMoreDescription(QObject::tr(" <a href='%1'>Learn more</a>").arg(learnMoreLink));
// Display a pop-up, the logs are easy to miss. This will make sure a user who encounters this error immediately knows their slice save has failed.
QMessageBox msgBox(activeWindow);
msgBox.setIcon(QMessageBox::Icon::Warning);
msgBox.setTextFormat(Qt::RichText);
msgBox.setWindowTitle(QObject::tr("Invalid save location"));
msgBox.setText(QString("%1 %2").arg(QObject::tr(errorMessage.c_str())).arg(learnMoreDescription));
msgBox.setText(QString("%1").arg(QObject::tr(errorMessage.c_str())));
msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Retry);
msgBox.setDefaultButton(QMessageBox::Retry);
const int response = msgBox.exec();
@@ -2689,7 +2685,16 @@ namespace AzToolsFramework
// so set the suggested save path to a known valid location.
if (assetSafeFolders.size() > 0)
{
retrySavePath = assetSafeFolders[0];
QStringList strList = slicePath.split("/");
if (strList.size() > 0)
{
retrySavePath = assetSafeFolders[0] + ("/" + strList[strList.size() - 1]).toUtf8().data();
}
else
{
retrySavePath = assetSafeFolders[0];
}
}
return SliceSaveResult::Retry;
case QMessageBox::Cancel:
@@ -840,8 +840,6 @@ namespace AzToolsFramework
richLabel->setTextFormat(Qt::RichText);
}
richLabel->setText(data);
richLabel->setGeometry(options.rect);
richLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
richLabel->setPalette(options.palette);
@@ -1117,6 +1117,8 @@ namespace AzToolsFramework
m_listModel->SearchStringChanged(filterString);
m_proxyModel->UpdateFilter();
m_gui->m_objectTree->expandAll();
}
void EntityOutlinerWidget::OnFilterChanged(const AzQtComponents::SearchTypeFilterList& activeTypeFilters)