Browse Source

Make List and Components typesafe with makro generation

Kajetan Johannes Hammerle 10 tháng trước cách đây
mục cha
commit
7f142017d1
10 tập tin đã thay đổi với 365 bổ sung387 xóa
  1. 1 2
      CMakeLists.txt
  2. 110 46
      include/core/Components.h
  3. 122 24
      include/core/List.h
  4. 0 9
      include/core/ToString.h
  5. 0 81
      src/Components.c
  6. 0 95
      src/List.c
  7. 0 17
      src/ToString.c
  8. 13 0
      test/TestInstances.c
  9. 13 10
      test/modules/ComponentsTests.c
  10. 106 103
      test/modules/ListTests.c

+ 1 - 2
CMakeLists.txt

@@ -7,10 +7,8 @@ set(SRC
     "src/BitArray.c"
     "src/Box.c"
     "src/Buffer.c"
-    "src/Components.c"
     "src/Frustum.c"
     "src/HashMap.c"
-    "src/List.c"
     "src/Logger.c"
     "src/Matrix.c"
     "src/Plane.c"
@@ -28,6 +26,7 @@ set(SRC
 
 set(SRC_TESTS
     "test/Main.c"
+    "test/TestInstances.c"
     "test/modules/BitArrayTests.c"
     "test/modules/BoxTests.c"
     "test/modules/BufferTests.c"

+ 110 - 46
include/core/Components.h

@@ -4,54 +4,118 @@
 #include "core/HashMap.h"
 #include "core/List.h"
 
-typedef size_t CoreEntity;
+LIST(size_t, Size)
 
-typedef struct {
-    CoreHashMap entityToIndex;
-    List indexToEntity;
-    List components;
-} CoreComponents;
+typedef size_t Entity;
 
-typedef struct {
-    CoreEntity entity;
-    void* component;
-} CoreComponentNode;
+#define COMPONENTS(T, N)                                                       \
+    typedef struct {                                                           \
+        CoreHashMap entityToIndex;                                             \
+        ListSize indexToEntity;                                                \
+        List##N components;                                                    \
+    } Components;                                                              \
+                                                                               \
+    typedef struct {                                                           \
+        Entity entity;                                                         \
+        T* component;                                                          \
+    } ComponentNode;                                                           \
+                                                                               \
+    typedef struct {                                                           \
+        const Entity* indexToEntity;                                           \
+        const Entity* indexToEntityEnd;                                        \
+        T* component;                                                          \
+        T* componentEnd;                                                       \
+        ComponentNode node;                                                    \
+    } ComponentIterator;                                                       \
+                                                                               \
+    void initComponents(Components* c);                                        \
+    void destroyComponents(Components* c);                                     \
+    T* getOrAddComponent(Components* c, Entity e);                             \
+    T* searchComponent(Components* c, Entity e);                               \
+    bool removeComponent(Components* c, Entity e);                             \
+    void initComponentIterator(ComponentIterator* ci, Components* c);          \
+    bool hasNextComponentNode(ComponentIterator* ci);                          \
+    ComponentNode* nextComponentNode(ComponentIterator* ci);                   \
+    T* getComponentsStart(Components* c);                                      \
+    T* getComponentsEnd(Components* c);
 
-typedef struct {
-    const CoreEntity* indexToEntity;
-    const CoreEntity* indexToEntityEnd;
-    void* component;
-    void* componentEnd;
-    size_t componentSize;
-    CoreComponentNode node;
-} CoreComponentIterator;
-
-void coreInitComponents(CoreComponents* c, size_t componentSize);
-void coreDestroyComponents(CoreComponents* c);
-void* coreGetOrAddComponent(CoreComponents* c, CoreEntity e);
-void* coreSearchComponent(CoreComponents* c, CoreEntity e);
-bool coreRemoveComponent(CoreComponents* c, CoreEntity e);
-void coreInitComponentIterator(CoreComponentIterator* ci, CoreComponents* c);
-bool coreHasNextComponentNode(CoreComponentIterator* ci);
-CoreComponentNode* coreNextComponentNode(CoreComponentIterator* ci);
-void* coreGetComponentsStart(CoreComponents* c);
-void* coreGetComponentsEnd(CoreComponents* c);
-
-#ifdef IMPORT_CORE
-#define Entity CoreEntity
-#define Components CoreComponents
-#define ComponentNode CoreComponentNode
-#define ComponentIterator CoreComponentIterator
-#define initComponents coreInitComponents
-#define destroyComponents coreDestroyComponents
-#define getOrAddComponent coreGetOrAddComponent
-#define searchComponent coreSearchComponent
-#define removeComponent coreRemoveComponent
-#define initComponentIterator coreInitComponentIterator
-#define hasNextComponentNode coreHasNextComponentNode
-#define nextComponentNode coreNextComponentNode
-#define getComponentsStart coreGetComponentsStart
-#define getComponentsEnd coreGetComponentsEnd
-#endif
+#define COMPONENTS_SOURCE(T, N)                                                \
+    void initComponents(Components* c) {                                       \
+        coreInitHashMap(&c->entityToIndex, sizeof(Entity), sizeof(size_t));    \
+        initListSize(&c->indexToEntity);                                       \
+        initList##N(&c->components);                                           \
+    }                                                                          \
+                                                                               \
+    void destroyComponents(Components* c) {                                    \
+        coreDestroyHashMap(&c->entityToIndex);                                 \
+        destroyListSize(&c->indexToEntity);                                    \
+        destroyList##N(&c->components);                                        \
+    }                                                                          \
+                                                                               \
+    T* getOrAddComponent(Components* c, Entity e) {                            \
+        void* component = searchComponent(c, e);                               \
+        if(component != nullptr) {                                             \
+            return component;                                                  \
+        }                                                                      \
+        size_t index = c->components.length;                                   \
+        corePutHashMapPair(&c->entityToIndex, &e, &index);                     \
+        addListDataSize(&c->indexToEntity, e);                                 \
+        return addEmptyListData##N(&c->components);                            \
+    }                                                                          \
+                                                                               \
+    T* searchComponent(Components* c, Entity e) {                              \
+        size_t* index = coreSearchHashMapKey(&c->entityToIndex, &e);           \
+        if(index == nullptr) {                                                 \
+            return nullptr;                                                    \
+        }                                                                      \
+        return getListIndex##N(&c->components, *index);                        \
+    }                                                                          \
+                                                                               \
+    bool removeComponent(Components* c, Entity e) {                            \
+        size_t* indexP = coreSearchHashMapKey(&c->entityToIndex, &e);          \
+        if(indexP == nullptr) {                                                \
+            return false;                                                      \
+        }                                                                      \
+        size_t lastIndex = c->components.length - 1;                           \
+        size_t index = *indexP;                                                \
+        coreRemoveHashMapKey(&c->entityToIndex, &e);                           \
+        removeListIndexBySwap##N(&c->components, index);                       \
+        if(index == lastIndex) {                                               \
+            removeListIndexBySwapSize(&c->indexToEntity, index);               \
+            return true;                                                       \
+        }                                                                      \
+        Entity other = *getListIndexSize(&c->indexToEntity, lastIndex);        \
+        removeListIndexBySwapSize(&c->indexToEntity, index);                   \
+        corePutHashMapPair(&c->entityToIndex, &other, &index);                 \
+        return true;                                                           \
+    }                                                                          \
+                                                                               \
+    void initComponentIterator(ComponentIterator* ci, Components* c) {         \
+        ci->indexToEntity = getListStartSize(&c->indexToEntity);               \
+        ci->indexToEntityEnd = getListEndSize(&c->indexToEntity);              \
+        ci->component = getListStart##N(&c->components);                       \
+        ci->componentEnd = getListEnd##N(&c->components);                      \
+        ci->node = (ComponentNode){0};                                         \
+    }                                                                          \
+                                                                               \
+    bool hasNextComponentNode(ComponentIterator* ci) {                         \
+        return ci->indexToEntity != ci->indexToEntityEnd;                      \
+    }                                                                          \
+                                                                               \
+    ComponentNode* nextComponentNode(ComponentIterator* ci) {                  \
+        ci->node.component = ci->component;                                    \
+        ci->node.entity = *ci->indexToEntity;                                  \
+        ci->indexToEntity++;                                                   \
+        ci->component++;                                                       \
+        return &ci->node;                                                      \
+    }                                                                          \
+                                                                               \
+    T* getComponentsStart(Components* c) {                                     \
+        return getListStart##N(&c->components);                                \
+    }                                                                          \
+                                                                               \
+    T* getComponentsEnd(Components* c) {                                       \
+        return getListEnd##N(&c->components);                                  \
+    }
 
 #endif

+ 122 - 24
include/core/List.h

@@ -1,32 +1,130 @@
 #ifndef CORE_LIST_H
 #define CORE_LIST_H
 
+#include <assert.h>
+
+#include "core/ToString.h"
 #include "core/Types.h"
+#include "core/Utility.h"
 
-struct ListT {
-    size_t length;
-    size_t capacity;
-    size_t dataSize;
-    void* data;
-};
-typedef struct ListT List;
+#define LIST(T, N)                                                             \
+    struct ListT##N {                                                          \
+        size_t length;                                                         \
+        size_t capacity;                                                       \
+        T* data;                                                               \
+    };                                                                         \
+    typedef struct ListT##N List##N;                                           \
+                                                                               \
+    void initList##N(List##N* l);                                              \
+    void destroyList##N(List##N* l);                                           \
+    void reserveListEntries##N(List##N* l, size_t n);                          \
+    void addListData##N(List##N* l, T data);                                   \
+    void addLastListData##N(List##N* l);                                       \
+    T* addEmptyListData##N(List##N* l);                                        \
+    T* getListIndex##N(const List##N* l, size_t index);                        \
+    T* getListLast##N(const List##N* l);                                       \
+    void clearList##N(List##N* l);                                             \
+    void removeListIndexBySwap##N(List##N* l, size_t index);                   \
+    void removeListIndex##N(List##N* l, size_t index);                         \
+    void removeListLast##N(List##N* l);                                        \
+    T* getListStart##N(const List##N* l);                                      \
+    T* getListEnd##N(const List##N* l);                                        \
+    size_t toStringList##N(const List##N* l, char* buffer, size_t n,           \
+                           CoreToString c);
 
-void initList(List* l, size_t dataSize);
-void destroyList(List* l);
-void reserveListEntries(List* l, size_t n);
-void addListData(List* l, const void* data);
-#define addListType(l, type, ...) addListData(l, &(type){__VA_ARGS__})
-void addLastListData(List* l);
-void* addEmptyListData(List* l);
-void* getListIndex(const List* l, size_t index);
-#define getTypedListIndex(l, index, type) (*(type*)getListIndex(l, index))
-void* getListLast(const List* l);
-#define getTypedListLast(l, type) (*(type*)getListLast(l))
-void clearList(List* l);
-void removeListIndexBySwap(List* l, size_t index);
-void removeListIndex(List* l, size_t index);
-void removeListLast(List* l);
-void* getListStart(const List* l);
-void* getListEnd(const List* l);
+#define LIST_SOURCE(T, N)                                                      \
+    void initList##N(List##N* l) {                                             \
+        *l = (List##N){0, 0, nullptr};                                         \
+    }                                                                          \
+                                                                               \
+    void destroyList##N(List##N* l) {                                          \
+        coreFree(l->data);                                                     \
+        *l = (List##N){0};                                                     \
+    }                                                                          \
+                                                                               \
+    void reserveListEntries##N(List##N* l, size_t n) {                         \
+        if(n > l->capacity) {                                                  \
+            l->capacity = n;                                                   \
+            l->data = coreReallocate(l->data, sizeof(T) * n);                  \
+        }                                                                      \
+    }                                                                          \
+                                                                               \
+    void addListData##N(List##N* l, T data) {                                  \
+        *addEmptyListData##N(l) = data;                                        \
+    }                                                                          \
+                                                                               \
+    void addLastListData##N(List##N* l) {                                      \
+        addListData##N(l, *getListLast##N(l));                                 \
+    }                                                                          \
+                                                                               \
+    T* addEmptyListData##N(List##N* l) {                                       \
+        if(l->length >= l->capacity) {                                         \
+            reserveListEntries##N(l, l->capacity +                             \
+                                         coreMaxSize(4lu, l->capacity / 4));   \
+        }                                                                      \
+        return l->data + l->length++;                                          \
+    }                                                                          \
+                                                                               \
+    T* getListIndex##N(const List##N* l, size_t index) {                       \
+        assert(index < l->length);                                             \
+        return l->data + index;                                                \
+    }                                                                          \
+                                                                               \
+    T* getListLast##N(const List##N* l) {                                      \
+        return getListIndex##N(l, l->length - 1);                              \
+    }                                                                          \
+                                                                               \
+    void clearList##N(List##N* l) {                                            \
+        l->length = 0;                                                         \
+    }                                                                          \
+                                                                               \
+    void removeListIndexBySwap##N(List##N* l, size_t index) {                  \
+        assert(index < l->length);                                             \
+        size_t length = l->length - 1;                                         \
+        if(index != length) {                                                  \
+            l->data[index] = l->data[length];                                  \
+        }                                                                      \
+        l->length = length;                                                    \
+    }                                                                          \
+                                                                               \
+    void removeListIndex##N(List##N* l, size_t index) {                        \
+        assert(index < l->length);                                             \
+        l->length--;                                                           \
+        T* p = l->data + index;                                                \
+        T* end = getListEnd##N(l);                                             \
+        while(p != end) {                                                      \
+            *p = *(p + 1);                                                     \
+            p++;                                                               \
+        }                                                                      \
+    }                                                                          \
+                                                                               \
+    void removeListLast##N(List##N* l) {                                       \
+        removeListIndexBySwap##N(l, l->length - 1);                            \
+    }                                                                          \
+                                                                               \
+    T* getListStart##N(const List##N* l) {                                     \
+        return l->data;                                                        \
+    }                                                                          \
+                                                                               \
+    T* getListEnd##N(const List##N* l) {                                       \
+        return l->data + l->length;                                            \
+    }                                                                          \
+                                                                               \
+    size_t toStringList##N(const List##N* l, char* buffer, size_t n,           \
+                           CoreToString c) {                                   \
+        size_t w = 0;                                                          \
+        coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));          \
+        T* end = getListEnd##N(l);                                             \
+        T* p = getListStart##N(l);                                             \
+        while(p != end) {                                                      \
+            coreStringAdd(&w, &buffer, &n, c(p, buffer, n));                   \
+            p++;                                                               \
+            if(p != end) {                                                     \
+                coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, ", ")); \
+            }                                                                  \
+        }                                                                      \
+        coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, "]"));          \
+        return w;                                                              \
+    }
 
 #endif

