4 Commits f96bc947c4 ... dd9cc95647

Autor SHA1 Mensaje Fecha
  Kajetan Johannes Hammerle dd9cc95647 Test struct in list, swap args for struct init hace 2 semanas
  Kajetan Johannes Hammerle 1288021d4b Cast vectors in tests hace 2 semanas
  Kajetan Johannes Hammerle 878b975652 Enforce init makros hace 2 semanas
  Kajetan Johannes Hammerle d9e3c74f38 List and tests hace 2 semanas

+ 3 - 2
CMakeLists.txt

@@ -7,6 +7,7 @@ set(SRC
     "src/Box.c"
     "src/Buffer.c"
     "src/Frustum.c"
+    "src/List.c"
     "src/Logger.c"
     "src/Matrix.c"
     "src/Plane.c"
@@ -25,6 +26,7 @@ set(SRC_TESTS
     "test/modules/BoxTests.c"
     "test/modules/BufferTests.c"
     "test/modules/FrustumTests.c"
+    "test/modules/ListTests.c"
     "test/modules/MatrixTests.c"
     "test/modules/PlaneTests.c"
     "test/modules/QuaternionTests.c"
@@ -37,7 +39,6 @@ set(SRC_TESTS
     #"test/modules/ComponentsTests.cpp"
     #"test/modules/HashMapTests.cpp"
     #"test/modules/LinkedListTests.cpp"
-    #"test/modules/ListTests.cpp"
     #"test/modules/MatrixStackTests.cpp"
     #"test/modules/RingBufferTests.cpp"
     #"test/modules/StackTests.cpp"
@@ -100,6 +101,7 @@ target_sources(core PUBLIC
         ./include/core/Buffer.h
         ./include/core/Check.h
         ./include/core/Frustum.h
+        ./include/core/List.h
         ./include/core/Logger.h
         ./include/core/Matrix.h
         ./include/core/Plane.h
@@ -113,7 +115,6 @@ target_sources(core PUBLIC
 #        ./include/core/Components.hpp
 #        ./include/core/HashMap.hpp
 #        ./include/core/LinkedList.hpp
-#        ./include/core/List.hpp
 #        ./include/core/MatrixStack.hpp
 #        ./include/core/ProbingHashMap.hpp
 #        ./include/core/RingBuffer.hpp

+ 1 - 0
include/core/Box.h

@@ -8,6 +8,7 @@ typedef struct {
     CoreVector3 max;
 } CoreBox;
 
+#define CORE_BOX ((CoreBox){0})
 CoreBox* coreSetBox(CoreBox* box, const CoreVector3* size);
 CoreBox* coreOffsetBox(CoreBox* box, const CoreVector3* offset);
 bool coreCollidesWithBox(const CoreBox* box, const CoreBox* other);

+ 36 - 0
include/core/List.h

@@ -0,0 +1,36 @@
+#ifndef CORE_LIST_H
+#define CORE_LIST_H
+
+#include "core/Types.h"
+
+typedef struct {
+    size_t length;
+    size_t capacity;
+    size_t dataSize;
+    void* data;
+} CoreList;
+
+#define CORE_LIST(dataSize) ((CoreList){0, 0, dataSize, nullptr})
+void coreCopyList(CoreList* l, const CoreList* other);
+void coreMoveList(CoreList* l, CoreList* other);
+void coreDestroyList(CoreList* l);
+void coreListReserve(CoreList* l, size_t n);
+void coreShrinkList(CoreList* l);
+void coreResizeList(CoreList* l, size_t n);
+void coreResizeListPointer(CoreList* l, size_t n, const void* data);
+#define coreResizeListV(l, n, type, ...)                                       \
+    coreResizeListPointer(l, n, &(type){__VA_ARGS__})
+CoreList* coreListAddPointer(CoreList* l, const void* data);
+#define coreListAdd(l, type, ...) coreListAddPointer(l, &(type){__VA_ARGS__})
+void* coreListGetPointer(CoreList* l, size_t index);
+#define coreListGet(l, index, type) *(type*)coreListGetPointer(l, index)
+const void* coreListGetPointerC(const CoreList* l, size_t index);
+#define coreListGetC(l, index, type) *(const type*)coreListGetPointerC(l, index)
+void coreClearList(CoreList* l);
+void coreListRemoveBySwap(CoreList* l, size_t index);
+void coreListRemove(CoreList* l, size_t index);
+void coreListRemoveLast(CoreList* l);
+size_t coreToStringList(CoreList* l, char* buffer, size_t n, CoreToString c);
+void coreSwapList(CoreList* a, CoreList* b);
+
+#endif

+ 2 - 0
include/core/Types.h

@@ -14,4 +14,6 @@ typedef uint16_t u16;
 typedef uint8_t u8;
 #define CORE_ARRAY_LENGTH(array) (sizeof(array) / sizeof(*array))
 
+typedef size_t (*CoreToString)(const void* data, char* buffer, size_t n);
+
 #endif

+ 24 - 0
include/core/Utility.h

@@ -10,6 +10,30 @@ size_t corePopCount(u64 u);
 #define coreRadianToDegree(radians) (radians * (180.0f / CORE_PI))
 #define coreDegreeToRadian(degrees) (degrees * (CORE_PI / 180.0f))
 
+inline size_t coreMaxSize(size_t a, size_t b) {
+    return a > b ? a : b;
+}
+
+inline size_t coreMinSize(size_t a, size_t b) {
+    return a < b ? a : b;
+}
+
+#define CORE_SWAP(a, b, type)                                                  \
+    {                                                                          \
+        type tmp = *a;                                                         \
+        *a = *b;                                                               \
+        *b = tmp;                                                              \
+    }
+
+inline void coreSwapSize(size_t* a, size_t* b) {
+    CORE_SWAP(a, b, size_t)
+}
+inline void coreSwapPointer(void** a, void** b){CORE_SWAP(a, b, void*)}
+
+size_t coreToStringSize(const void* p, char* buffer, size_t n);
+void coreStringAdd(size_t* w, char** buffer, size_t* n, size_t shift);
+void coreStringAddI(size_t* w, char** buffer, size_t* n, int shift);
+
 typedef void (*CoreExitHandler)(int, void*);
 [[noreturn]] void coreExitWithHandler(const char* file, int line, int value);
 void coreSetExitHandler(CoreExitHandler h, void* data);

+ 7 - 0
include/core/Vector.h

@@ -53,4 +53,11 @@ CORE_DEFINE_VECTOR_CONVERSION(CoreVector2, V2, CoreIntVector2, IV2);
 CORE_DEFINE_VECTOR_CONVERSION(CoreVector3, V3, CoreIntVector3, IV3);
 CORE_DEFINE_VECTOR_CONVERSION(CoreVector4, V4, CoreIntVector4, IV4);
 
+#define CORE_VECTOR2 ((CoreVector2){0})
+#define CORE_VECTOR3 ((CoreVector3){0})
+#define CORE_VECTOR4 ((CoreVector4){0})
+#define CORE_INT_VECTOR2 ((CoreIntVector2){0})
+#define CORE_INT_VECTOR3 ((CoreIntVector3){0})
+#define CORE_INT_VECTOR4 ((CoreIntVector4){0})
+
 #endif

+ 3 - 3
src/Box.c

@@ -42,11 +42,11 @@ CoreBox* coreExpandBox(CoreBox* box, const CoreVector3* offset) {
 }
 
 CoreBox* coreGrowBox(CoreBox* box, const CoreVector3* growth) {
-    CoreVector3 half = {0};
+    CoreVector3 half = CORE_VECTOR3;
     coreMulV3F(&half, growth, 0.5f);
-    CoreVector3 nMin = {0};
+    CoreVector3 nMin = CORE_VECTOR3;
     coreSubV3(&nMin, &box->min, &half);
-    CoreVector3 nMax = {0};
+    CoreVector3 nMax = CORE_VECTOR3;
     coreAddV3(&nMax, &box->max, &half);
     for(size_t i = 0; i < 3; i++) {
         if(nMin.data[i] > nMax.data[i]) {

+ 2 - 2
src/Frustum.c

@@ -5,13 +5,13 @@
 
 #include "core/Utility.h"
 
-#define CV30 (&(CoreVector3){0})
+#define CV30 (&CORE_VECTOR3)
 #define CV4(a, b, c, d) ((CoreVector4){{a, b, c, d}})
 
 CoreFrustum* coreInitFrustum(CoreFrustum* f, float fieldOfView, float nearClip,
                              float farClip) {
     for(size_t i = 0; i < CORE_ARRAY_LENGTH(f->planes); i++) {
-        f->planes[i] = (CorePlane){0};
+        f->planes[i] = CORE_PLANE;
     }
     f->tan = tanf(coreDegreeToRadian(fieldOfView) * 0.5f);
     f->nearClip = nearClip;

+ 185 - 0
src/List.c

@@ -0,0 +1,185 @@
+#include "core/List.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "core/Utility.h"
+
+static void ensureCapacity(CoreList* l) {
+    if(l->length >= l->capacity) {
+        coreListReserve(l, l->capacity + coreMaxSize(4lu, l->capacity / 4));
+    }
+}
+
+static void setSize(CoreList* l, size_t n) {
+    l->capacity = n;
+    l->data = coreReallocate(l->data, l->dataSize * n);
+}
+
+static void* getPointer(CoreList* l, size_t index) {
+    return (char*)l->data + (l->dataSize * index);
+}
+
+static const void* getPointerC(const CoreList* l, size_t index) {
+    return (const char*)l->data + (l->dataSize * index);
+}
+
+void coreCopyList(CoreList* l, const CoreList* other) {
+    if(l == other) {
+        return;
+    }
+    coreDestroyList(l);
+    l->length = other->length;
+    l->dataSize = other->dataSize;
+    setSize(l, other->capacity);
+    memcpy(l->data, other->data, l->dataSize * l->length);
+}
+
+void coreMoveList(CoreList* l, CoreList* other) {
+    if(l == other) {
+        return;
+    }
+    coreSwapList(l, other);
+    coreDestroyList(other);
+}
+
+void coreDestroyList(CoreList* l) {
+    coreFree(l->data);
+    *l = CORE_LIST(0);
+}
+
+void coreListReserve(CoreList* l, size_t n) {
+    if(n > l->capacity) {
+        setSize(l, n);
+    }
+}
+
+void coreShrinkList(CoreList* l) {
+    if(l->length != l->capacity) {
+        setSize(l, l->length);
+    }
+}
+
+void coreResizeList(CoreList* l, size_t n) {
+    if(l->length < n) {
+        coreListReserve(l, n);
+        memset(getPointer(l, l->length), 0, (n - l->length) * l->dataSize);
+    }
+    l->length = n;
+}
+
+void coreResizeListPointer(CoreList* l, size_t n, const void* data) {
+    if(l->length < n) {
+        coreListReserve(l, n);
+        while(l->length < n) {
+            coreListAddPointer(l, data);
+        }
+    } else if(l->length > n) {
+        l->length = n;
+    }
+}
+
+CoreList* coreListAddPointer(CoreList* l, const void* data) {
+    ensureCapacity(l);
+    memcpy(getPointer(l, l->length++), data, l->dataSize);
+    return l;
+}
+
+void* coreListGetPointer(CoreList* l, size_t index) {
+    assert(index < l->length);
+    return getPointer(l, index);
+}
+
+const void* coreListGetPointerC(const CoreList* l, size_t index) {
+    assert(index < l->length);
+    return getPointerC(l, index);
+}
+
+void coreClearList(CoreList* l) {
+    l->length = 0;
+}
+
+void coreListRemoveBySwap(CoreList* l, size_t index) {
+    assert(index < l->length);
+    size_t length = l->length - 1;
+    if(index != length) {
+        memcpy(coreListGetPointer(l, index), coreListGetPointer(l, length),
+               l->dataSize);
+    }
+    l->length = length;
+}
+
+void coreListRemove(CoreList* l, size_t index) {
+    assert(index < l->length);
+    l->length--;
+    char* p = getPointer(l, index);
+    char* end = getPointer(l, l->length);
+    while(p != end) {
+        *p = *(p + l->dataSize);
+        p++;
+    }
+}
+
+void coreListRemoveLast(CoreList* l) {
+    coreListRemoveBySwap(l, l->length - 1);
+}
+
+size_t coreToStringList(CoreList* l, char* buffer, size_t n, CoreToString c) {
+    size_t w = 0;
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "["));
+    char* end = getPointer(l, l->length);
+    char* p = l->data;
+    while(p != end) {
+        coreStringAdd(&w, &buffer, &n, c(p, buffer, n));
+        p += l->dataSize;
+        if(p != end) {
+            coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, ", "));
+        }
+    }
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "]"));
+    return w;
+}
+
+void coreSwapList(CoreList* a, CoreList* b) {
+    coreSwapSize(&a->length, &b->length);
+    coreSwapSize(&a->capacity, &b->capacity);
+    coreSwapSize(&a->dataSize, &b->dataSize);
+    coreSwapPointer(&a->data, &b->data);
+}
+
+/*
+    T* begin() {
+        return data;
+    }
+
+    T* end() {
+        return data + length;
+    }
+
+    const T* begin() const {
+        return data;
+    }
+
+    const T* end() const {
+        return data + length;
+    }
+
+    void resize(size_t n) {
+        if(length < n) {
+            reserve(n);
+            for(size_t i = n - length; i != 0; i--) {
+                unsafeAdd(T());
+            }
+        } else if(length > n) {
+            for(size_t i = n; i < length; i++) {
+                data[i].~T();
+            }
+            length = n;
+        }
+    }
+
+    void toString(BufferString& s) const {
+        Core::toString(s, *this);
+    }
+};*/

+ 12 - 34
src/Matrix.c

@@ -6,7 +6,7 @@
 #include "core/Utility.h"
 
 CoreMatrix* coreTransposeMatrix(CoreMatrix* m) {
-    CoreMatrix c = {0};
+    CoreMatrix c = CORE_ZERO_MATRIX;
     for(size_t x = 0; x < 4; x++) {
         for(size_t y = 0; y < 4; y++) {
             c.data[x].data[y] = m->data[y].data[x];
@@ -16,11 +16,11 @@ CoreMatrix* coreTransposeMatrix(CoreMatrix* m) {
     return m;
 }
 
-#define CV40 (&(CoreVector4){0})
+#define CV40 (&CORE_VECTOR4)
 
 CoreMatrix* coreMulSetMatrix(CoreMatrix* m, const CoreMatrix* a) {
     for(int i = 0; i < 4; i++) {
-        CoreVector4 d = {0};
+        CoreVector4 d = CORE_VECTOR4;
         coreAddSetV4(&d, coreMulV4F(CV40, a->data + 0, m->data[i].data[0]));
         coreAddSetV4(&d, coreMulV4F(CV40, a->data + 1, m->data[i].data[1]));
         coreAddSetV4(&d, coreMulV4F(CV40, a->data + 2, m->data[i].data[2]));
@@ -132,41 +132,19 @@ CoreMatrix* coreRotateMatrix(CoreMatrix* m, const CoreQuaternion* q) {
     m->data[0] = (CoreVector4){{a.data[0], b.data[0], c.data[0], d.data[0]}};
     m->data[1] = (CoreVector4){{a.data[1], b.data[1], c.data[1], d.data[1]}};
     m->data[2] = (CoreVector4){{a.data[2], b.data[2], c.data[2], d.data[2]}};
-
-    //    Vector3 a = q * Vector3(data[0][0], data[1][0], data[2][0]);
-    //    Vector3 b = q * Vector3(data[0][1], data[1][1], data[2][1]);
-    //    Vector3 c = q * Vector3(data[0][2], data[1][2], data[2][2]);
-    //    Vector3 d = q * Vector3(data[0][3], data[1][3], data[2][3]);
-    //    set(0, Vector4(a[0], b[0], c[0], d[0]));
-    //    set(1, Vector4(a[1], b[1], c[1], d[1]));
-    //    set(2, Vector4(a[2], b[2], c[2], d[2]));
     return m;
 }
 
-static void add(size_t* w, char** buffer, size_t* n, size_t shift) {
-    *w += shift;
-    if(*n > shift) {
-        *buffer += shift;
-        *n -= shift;
-    } else {
-        *n = 0;
-    }
-}
-
-static void addI(size_t* w, char** buffer, size_t* n, int shift) {
-    add(w, buffer, n, shift < 0 ? 0 : (size_t)shift);
-}
-
 size_t coreToStringMatrix(const CoreMatrix* m, char* buffer, size_t n) {
     size_t w = 0;
-    addI(&w, &buffer, &n, snprintf(buffer, n, "["));
-    add(&w, &buffer, &n, coreToStringV4(m->data + 0, buffer, n));
-    addI(&w, &buffer, &n, snprintf(buffer, n, ", "));
-    add(&w, &buffer, &n, coreToStringV4(m->data + 1, buffer, n));
-    addI(&w, &buffer, &n, snprintf(buffer, n, ", "));
-    add(&w, &buffer, &n, coreToStringV4(m->data + 2, buffer, n));
-    addI(&w, &buffer, &n, snprintf(buffer, n, ", "));
-    add(&w, &buffer, &n, coreToStringV4(m->data + 3, buffer, n));
-    addI(&w, &buffer, &n, snprintf(buffer, n, "]"));
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "["));
+    coreStringAdd(&w, &buffer, &n, coreToStringV4(m->data + 0, buffer, n));
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, ", "));
+    coreStringAdd(&w, &buffer, &n, coreToStringV4(m->data + 1, buffer, n));
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, ", "));
+    coreStringAdd(&w, &buffer, &n, coreToStringV4(m->data + 2, buffer, n));
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, ", "));
+    coreStringAdd(&w, &buffer, &n, coreToStringV4(m->data + 3, buffer, n));
+    coreStringAddI(&w, &buffer, &n, snprintf(buffer, n, "]"));
     return w;
 }

