Browse Source

Make List and Components typesafe with makro generation

Kajetan Johannes Hammerle 7 months ago
parent
commit
7f142017d1
10 changed files with 365 additions and 387 deletions
  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/BitArray.c"
     "src/Box.c"
     "src/Box.c"
     "src/Buffer.c"
     "src/Buffer.c"
-    "src/Components.c"
     "src/Frustum.c"
     "src/Frustum.c"
     "src/HashMap.c"
     "src/HashMap.c"
-    "src/List.c"
     "src/Logger.c"
     "src/Logger.c"
     "src/Matrix.c"
     "src/Matrix.c"
     "src/Plane.c"
     "src/Plane.c"
@@ -28,6 +26,7 @@ set(SRC
 
 
 set(SRC_TESTS
 set(SRC_TESTS
     "test/Main.c"
     "test/Main.c"
+    "test/TestInstances.c"
     "test/modules/BitArrayTests.c"
     "test/modules/BitArrayTests.c"
     "test/modules/BoxTests.c"
     "test/modules/BoxTests.c"
     "test/modules/BufferTests.c"
     "test/modules/BufferTests.c"

+ 110 - 46
include/core/Components.h

@@ -4,54 +4,118 @@
 #include "core/HashMap.h"
 #include "core/HashMap.h"
 #include "core/List.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
 #endif

+ 122 - 24
include/core/List.h

@@ -1,32 +1,130 @@
 #ifndef CORE_LIST_H
 #ifndef CORE_LIST_H
 #define CORE_LIST_H
 #define CORE_LIST_H
 
 
+#include <assert.h>
+
+#include "core/ToString.h"
 #include "core/Types.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
 #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);
 size_t coreToStringInt(const void* p, char* buffer, size_t n);
 void coreStringAdd(size_t* w, char** buffer, size_t* n, size_t shift);
 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;
 struct CoreQueueT;
 size_t coreToStringQueue(const struct CoreQueueT* r, char* buffer, size_t n,
 size_t coreToStringQueue(const struct CoreQueueT* r, char* buffer, size_t n,
                          CoreToString c);
                          CoreToString c);
@@ -34,7 +31,6 @@ CORE_STRUCT_TO_STRING(Plane)
 #define toStringSize coreToStringSize
 #define toStringSize coreToStringSize
 #define toStringInt coreToStringInt
 #define toStringInt coreToStringInt
 #define stringAdd coreStringAdd
 #define stringAdd coreStringAdd
-#define toStringList coreToStringList
 #define toStringQueue coreToStringQueue
 #define toStringQueue coreToStringQueue
 #define toStringHashMap coreToStringHashMap
 #define toStringHashMap coreToStringHashMap
 #define toStringBitArray coreToStringBitArray
 #define toStringBitArray coreToStringBitArray
@@ -49,10 +45,6 @@ CORE_STRUCT_TO_STRING(Plane)
     CORE_PAIR(const struct Core##name##T*, toString##name),                    \
     CORE_PAIR(const struct Core##name##T*, toString##name),                    \
         CORE_PAIR(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, ...)                                                       \
 #define toString(t, ...)                                                       \
     _Generic((t),                                                              \
     _Generic((t),                                                              \
         char*: coreToString,                                                   \
         char*: coreToString,                                                   \
@@ -60,7 +52,6 @@ CORE_STRUCT_TO_STRING(Plane)
         CORE_STRUCT_PAIR(Box),                                                 \
         CORE_STRUCT_PAIR(Box),                                                 \
         CORE_STRUCT_PAIR(Matrix),                                              \
         CORE_STRUCT_PAIR(Matrix),                                              \
         CORE_STRUCT_PAIR(Plane),                                               \
         CORE_STRUCT_PAIR(Plane),                                               \
-        STRUCT_PAIR(List),                                                     \
         CORE_STRUCT_PAIR(Queue),                                               \
         CORE_STRUCT_PAIR(Queue),                                               \
         CORE_STRUCT_PAIR(HashMap))(t, __VA_ARGS__)
         CORE_STRUCT_PAIR(HashMap))(t, __VA_ARGS__)
 #endif
 #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/BitArray.h"
 #include "core/Box.h"
 #include "core/Box.h"
 #include "core/HashMap.h"
 #include "core/HashMap.h"
-#include "core/List.h"
 #include "core/Matrix.h"
 #include "core/Matrix.h"
 #include "core/Plane.h"
 #include "core/Plane.h"
 #include "core/Queue.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);
                         (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 toStringQueue(const Queue* r, char* buffer, size_t n, ToString c) {
     size_t w = 0;
     size_t w = 0;
     stringAdd(&w, &buffer, &n, coreToString(buffer, n, "["));
     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 "../Tests.h"
 #include "core/Components.h"
 #include "core/Components.h"
 
 
+LIST(int, Int)
+COMPONENTS(int, Int)
+
 static void testAddForEach() {
 static void testAddForEach() {
     Components c;
     Components c;
-    initComponents(&c, sizeof(int));
+    initComponents(&c);
 
 
     int* i1 = getOrAddComponent(&c, 1);
     int* i1 = getOrAddComponent(&c, 1);
     if(TEST_NOT_NULL(i1)) {
     if(TEST_NOT_NULL(i1)) {
@@ -29,17 +32,17 @@ static void testAddForEach() {
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(1, n->entity);
         TEST_SIZE(1, n->entity);
-        TEST_INT(15, *(int*)n->component);
+        TEST_INT(15, *n->component);
     }
     }
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(5, n->entity);
         TEST_SIZE(5, n->entity);
-        TEST_INT(20, *(int*)n->component);
+        TEST_INT(20, *n->component);
     }
     }
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
     if(TEST_TRUE(hasNextComponentNode(&iter))) {
         ComponentNode* n = nextComponentNode(&iter);
         ComponentNode* n = nextComponentNode(&iter);
         TEST_SIZE(10, n->entity);
         TEST_SIZE(10, n->entity);
-        TEST_INT(30, *(int*)n->component);
+        TEST_INT(30, *n->component);
     }
     }
     TEST_FALSE(hasNextComponentNode(&iter));
     TEST_FALSE(hasNextComponentNode(&iter));
     destroyComponents(&c);
     destroyComponents(&c);
@@ -47,7 +50,7 @@ static void testAddForEach() {
 
 
 static void testAddComponentForEach() {
 static void testAddComponentForEach() {
     Components c;
     Components c;
-    initComponents(&c, sizeof(int));
+    initComponents(&c);
     int* i1 = getOrAddComponent(&c, 1);
     int* i1 = getOrAddComponent(&c, 1);
     if(TEST_NOT_NULL(i1)) {
     if(TEST_NOT_NULL(i1)) {
         *i1 = 10;
         *i1 = 10;
@@ -78,16 +81,16 @@ static void testAddComponentForEach() {
 
 
 static void testRemove() {
 static void testRemove() {
     Components c;
     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_FALSE(removeComponent(&c, 20));
     TEST_TRUE(removeComponent(&c, 5));
     TEST_TRUE(removeComponent(&c, 5));
     TEST_FALSE(removeComponent(&c, 30));
     TEST_FALSE(removeComponent(&c, 30));
 
 
-    *(int*)getOrAddComponent(&c, 20) = 40;
+    *getOrAddComponent(&c, 20) = 40;
     TEST_TRUE(removeComponent(&c, 20));
     TEST_TRUE(removeComponent(&c, 20));
 
 
     int* i1 = searchComponent(&c, 1);
     int* i1 = searchComponent(&c, 1);

+ 106 - 103
test/modules/ListTests.c

@@ -4,179 +4,182 @@
 #include "core/ToString.h"
 #include "core/ToString.h"
 #include "core/Vector.h"
 #include "core/Vector.h"
 
 
+LIST(size_t, Size)
+LIST(Vector3, V3)
+
 static void testAdd() {
 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);
     TEST_SIZE(1, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testMultipleAdd() {
 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);
     TEST_SIZE(3, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testAddLast() {
 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);
     TEST_SIZE(3, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testAddReplace() {
 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() {
 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);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testBigAdd(bool light) {
 static void testBigAdd(bool light) {
     size_t limit = light ? 10000 : 100000;
     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++) {
     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++) {
     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);
     TEST_SIZE(limit, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testToString1() {
 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];
     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_SIZE(13, n);
     TEST_STRING("[1, 243, 423]", buffer);
     TEST_STRING("[1, 243, 423]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testToString2() {
 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];
     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_SIZE(3, n);
     TEST_STRING("[1]", buffer);
     TEST_STRING("[1]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testToString3() {
 static void testToString3() {
-    List list;
-    initList(&list, sizeof(size_t));
+    ListSize list;
+    initListSize(&list);
     char buffer[128];
     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_SIZE(2, n);
     TEST_STRING("[]", buffer);
     TEST_STRING("[]", buffer);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testRemoveBySwap() {
 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);
     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);
     TEST_SIZE(1, list.length);
-    removeListIndexBySwap(&list, 0);
+    removeListIndexBySwapSize(&list, 0);
     TEST_SIZE(0, list.length);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testRemove() {
 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);
     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);
     TEST_SIZE(1, list.length);
-    removeListIndex(&list, 0);
+    removeListIndexSize(&list, 0);
     TEST_SIZE(0, list.length);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testRemoveLast() {
 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);
     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);
     TEST_SIZE(1, list.length);
-    removeListLast(&list);
+    removeListLastSize(&list);
     TEST_SIZE(0, list.length);
     TEST_SIZE(0, list.length);
-    destroyList(&list);
+    destroyListSize(&list);
 }
 }
 
 
 static void testInvalidReserve() {
 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() {
 static void testStruct() {
-    List list;
+    ListV3 list;
     Vector3 v = {{1, 2, 3}};
     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);
     TEST_V3(&v, entry);
-    destroyList(&list);
+    destroyListV3(&list);
 }
 }
 
 
 void testList(bool light) {
 void testList(bool light) {