+ 0 - 9
include/core/ToString.h

@@ -10,9 +10,6 @@ size_t coreToStringSize(const void* p, char* buffer, size_t n);
 size_t coreToStringInt(const void* p, char* buffer, size_t n);
 void coreStringAdd(size_t* w, char** buffer, size_t* n, size_t shift);
 
-struct ListT;
-size_t coreToStringList(const struct ListT* l, char* buffer, size_t n,
-                        CoreToString c);
 struct CoreQueueT;
 size_t coreToStringQueue(const struct CoreQueueT* r, char* buffer, size_t n,
                          CoreToString c);
@@ -34,7 +31,6 @@ CORE_STRUCT_TO_STRING(Plane)
 #define toStringSize coreToStringSize
 #define toStringInt coreToStringInt
 #define stringAdd coreStringAdd
-#define toStringList coreToStringList
 #define toStringQueue coreToStringQueue
 #define toStringHashMap coreToStringHashMap
 #define toStringBitArray coreToStringBitArray
@@ -49,10 +45,6 @@ CORE_STRUCT_TO_STRING(Plane)
     CORE_PAIR(const struct Core##name##T*, toString##name),                    \
         CORE_PAIR(struct Core##name##T*, toString##name)
 
-#define STRUCT_PAIR(name)                                                      \
-    CORE_PAIR(const struct name##T*, toString##name),                          \
-        CORE_PAIR(struct name##T*, toString##name)
-
 #define toString(t, ...)                                                       \
     _Generic((t),                                                              \
         char*: coreToString,                                                   \
@@ -60,7 +52,6 @@ CORE_STRUCT_TO_STRING(Plane)
         CORE_STRUCT_PAIR(Box),                                                 \
         CORE_STRUCT_PAIR(Matrix),                                              \
         CORE_STRUCT_PAIR(Plane),                                               \
-        STRUCT_PAIR(List),                                                     \
         CORE_STRUCT_PAIR(Queue),                                               \
         CORE_STRUCT_PAIR(HashMap))(t, __VA_ARGS__)
 #endif

+ 0 - 81
src/Components.c

@@ -1,81 +0,0 @@
-#define IMPORT_CORE
-#include "core/Components.h"
-
-void initComponents(Components* c, size_t componentSize) {
-    initHashMap(&c->entityToIndex, sizeof(Entity), sizeof(size_t));
-    initList(&c->indexToEntity, sizeof(Entity));
-    initList(&c->components, componentSize);
-}
-
-void destroyComponents(Components* c) {
-    destroyHashMap(&c->entityToIndex);
-    destroyList(&c->indexToEntity);
-    destroyList(&c->components);
-}
-
-void* getOrAddComponent(Components* c, Entity e) {
-    void* component = searchComponent(c, e);
-    if(component != nullptr) {
-        return component;
-    }
-    size_t index = c->components.length;
-    putHashMapPair(&c->entityToIndex, &e, &index);
-    addListData(&c->indexToEntity, &e);
-    return addEmptyListData(&c->components);
-}
-
-void* searchComponent(Components* c, Entity e) {
-    size_t* index = searchHashMapKey(&c->entityToIndex, &e);
-    if(index == nullptr) {
-        return nullptr;
-    }
-    return getListIndex(&c->components, *index);
-}
-
-bool removeComponent(Components* c, Entity e) {
-    size_t* indexP = searchHashMapKey(&c->entityToIndex, &e);
-    if(indexP == nullptr) {
-        return false;
-    }
-    size_t lastIndex = c->components.length - 1;
-    size_t index = *indexP;
-    removeHashMapKey(&c->entityToIndex, &e);
-    removeListIndexBySwap(&c->components, index);
-    if(index == lastIndex) {
-        removeListIndexBySwap(&c->indexToEntity, index);
-        return true;
-    }
-    Entity other = getTypedListIndex(&c->indexToEntity, lastIndex, Entity);
-    removeListIndexBySwap(&c->indexToEntity, index);
-    putHashMapPair(&c->entityToIndex, &other, &index);
-    return true;
-}
-
-void initComponentIterator(ComponentIterator* ci, Components* c) {
-    ci->indexToEntity = getListStart(&c->indexToEntity);
-    ci->indexToEntityEnd = getListEnd(&c->indexToEntity);
-    ci->component = getListStart(&c->components);
-    ci->componentEnd = getListEnd(&c->components);
-    ci->componentSize = c->components.dataSize;
-    ci->node = (ComponentNode){0};
-}
-
-bool hasNextComponentNode(ComponentIterator* ci) {
-    return ci->indexToEntity != ci->indexToEntityEnd;
-}
-
-ComponentNode* nextComponentNode(ComponentIterator* ci) {
-    ci->node.component = ci->component;
-    ci->node.entity = *ci->indexToEntity;
-    ci->indexToEntity++;
-    ci->component = (char*)ci->component + ci->componentSize;
-    return &ci->node;
-}
-
-void* getComponentsStart(Components* c) {
-    return getListStart(&c->components);
-}
-
-void* getComponentsEnd(Components* c) {
-    return getListEnd(&c->components);
-}

+ 0 - 95
src/List.c

@@ -1,95 +0,0 @@
-#define IMPORT_CORE
-#include "core/List.h"
-
-#include <assert.h>
-
-#include "core/Utility.h"
-
-static void iEnsureListCapacity(List* l) {
-    if(l->length >= l->capacity) {
-        reserveListEntries(l, l->capacity + maxSize(4lu, l->capacity / 4));
-    }
-}
-
-static void iSetListSize(List* l, size_t n) {
-    l->capacity = n;
-    l->data = cReallocate(l->data, l->dataSize * n);
-}
-
-static void* iGetListPointer(const List* l, size_t index) {
-    return (char*)l->data + (l->dataSize * index);
-}
-
-void initList(List* l, size_t dataSize) {
-    *l = (List){0, 0, dataSize, nullptr};
-}
-
-void destroyList(List* l) {
-    cFree(l->data);
-    *l = (List){0};
-}
-
-void reserveListEntries(List* l, size_t n) {
-    if(n > l->capacity) {
-        iSetListSize(l, n);
-    }
-}
-
-void addListData(List* l, const void* data) {
-    memcpy(addEmptyListData(l), data, l->dataSize);
-}
-
-void addLastListData(List* l) {
-    addListData(l, getListLast(l));
-}
-
-void* addEmptyListData(List* l) {
-    iEnsureListCapacity(l);
-    return iGetListPointer(l, l->length++);
-}
-
-void* getListIndex(const List* l, size_t index) {
-    assert(index < l->length);
-    return iGetListPointer(l, index);
-}
-
-void* getListLast(const List* l) {
-    return getListIndex(l, l->length - 1);
-}
-
-void clearList(List* l) {
-    l->length = 0;
-}
-
-void removeListIndexBySwap(List* l, size_t index) {
-    assert(index < l->length);
-    size_t length = l->length - 1;
-    if(index != length) {
-        memcpy(iGetListPointer(l, index), iGetListPointer(l, length),
-               l->dataSize);
-    }
-    l->length = length;
-}
-
-void removeListIndex(List* l, size_t index) {
-    assert(index < l->length);
-    l->length--;
-    char* p = iGetListPointer(l, index);
-    char* end = getListEnd(l);
-    while(p != end) {
-        *p = *(p + l->dataSize);
-        p++;
-    }
-}
-
-void removeListLast(List* l) {
-    removeListIndexBySwap(l, l->length - 1);
-}
-
-void* getListStart(const List* l) {
-    return l->data;
-}
-
-void* getListEnd(const List* l) {
-    return iGetListPointer(l, l->length);
-}

+ 0 - 17
src/ToString.c

@@ -7,7 +7,6 @@
 #include "core/BitArray.h"
 #include "core/Box.h"
 #include "core/HashMap.h"
-#include "core/List.h"
 #include "core/Matrix.h"
 #include "core/Plane.h"
 #include "core/Queue.h"
@@ -84,22 +83,6 @@ size_t toStringPlane(const Plane* p, char* buffer, size_t n) {
                         (double)p->abc.data[2], (double)p->d);
 }
 
-size_t toStringList(const List* l, char* buffer, size_t n, ToString c) {
-    size_t w = 0;
-    stringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));
-    char* end = getListEnd(l);
-    char* p = getListStart(l);
-    while(p != end) {
-        stringAdd(&w, &buffer, &n, c(p, buffer, n));
-        p += l->dataSize;
-        if(p != end) {
-            stringAdd(&w, &buffer, &n, coreToString(buffer, n, ", "));
-        }
-    }
-    stringAdd(&w, &buffer, &n, coreToString(buffer, n, "]"));
-    return w;
-}
-
 size_t toStringQueue(const Queue* r, char* buffer, size_t n, ToString c) {
     size_t w = 0;
     stringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));