+ 1 - 1
src/Plane.c

@@ -2,7 +2,7 @@
 
 #include <stdio.h>
 
-#define CV30 (&(CoreVector3){0})
+#define CV30 (&CORE_VECTOR3)
 
 CorePlane* coreInitPlane(CorePlane* p, const CoreVector3* a,
                          const CoreVector3* b, const CoreVector3* c) {

+ 1 - 1
src/Quaternion.c

@@ -5,7 +5,7 @@
 
 #include "core/Utility.h"
 
-#define CV30 (&(CoreVector3){0})
+#define CV30 (&CORE_VECTOR3)
 
 CoreQuaternion* coreAxisAngleQ(CoreQuaternion* q, const CoreVector3* axis,
                                float angle) {

+ 1 - 1
src/SpinLock.c

@@ -12,7 +12,7 @@ void coreLockSpinLock(CoreSpinLock* l) {
         if(atomic_compare_exchange_weak(&l->lock, &expected, true)) {
             break;
         }
-        struct timespec s = {0};
+        struct timespec s = {.tv_nsec = 0, .tv_sec = 0};
         thrd_sleep(&s, nullptr);
     }
 }

+ 24 - 0
src/Utility.c

@@ -9,6 +9,11 @@
 #include "ErrorSimulator.h"
 #include "core/Logger.h"
 
+extern inline size_t coreMaxSize(size_t a, size_t b);
+extern inline size_t coreMinSize(size_t a, size_t b);
+extern inline void coreSwapSize(size_t* a, size_t* b);
+extern inline void coreSwapPointer(void** a, void** b);
+
 static CoreExitHandler exitHandler = nullptr;
 static void* exitData = nullptr;
 static CoreOutOfMemoryHandler outOfMemoryHandler = nullptr;
@@ -23,6 +28,25 @@ size_t corePopCount(u64 u) {
     return sum;
 }
 
+size_t coreToStringSize(const void* p, char* buffer, size_t n) {
+    int w = snprintf(buffer, n, "%zu", *(const size_t*)p);
+    return w < 0 ? 0 : (size_t)w;
+}
+
+void coreStringAdd(size_t* w, char** buffer, size_t* n, size_t shift) {
+    *w += shift;
+    if(*n > shift) {
+        *buffer += shift;
+        *n -= shift;
+    } else {
+        *n = 0;
+    }
+}
+
+void coreStringAddI(size_t* w, char** buffer, size_t* n, int shift) {
+    coreStringAdd(w, buffer, n, shift < 0 ? 0 : (size_t)shift);
+}
+
 [[noreturn]] void coreExitWithHandler(const char* file, int line, int value) {
     if(value != 0) {
         file = coreGetShortFileName(file);

+ 1 - 1
test/Main.c

@@ -35,13 +35,13 @@ int main(int argAmount, const char** args) {
     // coreTestComponents();
     // coreTestHashMap(light);
     // coreTestLinkedList(light);
-    // coreTestList(light);
     // coreTestMatrixStack(light);
     // coreTestRingBuffer();
     // coreTestStack(light);
     coreTestBox();
     coreTestBuffer(light);
     coreTestFrustum();
+    coreTestList(light);
     coreTestMatrix();
     coreTestPlane();
     coreTestQuaternion();

+ 10 - 6
test/Test.h

@@ -40,20 +40,24 @@ bool coreTestNotNull(CORE_TEST_ARGS, const void* p);
 
 bool coreTestVectorN(CORE_TEST_ARGS, const float* wanted, const float* actual,
                      size_t n);
+#define CORE_TEST_VN(wanted, actual, n)                                        \
+    coreTestVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, n)
 #define CORE_TEST_V2(wanted, actual)                                           \
-    coreTestVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 2)
+    CORE_TEST_VN((CoreVector2*)(wanted), (CoreVector2*)(actual), 2)
 #define CORE_TEST_V3(wanted, actual)                                           \
-    coreTestVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 3)
+    CORE_TEST_VN((CoreVector3*)(wanted), (CoreVector3*)(actual), 3)
 #define CORE_TEST_V4(wanted, actual)                                           \
-    coreTestVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 4)
+    CORE_TEST_VN((CoreVector4*)(wanted), (CoreVector4*)(actual), 4)
 
 bool coreTestIntVectorN(CORE_TEST_ARGS, const int* wanted, const int* actual,
                         size_t n);
+#define CORE_TEST_IVN(wanted, actual, n)                                       \
+    coreTestIntVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, n)
 #define CORE_TEST_IV2(wanted, actual)                                          \
-    coreTestIntVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 2)
+    CORE_TEST_IVN((CoreIntVector2*)(wanted), (CoreIntVector2*)(actual), 2)
 #define CORE_TEST_IV3(wanted, actual)                                          \
-    coreTestIntVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 3)
+    CORE_TEST_IVN((CoreIntVector3*)(wanted), (CoreIntVector3*)(actual), 3)
 #define CORE_TEST_IV4(wanted, actual)                                          \
-    coreTestIntVectorN(__FILE__, __LINE__, (wanted)->data, (actual)->data, 4)
+    CORE_TEST_IVN((CoreIntVector4*)(wanted), (CoreIntVector4*)(actual), 4)
 
 #endif

+ 7 - 7
test/modules/BoxTests.c

@@ -4,7 +4,7 @@
 #define CV3(a, b, c) (&(CoreVector3){{a, b, c}})
 
 static void testInit() {
-    CoreBox box = {0};
+    CoreBox box = CORE_BOX;
     coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
     char buffer[128];
     coreToStringBox(&box, buffer, sizeof(buffer));
@@ -26,7 +26,7 @@ static void testInit() {
 }
 
 static void testOffset() {
-    CoreBox box = {0};
+    CoreBox box = CORE_BOX;
     coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
     coreOffsetBox(&box, CV3(7.0f, -4.0f, 6.0f));
     char buffer[128];
@@ -36,11 +36,11 @@ static void testOffset() {
 }
 
 static void testCollidesWith() {
-    CoreBox boxA = {0};
+    CoreBox boxA = CORE_BOX;
     coreSetBox(&boxA, CV3(1.0f, 2.0f, 3.0f));
-    CoreBox boxB = {0};
+    CoreBox boxB = CORE_BOX;
     coreSetBox(&boxB, CV3(-1.0f, -2.0f, -3.0f));
-    CoreBox boxC = {0};
+    CoreBox boxC = CORE_BOX;
     coreSetBox(&boxC, CV3(2.0f, 2.0f, 2.0f));
     coreOffsetBox(&boxC, CV3(-1.0f, -1.0f, -1.0f));
 
@@ -53,7 +53,7 @@ static void testCollidesWith() {
 }
 
 static void testExpand() {
-    CoreBox box = {0};
+    CoreBox box = CORE_BOX;
     coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
     coreExpandBox(&box, CV3(7.0f, -4.0f, 6.0f));
 
@@ -70,7 +70,7 @@ static void testExpand() {
 }
 
 static void testGrow() {
-    CoreBox box = {0};
+    CoreBox box = CORE_BOX;
     coreSetBox(&box, CV3(1.0f, 2.0f, 3.0f));
     coreGrowBox(&box, CV3(4.0f, 2.0f, 6.0f));
     char buffer[128];

+ 4 - 4
test/modules/FrustumTests.c

@@ -4,7 +4,7 @@
 #define CV3(a, b, c) (&(CoreVector3){{a, b, c}})
 
 static void testToString() {
-    CoreFrustum f = {0};
+    CoreFrustum f;
     coreInitFrustum(&f, 60.0f, 0.1f, 1000.0f);
     char buffer[128];
     coreToStringFrustum(&f, buffer, sizeof(buffer));
@@ -14,7 +14,7 @@ static void testToString() {
 
 static void testPointIsInside() {
     CoreIntVector2 size = {{200, 100}};
-    CoreFrustum f = {0};
+    CoreFrustum f;
     coreInitFrustum(&f, 60.0f, 0.1f, 1000.0f);
     coreUpdateFrustumPlanes(&f, CV3(0, 0, 0), CV3(1, 0, 0), CV3(0, 1, 0),
                             CV3(0, 0, 1), &size);
@@ -30,7 +30,7 @@ static void testPointIsInside() {
 
 static void testSphereIsInside() {
     CoreIntVector2 size = {{200, 100}};
-    CoreFrustum f = {0};
+    CoreFrustum f;
     coreInitFrustum(&f, 60.0f, 0.1f, 1000.0f);
     coreUpdateFrustumPlanes(&f, CV3(0, 0, 0), CV3(1, 0, 0), CV3(0, 1, 0),
                             CV3(0, 0, 1), &size);
@@ -53,7 +53,7 @@ static void testSphereIsInside() {
 }
 
 static void testUpdateProjection() {
-    CoreFrustum f = {0};
+    CoreFrustum f;
     coreInitFrustum(&f, 60.0f, 0.1f, 1000.0f);
     const CoreMatrix* m =
         coreUpdateProjection(&f, &(CoreIntVector2){{400, 300}});

+ 279 - 0
test/modules/ListTests.c

@@ -0,0 +1,279 @@
+#include "../Tests.h"
+#include "core/List.h"
+#include "core/Utility.h"
+#include "core/Vector.h"
+
+static void testAdd() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 5);
+    CORE_TEST_SIZE(5, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(5, coreListGetC(&list, 0, size_t));
+    CORE_TEST_SIZE(1, list.length);
+    coreDestroyList(&list);
+}
+
+static void testMultipleAdd() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 4);
+    coreListAdd(&list, size_t, 3);
+    coreListAdd(&list, size_t, 2);
+    CORE_TEST_SIZE(4, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(3, coreListGet(&list, 1, size_t));
+    CORE_TEST_SIZE(2, coreListGet(&list, 2, size_t));
+    CORE_TEST_SIZE(4, coreListGetC(&list, 0, size_t));
+    CORE_TEST_SIZE(3, coreListGetC(&list, 1, size_t));
+    CORE_TEST_SIZE(2, coreListGetC(&list, 2, size_t));
+    CORE_TEST_SIZE(3, list.length);
+    coreDestroyList(&list);
+}
+
+static void testAddReplace() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 5);
+    coreListGet(&list, 0, size_t) = 3;
+    CORE_TEST_SIZE(3, coreListGet(&list, 0, size_t));
+    coreDestroyList(&list);
+}
+
+static void testClear() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 5);
+    coreListAdd(&list, size_t, 4);
+    coreClearList(&list);
+    CORE_TEST_SIZE(0, list.length);
+    coreDestroyList(&list);
+}
+
+static void testShrink() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 5);
+    coreListAdd(&list, size_t, 4);
+    coreListAdd(&list, size_t, 3);
+    CORE_TEST_TRUE(list.capacity >= 3);
+    coreShrinkList(&list);
+    CORE_TEST_SIZE(3, list.length);
+    CORE_TEST_SIZE(3, list.capacity);
+    CORE_TEST_SIZE(5, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(4, coreListGet(&list, 1, size_t));
+    CORE_TEST_SIZE(3, coreListGet(&list, 2, size_t));
+    coreDestroyList(&list);
+}
+
+static void testBigAdd(bool light) {
+    size_t limit = light ? 10000 : 100000;
+    CoreList list = CORE_LIST(sizeof(size_t));
+    for(size_t i = 0; i < limit; i++) {
+        coreListAdd(&list, size_t, i);
+    }
+    for(size_t i = 0; i < list.length; i++) {
+        CORE_TEST_SIZE(i, coreListGet(&list, i, size_t));
+    }
+    CORE_TEST_SIZE(limit, list.length);
+    coreDestroyList(&list);
+}
+
+static void testCopy() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 1);
+    coreListAdd(&list, size_t, 2);
+    coreListAdd(&list, size_t, 3);
+
+    CoreList copy = CORE_LIST(0);
+    coreCopyList(&copy, &list);
+    coreCopyList(&copy, &copy);
+    CORE_TEST_SIZE(list.length, copy.length);
+    size_t limit = coreMinSize(copy.length, list.length);
+    for(size_t i = 0; i < limit; i++) {
+        CORE_TEST_SIZE(coreListGet(&list, i, size_t),
+                       coreListGet(&copy, i, size_t));
+    }
+    coreDestroyList(&copy);
+    coreDestroyList(&list);
+}
+
+static void testMove() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 1);
+    coreListAdd(&list, size_t, 2);
+    coreListAdd(&list, size_t, 3);
+
+    CoreList move = CORE_LIST(0);
+    coreMoveList(&move, &list);
+    coreMoveList(&move, &move);
+    CORE_TEST_SIZE(0, list.length);
+    CORE_TEST_SIZE(3, move.length);
+    CORE_TEST_SIZE(1, coreListGet(&move, 0, size_t));
+    CORE_TEST_SIZE(2, coreListGet(&move, 1, size_t));
+    CORE_TEST_SIZE(3, coreListGet(&move, 2, size_t));
+    coreDestroyList(&move);
+}
+
+static void testToString1() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 1);
+    coreListAdd(&list, size_t, 243);
+    coreListAdd(&list, size_t, 423);
+    char buffer[128];
+    size_t n =
+        coreToStringList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(13, n);
+    CORE_TEST_STRING("[1, 243, 423]", buffer);
+    coreDestroyList(&list);
+}
+
+static void testToString2() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 1);
+    char buffer[128];
+    size_t n =
+        coreToStringList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(3, n);
+    CORE_TEST_STRING("[1]", buffer);
+    coreDestroyList(&list);
+}
+
+static void testToString3() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    char buffer[128];
+    size_t n =
+        coreToStringList(&list, buffer, sizeof(buffer), coreToStringSize);
+    CORE_TEST_SIZE(2, n);
+    CORE_TEST_STRING("[]", buffer);
+    coreDestroyList(&list);
+}
+
+static void testRemoveBySwap() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 4);
+    coreListAdd(&list, size_t, 3);
+    coreListAdd(&list, size_t, 2);
+    coreListRemoveBySwap(&list, 0);
+    CORE_TEST_SIZE(2, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(3, coreListGet(&list, 1, size_t));
+    CORE_TEST_SIZE(2, list.length);
+    coreListRemoveBySwap(&list, 1);
+    CORE_TEST_SIZE(2, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(1, list.length);
+    coreListRemoveBySwap(&list, 0);
+    CORE_TEST_SIZE(0, list.length);
+    coreDestroyList(&list);
+}
+
+static void testRemove() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 4);
+    coreListAdd(&list, size_t, 3);
+    coreListAdd(&list, size_t, 2);
+    coreListRemove(&list, 0);
+    CORE_TEST_SIZE(3, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(2, coreListGet(&list, 1, size_t));
+    CORE_TEST_SIZE(2, list.length);
+    coreListRemove(&list, 1);
+    CORE_TEST_SIZE(3, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(1, list.length);
+    coreListRemove(&list, 0);
+    CORE_TEST_SIZE(0, list.length);
+    coreDestroyList(&list);
+}
+
+static void testRemoveLast() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListAdd(&list, size_t, 4);
+    coreListAdd(&list, size_t, 3);
+    coreListAdd(&list, size_t, 2);
+    coreListRemoveLast(&list);
+    CORE_TEST_SIZE(4, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(3, coreListGet(&list, 1, size_t));
+    CORE_TEST_SIZE(2, list.length);
+    coreListRemoveLast(&list);
+    CORE_TEST_SIZE(4, coreListGet(&list, 0, size_t));
+    CORE_TEST_SIZE(1, list.length);
+    coreListRemoveLast(&list);
+    CORE_TEST_SIZE(0, list.length);
+    coreDestroyList(&list);
+}
+
+static void testResize() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreResizeListV(&list, 5, size_t, 10);
+    CORE_TEST_SIZE(5, list.length);
+    for(size_t i = 0; i < 5; i++) {
+        CORE_TEST_SIZE(10, coreListGet(&list, i, size_t));
+    }
+    coreDestroyList(&list);
+}
+
+static void testDefaultResize() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreResizeList(&list, 5);
+    CORE_TEST_SIZE(5, list.length);
+    for(size_t i = 0; i < 5; i++) {
+        CORE_TEST_SIZE(0, coreListGet(&list, i, size_t));
+    }
+    coreDestroyList(&list);
+}
+
+static void testInvalidReserve() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreListReserve(&list, 0);
+    coreDestroyList(&list);
+}
+
+static void testShrinkExact() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreResizeList(&list, 50);
+    coreShrinkList(&list);
+    coreDestroyList(&list);
+}
+
+static void testShrinkResize() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    coreResizeList(&list, 50);
+    CORE_TEST_SIZE(50, list.length);
+    coreResizeListV(&list, 20, size_t, 5);
+    CORE_TEST_SIZE(20, list.length);
+    coreResizeList(&list, 10);
+    CORE_TEST_SIZE(10, list.length);
+    coreDestroyList(&list);
+}
+
+static void testCopyEmpty() {
+    CoreList list = CORE_LIST(sizeof(size_t));
+    CoreList copy = CORE_LIST(0);
+    coreCopyList(&copy, &list);
+    coreDestroyList(&copy);
+    coreDestroyList(&list);
+}
+
+static void testStruct() {
+    CoreList list = CORE_LIST(sizeof(CoreVector3));
+    CoreVector3 v = {{1, 2, 3}};
+    coreListAddPointer(&list, &v);
+    coreListAdd(&list, CoreVector3, {2, 3, 4});
+    CORE_TEST_V3(&v, coreListGetPointer(&list, 0));
+    coreDestroyList(&list);
+}
+
+void coreTestList(bool light) {
+    testAdd();
+    testMultipleAdd();
+    testAddReplace();
+    testClear();
+    testShrink();
+    testBigAdd(light);
+    testCopy();
+    testMove();
+    testToString1();
+    testToString2();
+    testToString3();
+    testRemoveBySwap();
+    testRemove();
+    testRemoveLast();
+    testResize();
+    testDefaultResize();
+    testInvalidReserve();
+    testShrinkExact();
+    testShrinkResize();
+    testCopyEmpty();
+    testStruct();
+}

