Dqn_Rect_Intersection, remove Dqn_FixedStack, minor fixes
This commit is contained in:
parent
4bd8691076
commit
f67d97ec3d
50
Code/Dqn.h
50
Code/Dqn.h
@ -233,10 +233,10 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri
|
|||||||
#define DQN_ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))
|
#define DQN_ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define DEBUG_BREAK __debugbreak()
|
#define DQN_DEBUG_BREAK __debugbreak()
|
||||||
#else
|
#else
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#define DEBUG_BREAK raise(SIGTRAP)
|
#define DQN_DEBUG_BREAK raise(SIGTRAP)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DQN_INVALID_CODE_PATH 0
|
#define DQN_INVALID_CODE_PATH 0
|
||||||
@ -246,7 +246,7 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri
|
|||||||
if (!(expr)) \
|
if (!(expr)) \
|
||||||
{ \
|
{ \
|
||||||
DQN_LOG_E("Assert: [" #expr "] " fmt, ##__VA_ARGS__); \
|
DQN_LOG_E("Assert: [" #expr "] " fmt, ##__VA_ARGS__); \
|
||||||
DEBUG_BREAK; \
|
DQN_DEBUG_BREAK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DQN_IF_ASSERT(expr) DQN_IF_ASSERT_MSG(expr, "")
|
#define DQN_IF_ASSERT(expr) DQN_IF_ASSERT_MSG(expr, "")
|
||||||
@ -295,6 +295,7 @@ using u16 = uint16_t;
|
|||||||
using u8 = uint8_t;
|
using u8 = uint8_t;
|
||||||
|
|
||||||
using b32 = int32_t;
|
using b32 = int32_t;
|
||||||
|
using b8 = int8_t;
|
||||||
|
|
||||||
const i32 I32_MAX = INT32_MAX;
|
const i32 I32_MAX = INT32_MAX;
|
||||||
const u32 U32_MAX = UINT32_MAX;
|
const u32 U32_MAX = UINT32_MAX;
|
||||||
@ -911,12 +912,11 @@ DQN_HEADER_COPY_PROTOTYPE(template <Dqn_usize N> void, Dqn_StringBuilder_Free(Dq
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct Dqn_Slice
|
struct Dqn_Slice
|
||||||
{
|
{
|
||||||
union { T *data; T *buf; T *str; T const *const_str; };
|
union { T *data; T *buf; T *str; };
|
||||||
union { Dqn_isize size; Dqn_isize len; };
|
union { Dqn_isize size; Dqn_isize len; };
|
||||||
|
|
||||||
Dqn_Slice() = default;
|
Dqn_Slice() = default;
|
||||||
Dqn_Slice(T *str, Dqn_isize len) { this->str = str; this->len = len; }
|
Dqn_Slice(T *str, Dqn_isize len) { this->str = str; this->len = len; }
|
||||||
Dqn_Slice(T const *str, Dqn_isize len) { this->const_str = str; this->len = len; }
|
|
||||||
|
|
||||||
T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
|
T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
|
||||||
T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
|
T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
|
||||||
@ -1111,7 +1111,7 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEM
|
|||||||
|
|
||||||
|
|
||||||
DQN_FIXED_ARRAY_TEMPLATE
|
DQN_FIXED_ARRAY_TEMPLATE
|
||||||
DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num))
|
DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num = 1))
|
||||||
{
|
{
|
||||||
DQN_ASSERT(a->len - num >= 0);
|
DQN_ASSERT(a->len - num >= 0);
|
||||||
a->len -= num;
|
a->len -= num;
|
||||||
@ -1153,19 +1153,6 @@ DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ -------------------------------------------------------------------------------------------------
|
|
||||||
// @
|
|
||||||
// @ NOTE: Dqn_FixedStack
|
|
||||||
// @
|
|
||||||
// @ -------------------------------------------------------------------------------------------------
|
|
||||||
DQN_HEADER_COPY_BEGIN
|
|
||||||
template <typename T, int MAX_> using Dqn_FixedStack = DQN_FIXED_ARRAY_TEMPLATE_DECL;
|
|
||||||
template <typename T, int MAX_> T Dqn_FixedStack_Pop (Dqn_FixedStack<T, MAX_> *array) { T result = *Dqn_FixedArray_Peek(array); Dqn_FixedArray_Pop(array, 1); return result; }
|
|
||||||
template <typename T, int MAX_> T *Dqn_FixedStack_Peek (Dqn_FixedStack<T, MAX_> *array) { return Dqn_FixedArray_Peek(array); }
|
|
||||||
template <typename T, int MAX_> T *Dqn_FixedStack_Push (Dqn_FixedStack<T, MAX_> *array, T item) { return Dqn_FixedArray_Add(array, item); }
|
|
||||||
template <typename T, int MAX_> void Dqn_FixedStack_Clear(Dqn_FixedStack<T, MAX_> *array) { Dqn_FixedArray_Clear(array); }
|
|
||||||
DQN_HEADER_COPY_END
|
|
||||||
|
|
||||||
// @ -------------------------------------------------------------------------------------------------
|
// @ -------------------------------------------------------------------------------------------------
|
||||||
// @
|
// @
|
||||||
// @ NOTE: Dqn_Array
|
// @ NOTE: Dqn_Array
|
||||||
@ -1865,6 +1852,27 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amou
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b))
|
||||||
|
{
|
||||||
|
Dqn_Rect result = {};
|
||||||
|
if (a.min.x >= b.min.x && a.min.x <= b.max.x) result.min.x = a.min.x;
|
||||||
|
else if (b.min.x >= a.min.x && b.min.x <= a.max.x) result.min.x = b.min.x;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.max.x >= b.min.x && a.max.x <= b.max.x) result.max.x = a.max.x;
|
||||||
|
else if (b.max.x >= a.min.x && b.max.x <= a.max.x) result.max.x = b.max.x;
|
||||||
|
|
||||||
|
if (a.min.y >= b.min.y && a.min.y <= b.max.y) result.min.y = a.min.y;
|
||||||
|
else if (b.min.y >= a.min.y && b.min.y <= a.max.y) result.min.y = b.min.y;
|
||||||
|
|
||||||
|
if (a.max.y >= b.min.y && a.max.y <= b.max.y) result.max.y = a.max.y;
|
||||||
|
else if (b.max.y >= a.min.y && b.max.y <= a.max.y) result.max.y = b.max.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b))
|
DQN_HEADER_COPY_PROTOTYPE(Dqn_Rect, Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b))
|
||||||
{
|
{
|
||||||
Dqn_Rect result = {};
|
Dqn_Rect result = {};
|
||||||
@ -2157,7 +2165,7 @@ DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_FindMulti(char const *buf, char
|
|||||||
if (buf_len < 0) buf_len = (Dqn_isize)strlen(buf);
|
if (buf_len < 0) buf_len = (Dqn_isize)strlen(buf);
|
||||||
|
|
||||||
char const *buf_end = buf + buf_len;
|
char const *buf_end = buf + buf_len;
|
||||||
for (; *buf; ++buf)
|
for (; buf != buf_end; ++buf)
|
||||||
{
|
{
|
||||||
Dqn_isize remaining = static_cast<Dqn_isize>(buf_end - buf);
|
Dqn_isize remaining = static_cast<Dqn_isize>(buf_end - buf);
|
||||||
DQN_FOR_EACH(find_index, find_len)
|
DQN_FOR_EACH(find_index, find_len)
|
||||||
@ -2186,7 +2194,7 @@ DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_Find(char const *buf, char const
|
|||||||
|
|
||||||
char const *buf_end = buf + buf_len;
|
char const *buf_end = buf + buf_len;
|
||||||
char const *result = nullptr;
|
char const *result = nullptr;
|
||||||
for (; *buf; ++buf)
|
for (; buf != buf_end; ++buf)
|
||||||
{
|
{
|
||||||
Dqn_isize remaining = static_cast<Dqn_isize>(buf_end - buf);
|
Dqn_isize remaining = static_cast<Dqn_isize>(buf_end - buf);
|
||||||
if (remaining < find_len) break;
|
if (remaining < find_len) break;
|
||||||
|
@ -273,6 +273,138 @@ FILE_SCOPE void UnitTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// NOTE: Dqn_Rect
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_Rect");
|
||||||
|
// NOTE: Dqn_Rect_Intersection
|
||||||
|
{
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "No intersection");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2(0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2(200, 0), Dqn_V2(200, 200));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 0 && ab.min.y == 0 && ab.max.x == 0 && ab.max.y == 0,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "A's min intersects B");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2(50, 50), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 50 && ab.min.y == 50 && ab.max.x == 100 && ab.max.y == 100,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "B's min intersects A");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2(50, 50), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 50 && ab.min.y == 50 && ab.max.x == 100 && ab.max.y == 100,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "A's max intersects B");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2(-50, -50), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 0 && ab.min.y == 0 && ab.max.x == 50 && ab.max.y == 50,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "B's max intersects A");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2(-50, -50), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 0 && ab.min.y == 0 && ab.max.x == 50 && ab.max.y == 50,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "B contains A");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2(25, 25), Dqn_V2( 25, 25));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 25 && ab.min.y == 25 && ab.max.x == 50 && ab.max.y == 50,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "A contains B");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2( 0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = Dqn_Rect_InitFromPosAndSize(Dqn_V2(25, 25), Dqn_V2( 25, 25));
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 25 && ab.min.y == 25 && ab.max.x == 50 && ab.max.y == 50,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "A equals B");
|
||||||
|
Dqn_Rect a = Dqn_Rect_InitFromPosAndSize(Dqn_V2(0, 0), Dqn_V2(100, 100));
|
||||||
|
Dqn_Rect b = a;
|
||||||
|
Dqn_Rect ab = Dqn_Rect_Intersection(a, b);
|
||||||
|
|
||||||
|
TEST_EXPECT_MSG(testing_state,
|
||||||
|
ab.min.x == 0 && ab.min.y == 0 && ab.max.x == 100 && ab.max.y == 100,
|
||||||
|
"ab = { min.x = %.2f, min.y = %.2f, max.x = %.2f. max.y = %.2f }",
|
||||||
|
ab.min.x,
|
||||||
|
ab.min.y,
|
||||||
|
ab.max.x,
|
||||||
|
ab.max.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// NOTE: Dqn_StringBuilder
|
// NOTE: Dqn_StringBuilder
|
||||||
@ -606,6 +738,31 @@ FILE_SCOPE void UnitTests()
|
|||||||
TEST_EXPECT(testing_state, result == 12);
|
TEST_EXPECT(testing_state, result == 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// NOTE: Dqn_Str_Find
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_Str_Find");
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "String (char) is not in buffer");
|
||||||
|
char const buf[] = "836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55";
|
||||||
|
char const find[] = "2";
|
||||||
|
char const *result = Dqn_Str_Find(buf, find, Dqn_CharCountI(buf), Dqn_CharCountI(find));
|
||||||
|
TEST_EXPECT(testing_state, result == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TEST_START_SCOPE(testing_state, "String (char) is in buffer");
|
||||||
|
char const buf[] = "836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55";
|
||||||
|
char const find[] = "6";
|
||||||
|
char const *result = Dqn_Str_Find(buf, find, Dqn_CharCountI(buf), Dqn_CharCountI(find));
|
||||||
|
TEST_EXPECT(testing_state, result != nullptr);
|
||||||
|
TEST_EXPECT(testing_state, result[0] == '6' && result[1] == 'a');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
Loading…
Reference in New Issue
Block a user