+ 13 - 0
test/TestInstances.c

@@ -0,0 +1,13 @@
+#include "core/Components.h"
+#include "core/Vector.h"
+
+LIST_SOURCE(size_t, Size)
+
+LIST(CoreVector3, V3)
+LIST_SOURCE(CoreVector3, V3)
+
+LIST(int, Int)
+LIST_SOURCE(int, Int)
+
+COMPONENTS(int, Int)
+COMPONENTS_SOURCE(int, Int)

+ 13 - 10
test/modules/ComponentsTests.c

@@ -2,9 +2,12 @@
 #include "../Tests.h"
 #include "core/Components.h"
 
+LIST(int, Int)
+COMPONENTS(int, Int)
+
 static void testAddForEach() {
     Components c;
-    initComponents(&c, sizeof(int));
+    initComponents(&c);
 
     int* i1 = getOrAddComponent(&c, 1);
     if(TEST_NOT_NULL(i1)) {
@@ -29,17 +32,17 @@ static void testAddForEach() {
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(1, n->entity);
-        TEST_INT(15, *(int*)n->component);
+        TEST_INT(15, *n->component);
     }
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(5, n->entity);
-        TEST_INT(20, *(int*)n->component);
+        TEST_INT(20, *n->component);
     }
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(10, n->entity);
-        TEST_INT(30, *(int*)n->component);
+        TEST_INT(30, *n->component);
     }
     TEST_FALSE(hasNextComponentNode(&iter));
     destroyComponents(&c);