+ 2 - 2
test/modules/SpinLockTests.c

@@ -23,7 +23,7 @@ static int incrementMutexCounter(void* p) {
 static void testMutex() {
     i64 n = -coreNanos();
 
-    MutexCounter mc = {0};
+    MutexCounter mc = {.counter = 0};
     mtx_init(&mc.m, mtx_plain);
     thrd_t t[2];
     thrd_create(t + 0, incrementMutexCounter, &mc);
@@ -54,7 +54,7 @@ static int incrementSpinLockCounter(void* p) {
 static void testSpinLock() {
     i64 n = -coreNanos();
 
-    SpinLockCounter sc = {0};
+    SpinLockCounter sc = {.counter = 0};
     coreInitSpinLock(&sc.s);
     thrd_t t[2];
     thrd_create(t + 0, incrementSpinLockCounter, &sc);

+ 2 - 2
test/modules/VectorTests.c

@@ -81,7 +81,7 @@ static void testCross() {
 static void testSetAdd() {
 #define X(T)                                                                   \
     {                                                                          \
-        T v = {0};                                                             \
+        T v = *C##T(0, 0, 0, 0);                                               \
         coreAddSet##T(&v, C##T(1, 2, 3, 4));                                   \
         CORE_TEST_##T(C##T(1, 2, 3, 4), &v);                                   \
         coreAddSet##T(&v, C##T(2, 3, 4, 5));                                   \
@@ -99,7 +99,7 @@ static void testAdd() {
 static void testSetSub() {
 #define X(T)                                                                   \
     {                                                                          \
-        T v = {0};                                                             \
+        T v = *C##T(0, 0, 0, 0);                                               \
         coreSubSet##T(&v, C##T(1, 2, 3, 4));                                   \
         CORE_TEST_##T(C##T(-1, -2, -3, -4), &v);                               \
         coreSubSet##T(&v, C##T(2, 3, 4, 5));                                   \

+ 3 - 3
test/modules/ViewTests.c

@@ -4,7 +4,7 @@
 #define CV3(a, b, c) (&(CoreVector3){{a, b, c}})
 
 static void testFromAngles() {
-    CoreView v = {0};
+    CoreView v = CORE_VIEW;
     coreUpdateDirections(&v, 0.0f, 0.0f);
     CORE_TEST_V3(CV3(0.0f, 1.0f, 0.0f), &v.up);
     CORE_TEST_V3(CV3(0.0f, -1.0f, 0.0f), &v.down);
@@ -15,7 +15,7 @@ static void testFromAngles() {
 }
 
 static void testFromQuaternion() {
-    CoreView v = {0};
+    CoreView v = CORE_VIEW;
     coreUpdateDirectionsQ(&v, &CORE_UNIT_QUATERNION);
     CORE_TEST_V3(CV3(0.0f, 1.0f, 0.0f), &v.up);
     CORE_TEST_V3(CV3(0.0f, -1.0f, 0.0f), &v.down);
@@ -26,7 +26,7 @@ static void testFromQuaternion() {
 }
 
 static void testUpdateMatrix() {
-    CoreView v = {0};
+    CoreView v = CORE_VIEW;
     CoreMatrix* m = coreUpdateMatrix(&v, CV3(1.0f, 2.0f, 3.0f));
 
     char buffer[128];