Skip to content

Instantly share code, notes, and snippets.

@mrtrizer
Last active October 21, 2020 09:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrtrizer/fe8b20a9d9ea7f86ca731fd3f1e68888 to your computer and use it in GitHub Desktop.
Save mrtrizer/fe8b20a9d9ea7f86ca731fd3f1e68888 to your computer and use it in GitHub Desktop.
The main idea is to make serial components access as fast as possible because this is the most usual way to interact with components.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <assert.h>
#include <stdbool.h>
typedef uint32_t EId;
typedef struct
{
EId* eIds;
uint8_t* data;
size_t itemSize;
size_t length;
size_t reserve;
size_t i;
size_t removedN;
void (*deinit)(void*);
void* (*realloc)(void *, size_t);
} ECDict;
static inline bool getCDataIndex(ECDict* dict, size_t* i, EId eId)
{
*i = dict->i + 1;
if (*i >= dict->length)
{
if (dict->length == 0)
return false;
i = 0;
}
if (dict->eIds[*i] == eId)
return true;
else
*i = 0;
while (true)
{
if (dict->eIds[*i] == eId)
return true;
*i += 1;
if (*i == dict->length)
return false;
}
return false;
}
static inline void* getCData(ECDict* dict, EId eId)
{
size_t i;
if (getCDataIndex(dict, &i, eId))
{
dict->i = i;
return dict->data + i * dict->itemSize;
}
else
{
return NULL;
}
}
void* addC(ECDict* dict, EId eId)
{
if (dict->removedN > 0)
{
size_t i;
assert(getCDataIndex(dict, &i, 0));
dict->eIds[i] = eId;
dict->removedN--;
return dict->data + i * dict->itemSize;
}
else
{
if (dict->length == dict->reserve)
{
dict->reserve += 1000;
dict->data = dict->realloc(dict->data, dict->reserve * dict->itemSize);
dict->eIds = dict->realloc(dict->eIds, dict->reserve * sizeof(*dict->eIds));
}
dict->eIds[dict->length] = eId;
return dict->data + dict->itemSize * dict->length++;
}
}
bool removeC(ECDict* dict, EId eId)
{
size_t i;
if (getCDataIndex(dict, &i, eId))
{
dict->eIds[i] = 0;
if (dict->deinit)
dict->deinit(dict->data + dict->itemSize * i);
dict->removedN++;
return true;
}
return false;
}
typedef struct
{
int x;
int y;
} TestComponent;
void initTestComponent(void* ref, int x, int y)
{
TestComponent* c = ref;
c->x = x;
c->y = y;
}
void deinitTestComponent(void* ref)
{
TestComponent* c = ref;
c->x = c->y = 0;
}
void testSys(ECDict test)
{
for (EId* id = test.eIds; id != test.eIds + test.length; id++)
{
TestComponent* c = getCData(&test, *id);
printf("%lu ( %u ) %d %d\n", id - test.eIds, *id, c->x, c->y);
}
}
int main(void)
{
ECDict test = { .itemSize = sizeof(TestComponent), .realloc = realloc, .deinit = deinitTestComponent };
initTestComponent(addC(&test, 1), 10, 20);
initTestComponent(addC(&test, 2), 11, 21);
assert(test.length == 2);
assert(test.reserve == 1000);
removeC(&test, 1);
initTestComponent(addC(&test, 3), 12, 22);
initTestComponent(addC(&test, 4), 13, 23);
assert(test.length == 3);
testSys(test);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment