Many small fixes to combat behaviour, navigation and perfomance.

This commit is contained in:
jeefo 2019-08-18 21:00:00 +03:00
commit f673f5cd0a
26 changed files with 1447 additions and 1330 deletions

View file

@ -67,7 +67,9 @@ namespace detail {
// basic dictionary
template <class K, class V, class H = StringHash <K>, size_t HashSize = 36> class Dictionary final : public DenyCopying {
public:
static constexpr size_t kInvalidIndex = static_cast <size_t> (-1);
enum : size_t {
InvalidIndex = static_cast <size_t> (-1)
};
private:
Array <detail::DictionaryList *> m_table;
@ -105,7 +107,7 @@ private:
return created;
}
return kInvalidIndex;
return InvalidIndex;
}
size_t findIndex (const K &key) const {
@ -126,7 +128,7 @@ public:
public:
bool exists (const K &key) const {
return findIndex (key) != kInvalidIndex;
return findIndex (key) != InvalidIndex;
}
bool empty () const {
@ -140,7 +142,7 @@ public:
bool find (const K &key, V &value) const {
size_t index = findIndex (key);
if (index == kInvalidIndex) {
if (index == InvalidIndex) {
return false;
}
value = m_buckets[index].value;

View file

@ -178,12 +178,12 @@ namespace detail {
}
size_t protocol = uri.find ("://");
if (protocol != String::kInvalidIndex) {
if (protocol != String::InvalidIndex) {
result.protocol = uri.substr (0, protocol);
size_t host = uri.find ("/", protocol + 3);
if (host != String::kInvalidIndex) {
if (host != String::InvalidIndex) {
result.path = uri.substr (host + 1);
result.host = uri.substr (protocol + 3, host - protocol - 3);
@ -244,7 +244,7 @@ private:
String response (reinterpret_cast <const char *> (buffer));
size_t responseCodeStart = response.find ("HTTP/1.1");
if (responseCodeStart != String::kInvalidIndex) {
if (responseCodeStart != String::InvalidIndex) {
String respCode = response.substr (responseCodeStart + 9, 3).trim ();
if (respCode == "200") {
@ -369,7 +369,7 @@ public:
String boundaryName = localPath;
size_t boundarySlash = localPath.findLastOf ("\\/");
if (boundarySlash != String::kInvalidIndex) {
if (boundarySlash != String::InvalidIndex) {
boundaryName = localPath.substr (boundarySlash + 1);
}
const String &kBoundary = "---crlib_upload_boundary_1337";

View file

@ -14,10 +14,14 @@
CR_NAMESPACE_BEGIN
static constexpr uint32 kLambdaSmallBufferSize = sizeof (void *) * 16;
template <typename> class Lambda;
template <typename R, typename ...Args> class Lambda <R (Args...)> {
private:
enum : uint32 {
LamdaSmallBufferLength = sizeof (void *) * 16
};
private:
class LambdaFunctorWrapper {
public:
LambdaFunctorWrapper () = default;
@ -69,7 +73,7 @@ template <typename R, typename ...Args> class Lambda <R (Args...)> {
union {
UniquePtr <LambdaFunctorWrapper> m_functor;
uint8 m_small[kLambdaSmallBufferSize];
uint8 m_small[LamdaSmallBufferLength];
};
bool m_smallObject;
@ -118,7 +122,7 @@ public:
}
template <typename F> Lambda (F function) {
if (cr::fix (sizeof (function) > kLambdaSmallBufferSize)) {
if (cr::fix (sizeof (function) > LamdaSmallBufferLength)) {
m_smallObject = false;
new (m_small) UniquePtr <LambdaFunctorWrapper> (createUniqueBase <LambdaFunctor <F>, LambdaFunctorWrapper> (cr::move (function)));
}

View file

@ -23,10 +23,15 @@ CR_NAMESPACE_BEGIN
// small-string optimized string class, sso stuff based on: https://github.com/elliotgoodrich/SSO-23/
class String final {
public:
static constexpr size_t kInvalidIndex = static_cast <size_t> (-1);
enum : size_t {
InvalidIndex = static_cast <size_t> (-1)
};
private:
static constexpr size_t kExcessSpace = 32;
enum : size_t {
ExcessSpace = 32,
CharBit = CHAR_BIT
};
private:
using Length = Twin <size_t, size_t>;
@ -34,7 +39,7 @@ private:
private:
union Data {
struct Big {
char excess[kExcessSpace - sizeof (char *) - 2 * sizeof (size_t)];
char excess[ExcessSpace - sizeof (char *) - 2 * sizeof (size_t)];
char *ptr;
size_t length;
size_t capacity;
@ -47,7 +52,9 @@ private:
} m_data;
private:
static size_t const kSmallCapacity = sizeof (typename Data::Big) / sizeof (char) - 1;
enum : size_t {
SmallCapacity = sizeof (typename Data::Big) / sizeof (char) - 1
};
public:
explicit String () {
@ -89,7 +96,7 @@ private:
}
template <size_t N> static bool getMostSignificantBit (uint8 byte) {
return byte & cr::bit (CHAR_BIT - N - 1);
return byte & cr::bit (CharBit - N - 1);
}
template <size_t N> static void setLeastSignificantBit (uint8 &byte, bool bit) {
@ -103,10 +110,10 @@ private:
template <size_t N> static void setMostSignificantBit (uint8 &byte, bool bit) {
if (bit) {
byte |= cr::bit (CHAR_BIT - N - 1);
byte |= cr::bit (CharBit - N - 1);
}
else {
byte &= ~cr::bit (CHAR_BIT - N - 1);
byte &= ~cr::bit (CharBit - N - 1);
}
}
@ -144,7 +151,7 @@ private:
}
void setLength (size_t amount, size_t capacity) {
if (amount <= kSmallCapacity) {
if (amount <= SmallCapacity) {
endString (m_data.small.str, amount);
setSmallLength (static_cast <uint8> (amount));
}
@ -159,11 +166,11 @@ private:
}
void setSmallLength (uint8 length) {
m_data.small.length = static_cast <char> (kSmallCapacity - length) << 2;
m_data.small.length = static_cast <char> (SmallCapacity - length) << 2;
}
size_t getSmallLength () const {
return kSmallCapacity - ((m_data.small.length >> 2) & 63u);
return SmallCapacity - ((m_data.small.length >> 2) & 63u);
}
void setDataNonSmall (size_t length, size_t capacity) {
@ -208,14 +215,14 @@ public:
String &assign (const char *str, size_t length = 0) {
length = length > 0 ? length : strlen (str);
if (length <= kSmallCapacity) {
if (length <= SmallCapacity) {
moveString (m_data.small.str, str, length);
endString (m_data.small.str, length);
setSmallLength (static_cast <uint8> (length));
}
else {
auto capacity = cr::max (kSmallCapacity * 2, length);
auto capacity = cr::max (SmallCapacity * 2, length);
m_data.big.ptr = alloc.allocate <char> (capacity + 1);
if (m_data.big.ptr) {
@ -287,7 +294,7 @@ public:
void resize (size_t amount) {
size_t oldLength = length ();
if (amount <= kSmallCapacity) {
if (amount <= SmallCapacity) {
if (!isSmall ()) {
auto ptr = m_data.big.ptr;
@ -300,7 +307,7 @@ public:
size_t newCapacity = 0;
if (isSmall ()) {
newCapacity = cr::max (amount, kSmallCapacity * 2);
newCapacity = cr::max (amount, SmallCapacity * 2);
auto ptr = alloc.allocate <char> (newCapacity + 1);
moveString (ptr, m_data.small.str, cr::min (oldLength, amount));
@ -369,7 +376,7 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t find (const String &pattern, size_t start = 0) const {
@ -377,7 +384,7 @@ public:
const size_t dataLength = length ();
if (patternLength > dataLength || start > dataLength) {
return kInvalidIndex;
return InvalidIndex;
}
for (size_t i = start; i <= dataLength - patternLength; ++i) {
@ -393,7 +400,7 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t rfind (char pattern) const {
@ -402,7 +409,7 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t rfind (const String &pattern) const {
@ -410,7 +417,7 @@ public:
const size_t dataLength = length ();
if (patternLength > dataLength) {
return kInvalidIndex;
return InvalidIndex;
}
bool match = true;
@ -428,7 +435,7 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t findFirstOf (const String &pattern, size_t start = 0) const {
@ -442,7 +449,7 @@ public:
}
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t findLastOf (const String &pattern) const {
@ -456,7 +463,7 @@ public:
}
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t findFirstNotOf (const String &pattern, size_t start = 0) const {
@ -479,7 +486,7 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t findLastNotOf (const String &pattern) const {
@ -501,10 +508,9 @@ public:
return i;
}
}
return kInvalidIndex;
return InvalidIndex;
}
size_t countChar (char ch) const {
size_t count = 0;
@ -533,10 +539,10 @@ public:
return count;
}
String substr (size_t start, size_t count = kInvalidIndex) const {
String substr (size_t start, size_t count = InvalidIndex) const {
start = cr::min (start, length ());
if (count == kInvalidIndex) {
if (count == InvalidIndex) {
count = length ();
}
return String (data () + start, cr::min (count, length () - start));
@ -551,7 +557,7 @@ public:
while (pos < length ()) {
pos = find (needle, pos);
if (pos == kInvalidIndex) {
if (pos == InvalidIndex) {
break;
}
erase (pos, needle.length ());
@ -581,7 +587,7 @@ public:
Array <String> tokens;
size_t prev = 0, pos = 0;
while ((pos = find (delim, pos)) != kInvalidIndex) {
while ((pos = find (delim, pos)) != InvalidIndex) {
tokens.push (substr (prev, pos - prev));
prev = ++pos;
}
@ -641,7 +647,7 @@ public:
}
bool contains (const String &rhs) const {
return find (rhs) != kInvalidIndex;
return find (rhs) != InvalidIndex;
}
String &lowercase () {
@ -670,7 +676,7 @@ public:
size_t begin = length ();
for (size_t i = 0; i < begin; ++i) {
if (characters.find (at (i)) == kInvalidIndex) {
if (characters.find (at (i)) == InvalidIndex) {
begin = i;
break;
}
@ -682,7 +688,7 @@ public:
size_t end = 0;
for (size_t i = length (); i > 0; --i) {
if (characters.find (at (i - 1)) == kInvalidIndex) {
if (characters.find (at (i - 1)) == InvalidIndex) {
end = i;
break;
}

View file

@ -14,67 +14,71 @@
CR_NAMESPACE_BEGIN
// 3dmath vector
class Vector final {
template <typename T> class Vec3D {
public:
float x = 0.0f, y = 0.0f, z = 0.0f;
T x = 0.0f, y = 0.0f, z = 0.0f;
public:
Vector (const float scaler = 0.0f) : x (scaler), y (scaler), z (scaler)
Vec3D (const T &scaler = 0.0f) : x (scaler), y (scaler), z (scaler)
{ }
explicit Vector (const float _x, const float _y, const float _z) : x (_x), y (_y), z (_z)
Vec3D (const T &x, const T &y, const T &z) : x (x), y (y), z (z)
{ }
Vector (float *rhs) : x (rhs[0]), y (rhs[1]), z (rhs[2])
Vec3D (T *rhs) : x (rhs[0]), y (rhs[1]), z (rhs[2])
{ }
Vector (const Vector &) = default;
Vec3D (const Vec3D &) = default;
Vec3D (decltype (nullptr)) {
clear ();
}
public:
operator float *() {
operator T * () {
return &x;
}
operator const float * () const {
operator const T * () const {
return &x;
}
Vector operator + (const Vector &rhs) const {
return Vector (x + rhs.x, y + rhs.y, z + rhs.z);
Vec3D operator + (const Vec3D &rhs) const {
return { x + rhs.x, y + rhs.y, z + rhs.z };
}
Vector operator - (const Vector &rhs) const {
return Vector (x - rhs.x, y - rhs.y, z - rhs.z);
Vec3D operator - (const Vec3D &rhs) const {
return { x - rhs.x, y - rhs.y, z - rhs.z };
}
Vector operator - () const {
return Vector (-x, -y, -z);
Vec3D operator - () const {
return { -x, -y, -z };
}
friend Vector operator * (const float scale, const Vector &rhs) {
return Vector (rhs.x * scale, rhs.y * scale, rhs.z * scale);
friend Vec3D operator * (const T &scale, const Vec3D &rhs) {
return { rhs.x * scale, rhs.y * scale, rhs.z * scale };
}
Vector operator * (const float scale) const {
return Vector (scale * x, scale * y, scale * z);
Vec3D operator * (const T &scale) const {
return { scale * x, scale * y, scale * z };
}
Vector operator / (const float div) const {
const float inv = 1 / div;
return Vector (inv * x, inv * y, inv * z);
Vec3D operator / (const T &rhs) const {
const auto inv = 1 / (rhs + kFloatEqualEpsilon);
return { inv * x, inv * y, inv * z };
}
// cross product
Vector operator ^ (const Vector &rhs) const {
return Vector (y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
Vec3D operator ^ (const Vec3D &rhs) const {
return { y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x };
}
// dot product
float operator | (const Vector &rhs) const {
T operator | (const Vec3D &rhs) const {
return x * rhs.x + y * rhs.y + z * rhs.z;
}
const Vector &operator += (const Vector &rhs) {
const Vec3D &operator += (const Vec3D &rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
@ -82,24 +86,24 @@ public:
return *this;
}
const Vector &operator -= (const Vector &right) {
x -= right.x;
y -= right.y;
z -= right.z;
const Vec3D &operator -= (const Vec3D &rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
const Vector &operator *= (float scale) {
x *= scale;
y *= scale;
z *= scale;
const Vec3D &operator *= (const T &rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
const Vector &operator /= (float div) {
const float inv = 1 / div;
const Vec3D &operator /= (const T &rhs) {
const auto inv = 1 / (rhs + kFloatEqualEpsilon);
x *= inv;
y *= inv;
@ -108,67 +112,66 @@ public:
return *this;
}
bool operator == (const Vector &rhs) const {
bool operator == (const Vec3D &rhs) const {
return cr::fequal (x, rhs.x) && cr::fequal (y, rhs.y) && cr::fequal (z, rhs.z);
}
bool operator != (const Vector &rhs) const {
return !cr::fequal (x, rhs.x) && !cr::fequal (y, rhs.y) && !cr::fequal (z, rhs.z);
bool operator != (const Vec3D &rhs) const {
return !operator == (rhs);
}
Vector &operator = (const Vector &) = default;
void operator = (decltype (nullptr)) {
clear ();
}
Vec3D &operator = (const Vec3D &) = default;
public:
float length () const {
T length () const {
return cr::sqrtf (lengthSq ());
}
float length2d () const {
T length2d () const {
return cr::sqrtf (x * x + y * y);
}
float lengthSq () const {
T lengthSq () const {
return x * x + y * y + z * z;
}
Vector get2d () const {
return Vector (x, y, 0.0f);
Vec3D get2d () const {
return { x, y, 0.0f };
}
Vector normalize () const {
float len = length () + cr::kFloatCmpEpsilon;
Vec3D normalize () const {
auto len = length () + cr::kFloatCmpEpsilon;
if (cr::fzero (len)) {
return Vector (0.0f, 0.0f, 1.0f);
return { 0.0f, 0.0f, 1.0f };
}
len = 1.0f / len;
return Vector (x * len, y * len, z * len);
return { x * len, y * len, z * len };
}
Vector normalize2d () const {
float len = length2d () + cr::kFloatCmpEpsilon;
Vec3D normalize2d () const {
auto len = length2d () + cr::kFloatCmpEpsilon;
if (cr::fzero (len)) {
return Vector (0.0f, 1.0f, 0.0f);
return { 0.0f, 1.0f, 0.0f };
}
len = 1.0f / len;
return Vector (x * len, y * len, 0.0f);
return { x * len, y * len, 0.0f };
}
bool empty () const {
return cr::fzero (x) && cr::fzero (y) && cr::fzero (z);
}
static const Vector &null () {
static const Vector &s_null {};
return s_null;
}
void clear () {
x = y = z = 0.0f;
}
Vector clampAngles () {
Vec3D clampAngles () {
x = cr::normalizeAngles (x);
y = cr::normalizeAngles (y);
z = 0.0f;
@ -176,78 +179,84 @@ public:
return *this;
}
float pitch () const {
T pitch () const {
if (cr::fzero (x) && cr::fzero (y)) {
return 0.0f;
}
return cr::degreesToRadians (cr::atan2f (z, length2d ()));
}
float yaw () const {
T yaw () const {
if (cr::fzero (x) && cr::fzero (y)) {
return 0.0f;
}
return cr::radiansToDegrees (cr:: atan2f (y, x));
}
Vector angles () const {
Vec3D angles () const {
if (cr::fzero (x) && cr::fzero (y)) {
return Vector (z > 0.0f ? 90.0f : 270.0f, 0.0, 0.0f);
return { z > 0.0f ? 90.0f : 270.0f, 0.0, 0.0f };
}
return Vector (cr::radiansToDegrees (cr::atan2f (z, length2d ())), cr::radiansToDegrees (cr::atan2f (y, x)), 0.0f);
return { cr::radiansToDegrees (cr::atan2f (z, length2d ())), cr::radiansToDegrees (cr::atan2f (y, x)), 0.0f };
}
void buildVectors (Vector *forward, Vector *right, Vector *upward) const {
void angleVectors (Vec3D *forward, Vec3D *right, Vec3D *upward) const {
enum { pitch, yaw, roll, unused, max };
float sines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
float cosines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
T sines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
T cosines[max] = { 0.0f, 0.0f, 0.0f, 0.0f };
// compute the sine and cosine compontents
cr::sincosf (cr::degreesToRadians (x), cr::degreesToRadians (y), cr::degreesToRadians (z), sines, cosines);
if (forward) {
forward->x = cosines[pitch] * cosines[yaw];
forward->y = cosines[pitch] * sines[yaw];
forward->z = -sines[pitch];
*forward = {
cosines[pitch] * cosines[yaw],
cosines[pitch] * sines[yaw],
-sines[pitch]
};
}
if (right) {
right->x = -sines[roll] * sines[pitch] * cosines[yaw] + cosines[roll] * sines[yaw];
right->y = -sines[roll] * sines[pitch] * sines[yaw] - cosines[roll] * cosines[yaw];
right->z = -sines[roll] * cosines[pitch];
*right = {
-sines[roll] * sines[pitch] * cosines[yaw] + cosines[roll] * sines[yaw],
-sines[roll] * sines[pitch] * sines[yaw] - cosines[roll] * cosines[yaw],
-sines[roll] * cosines[pitch]
};
}
if (upward) {
upward->x = cosines[roll] * sines[pitch] * cosines[yaw] + sines[roll] * sines[yaw];
upward->y = cosines[roll] * sines[pitch] * sines[yaw] - sines[roll] * cosines[yaw];
upward->z = cosines[roll] * cosines[pitch];
*upward = {
cosines[roll] * sines[pitch] * cosines[yaw] + sines[roll] * sines[yaw],
upward->y = cosines[roll] * sines[pitch] * sines[yaw] - sines[roll] * cosines[yaw],
upward->z = cosines[roll] * cosines[pitch]
};
}
}
const Vector &forward () {
static Vector s_fwd {};
buildVectors (&s_fwd, nullptr, nullptr);
const Vec3D &forward () {
static Vec3D s_fwd {};
angleVectors (&s_fwd, nullptr, nullptr);
return s_fwd;
}
const Vector &upward () {
static Vector s_up {};
buildVectors (nullptr, nullptr, &s_up);
const Vec3D &upward () {
static Vec3D s_up {};
angleVectors (nullptr, nullptr, &s_up);
return s_up;
}
const Vector &right () {
static Vector s_right {};
buildVectors (nullptr, &s_right, nullptr);
const Vec3D &right () {
static Vec3D s_right {};
angleVectors (nullptr, &s_right, nullptr);
return s_right;
}
};
// expose global null vector
static auto &nullvec = Vector::null ();
// default is float
using Vector = Vec3D <float>;
CR_NAMESPACE_END