Dqn_Rect_Intersection, remove Dqn_FixedStack, minor fixes

This commit is contained in:
doyle 2020-01-18 02:01:25 +11:00
parent 4bd8691076
commit f67d97ec3d
2 changed files with 187 additions and 22 deletions

View File

@ -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;

View File

@ -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[])