@@ -47,7 +50,7 @@ static void testAddForEach() {
 
 static void testAddComponentForEach() {
     Components c;
-    initComponents(&c, sizeof(int));
+    initComponents(&c);
     int* i1 = getOrAddComponent(&c, 1);
     if(TEST_NOT_NULL(i1)) {
         *i1 = 10;
@@ -78,16 +81,16 @@ static void testAddComponentForEach() {
 
 static void testRemove() {
     Components c;
-    initComponents(&c, sizeof(int));
-    *(int*)getOrAddComponent(&c, 1) = 10;
-    *(int*)getOrAddComponent(&c, 5) = 20;
-    *(int*)getOrAddComponent(&c, 10) = 30;
+    initComponents(&c);
+    *getOrAddComponent(&c, 1) = 10;
+    *getOrAddComponent(&c, 5) = 20;
+    *getOrAddComponent(&c, 10) = 30;
 
     TEST_FALSE(removeComponent(&c, 20));
     TEST_TRUE(removeComponent(&c, 5));
     TEST_FALSE(removeComponent(&c, 30));
 
-    *(int*)getOrAddComponent(&c, 20) = 40;
+    *getOrAddComponent(&c, 20) = 40;
     TEST_TRUE(removeComponent(&c, 20));
 
     int* i1 = searchComponent(&c, 1);

+ 106 - 103
test/modules/ListTests.c

@@ -4,179 +4,182 @@
 #include "core/ToString.h"
 #include "core/Vector.h"
 
+LIST(size_t, Size)
+LIST(Vector3, V3)
+
 static void testAdd() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 5);
-    TEST_SIZE(5, getTypedListIndex(&list, 0, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 5);
+    TEST_SIZE(5, *getListIndexSize(&list, 0));
     TEST_SIZE(1, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testMultipleAdd() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 4);
-    addListType(&list, size_t, 3);
-    addListType(&list, size_t, 2);
-    TEST_SIZE(4, getTypedListIndex(&list, 0, size_t));
-    TEST_SIZE(3, getTypedListIndex(&list, 1, size_t));
-    TEST_SIZE(2, getTypedListIndex(&list, 2, size_t));
-    TEST_SIZE(2, getTypedListLast(&list, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 4);
+    addListDataSize(&list, 3);
+    addListDataSize(&list, 2);
+    TEST_SIZE(4, *getListIndexSize(&list, 0));
+    TEST_SIZE(3, *getListIndexSize(&list, 1));
+    TEST_SIZE(2, *getListIndexSize(&list, 2));
+    TEST_SIZE(2, *getListLastSize(&list));
     TEST_SIZE(3, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testAddLast() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 4);
-    addListType(&list, size_t, 3);
-    addLastListData(&list);
-    TEST_SIZE(4, getTypedListIndex(&list, 0, size_t));
-    TEST_SIZE(3, getTypedListIndex(&list, 1, size_t));
-    TEST_SIZE(3, getTypedListIndex(&list, 2, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 4);
+    addListDataSize(&list, 3);
+    addLastListDataSize(&list);
+    TEST_SIZE(4, *getListIndexSize(&list, 0));
+    TEST_SIZE(3, *getListIndexSize(&list, 1));
+    TEST_SIZE(3, *getListIndexSize(&list, 2));
     TEST_SIZE(3, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testAddReplace() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 5);
-    getTypedListIndex(&list, 0, size_t) = 3;
-    TEST_SIZE(3, getTypedListIndex(&list, 0, size_t));
-    destroyList(&list);
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 5);
+    *getListIndexSize(&list, 0) = 3;
+    TEST_SIZE(3, *getListIndexSize(&list, 0));
+    destroyListSize(&list);
 }
 
 static void testClear() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 5);
-    addListType(&list, size_t, 4);
-    clearList(&list);
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 5);
+    addListDataSize(&list, 4);
+    clearListSize(&list);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testBigAdd(bool light) {
     size_t limit = light ? 10000 : 100000;
-    List list;
-    initList(&list, sizeof(size_t));
+    ListSize list;
+    initListSize(&list);
     for(size_t i = 0; i < limit; i++) {
-        addListType(&list, size_t, i);
+        addListDataSize(&list, i);
     }
     for(size_t i = 0; i < list.length; i++) {
-        TEST_SIZE(i, getTypedListIndex(&list, i, size_t));
+        TEST_SIZE(i, *getListIndexSize(&list, i));
     }
     TEST_SIZE(limit, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testToString1() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 1);
-    addListType(&list, size_t, 243);
-    addListType(&list, size_t, 423);
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 1);
+    addListDataSize(&list, 243);
+    addListDataSize(&list, 423);
     char buffer[128];
-    size_t n = toString(&list, buffer, sizeof(buffer), toStringSize);
+    size_t n = toStringListSize(&list, buffer, sizeof(buffer), toStringSize);
     TEST_SIZE(13, n);
     TEST_STRING("[1, 243, 423]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testToString2() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 1);
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 1);
     char buffer[128];
-    size_t n = toString(&list, buffer, sizeof(buffer), toStringSize);
+    size_t n = toStringListSize(&list, buffer, sizeof(buffer), toStringSize);
     TEST_SIZE(3, n);
     TEST_STRING("[1]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testToString3() {
-    List list;
-    initList(&list, sizeof(size_t));
+    ListSize list;
+    initListSize(&list);
     char buffer[128];
-    size_t n = toString(&list, buffer, sizeof(buffer), toStringSize);
+    size_t n = toStringListSize(&list, buffer, sizeof(buffer), toStringSize);
     TEST_SIZE(2, n);
     TEST_STRING("[]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testRemoveBySwap() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 4);
-    addListType(&list, size_t, 3);
-    addListType(&list, size_t, 2);
-    removeListIndexBySwap(&list, 0);
-    TEST_SIZE(2, getTypedListIndex(&list, 0, size_t));
-    TEST_SIZE(3, getTypedListIndex(&list, 1, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 4);
+    addListDataSize(&list, 3);
+    addListDataSize(&list, 2);
+    removeListIndexBySwapSize(&list, 0);
+    TEST_SIZE(2, *getListIndexSize(&list, 0));
+    TEST_SIZE(3, *getListIndexSize(&list, 1));
     TEST_SIZE(2, list.length);
-    removeListIndexBySwap(&list, 1);
-    TEST_SIZE(2, getTypedListIndex(&list, 0, size_t));
+    removeListIndexBySwapSize(&list, 1);
+    TEST_SIZE(2, *getListIndexSize(&list, 0));
     TEST_SIZE(1, list.length);
-    removeListIndexBySwap(&list, 0);
+    removeListIndexBySwapSize(&list, 0);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testRemove() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 4);
-    addListType(&list, size_t, 3);
-    addListType(&list, size_t, 2);
-    removeListIndex(&list, 0);
-    TEST_SIZE(3, getTypedListIndex(&list, 0, size_t));
-    TEST_SIZE(2, getTypedListIndex(&list, 1, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 4);
+    addListDataSize(&list, 3);
+    addListDataSize(&list, 2);
+    removeListIndexSize(&list, 0);
+    TEST_SIZE(3, *getListIndexSize(&list, 0));
+    TEST_SIZE(2, *getListIndexSize(&list, 1));
     TEST_SIZE(2, list.length);
-    removeListIndex(&list, 1);
-    TEST_SIZE(3, getTypedListIndex(&list, 0, size_t));
+    removeListIndexSize(&list, 1);
+    TEST_SIZE(3, *getListIndexSize(&list, 0));
     TEST_SIZE(1, list.length);
-    removeListIndex(&list, 0);
+    removeListIndexSize(&list, 0);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testRemoveLast() {
-    List list;
-    initList(&list, sizeof(size_t));
-    addListType(&list, size_t, 4);
-    addListType(&list, size_t, 3);
-    addListType(&list, size_t, 2);
-    removeListLast(&list);
-    TEST_SIZE(4, getTypedListIndex(&list, 0, size_t));
-    TEST_SIZE(3, getTypedListIndex(&list, 1, size_t));
+    ListSize list;
+    initListSize(&list);
+    addListDataSize(&list, 4);
+    addListDataSize(&list, 3);
+    addListDataSize(&list, 2);
+    removeListLastSize(&list);
+    TEST_SIZE(4, *getListIndexSize(&list, 0));
+    TEST_SIZE(3, *getListIndexSize(&list, 1));
     TEST_SIZE(2, list.length);
-    removeListLast(&list);
-    TEST_SIZE(4, getTypedListIndex(&list, 0, size_t));
+    removeListLastSize(&list);
+    TEST_SIZE(4, *getListIndexSize(&list, 0));
     TEST_SIZE(1, list.length);
-    removeListLast(&list);
+    removeListLastSize(&list);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 
 static void testInvalidReserve() {
-    List list;
-    initList(&list, sizeof(size_t));
-    reserveListEntries(&list, 0);
-    destroyList(&list);
+    ListSize list;
+    initListSize(&list);
+    reserveListEntriesSize(&list, 0);
+    destroyListSize(&list);
 }
 
 static void testStruct() {
-    List list;
+    ListV3 list;
     Vector3 v = {{1, 2, 3}};
-    initList(&list, sizeof(v));
-    addListData(&list, &v);
-    addListType(&list, Vector3, {2, 3, 4});
-    Vector3* entry = getListIndex(&list, 0);
+    initListV3(&list);
+    addListDataV3(&list, v);
+    addListDataV3(&list, (Vector3){2, 3, 4});
+    Vector3* entry = getListIndexV3(&list, 0);
     TEST_V3(&v, entry);
-    destroyList(&list);
+    destroyListV3(&list);
 }
 
 void testList(bool light) {