mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-20 07:50:45 +00:00
[ecs] Add a component rotation function
This allows rotation of components within the array. I'm not sure if it's what I want, but it was an interesting exercise anyway.
This commit is contained in:
parent
4471a40494
commit
0b6e8b60bd
3 changed files with 140 additions and 0 deletions
|
@ -60,6 +60,9 @@ COMPINLINE void Component_ResizeArray (const component_t *component,
|
|||
COMPINLINE void *Component_MoveElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex,
|
||||
uint32_t srcIndex, uint32_t count);
|
||||
COMPINLINE void Component_RotateElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex,
|
||||
uint32_t srcIndex, uint32_t count);
|
||||
COMPINLINE void Component_SwapElements (const component_t *component,
|
||||
void *a, void *b);
|
||||
COMPINLINE void *Component_CopyElements (const component_t *component,
|
||||
|
@ -98,6 +101,49 @@ Component_MoveElements (const component_t *component,
|
|||
return memmove (dst, src, count * component->size);
|
||||
}
|
||||
|
||||
COMPINLINE void
|
||||
Component_RotateElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex, uint32_t srcIndex,
|
||||
uint32_t count)
|
||||
{
|
||||
if (dstIndex == srcIndex) {
|
||||
puts ("a");
|
||||
return;
|
||||
}
|
||||
auto dst = (byte *) array + dstIndex * component->size;
|
||||
auto src = (byte *) array + srcIndex * component->size;
|
||||
size_t countSize = count * component->size;
|
||||
if (dstIndex < srcIndex) {
|
||||
uint32_t bcount = srcIndex - dstIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
if (count < bcount) {
|
||||
byte tmp[countSize];
|
||||
memcpy (tmp, src, countSize);
|
||||
memmove (dst + countSize, dst, bcountSize);
|
||||
memcpy (dst, tmp, countSize);
|
||||
} else {
|
||||
byte tmp[bcountSize];
|
||||
memcpy (tmp, dst, bcountSize);
|
||||
memmove (dst, src, countSize);
|
||||
memcpy (dst + countSize, tmp, bcountSize);
|
||||
}
|
||||
} else if (dstIndex < srcIndex + count) {
|
||||
uint32_t bcount = dstIndex - srcIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
byte tmp[bcountSize];
|
||||
memcpy (tmp, src + countSize, bcountSize);
|
||||
memmove (dst, src, countSize);
|
||||
memcpy (src, tmp, bcountSize);
|
||||
} else {
|
||||
uint32_t bcount = dstIndex - srcIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
byte tmp[countSize];
|
||||
memcpy (tmp, src, countSize);
|
||||
memmove (src, src + countSize, bcountSize);
|
||||
memcpy (dst, tmp, countSize);
|
||||
}
|
||||
}
|
||||
|
||||
COMPINLINE void
|
||||
Component_SwapElements (const component_t *component, void *a, void *b)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
libs_ecs_tests = \
|
||||
libs/ecs/test/test-components \
|
||||
libs/ecs/test/test-compops \
|
||||
libs/ecs/test/test-hierarchy \
|
||||
libs/ecs/test/test-registry \
|
||||
libs/ecs/test/test-subpools
|
||||
|
@ -19,6 +20,13 @@ libs_ecs_test_test_components_LDADD= \
|
|||
libs_ecs_test_test_components_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
||||
libs_ecs_test_test_compops_SOURCES= \
|
||||
libs/ecs/test/test-compops.c
|
||||
libs_ecs_test_test_compops_LDADD= \
|
||||
$(libs_ecs_test_libs)
|
||||
libs_ecs_test_test_compops_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
||||
libs_ecs_test_test_hierarchy_SOURCES= \
|
||||
libs/ecs/test/test-hierarchy.c
|
||||
libs_ecs_test_test_hierarchy_LDADD= \
|
||||
|
|
86
libs/ecs/test/test-compops.c
Normal file
86
libs/ecs/test/test-compops.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "QF/ecs.h"
|
||||
|
||||
enum {
|
||||
test_comp,
|
||||
};
|
||||
|
||||
static int counter = 0;
|
||||
static void
|
||||
create_test_comp (void *comp)
|
||||
{
|
||||
*(int *) comp = counter++;
|
||||
}
|
||||
|
||||
static const component_t test_component[] = {
|
||||
[test_comp] = {
|
||||
.size = sizeof (int),
|
||||
.create = create_test_comp,
|
||||
.name = "position",
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
test_rotation (const component_t *comp, int *array, uint32_t array_count,
|
||||
uint32_t dstIndex, uint32_t srcIndex, uint32_t count,
|
||||
int *expect)
|
||||
{
|
||||
counter = 0;
|
||||
Component_CreateElements (comp, array, 0, array_count);
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
if (array[i] != (int) i) {
|
||||
printf ("array initialized incorrectly");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Component_RotateElements (comp, array, dstIndex, srcIndex, count);
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
printf ("%d ", expect[i]);
|
||||
}
|
||||
puts ("");
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
printf ("%d ", array[i]);
|
||||
}
|
||||
puts ("");
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
if (array[i] != expect[i]) {
|
||||
printf ("array rotated incorrectly");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
static int expect2[] = { 0, 1, 6, 7, 8, 2, 3, 4, 5, 9 };
|
||||
static int expect3[] = { 0, 1, 4, 5, 6, 7, 8, 2, 3, 9 };
|
||||
static int expect4[] = { 0, 6, 7, 8, 1, 2, 3, 4, 5, 9 };
|
||||
static int expect5[] = { 0, 4, 5, 6, 7, 8, 1, 2, 3, 9 };
|
||||
|
||||
static int *test_array = 0;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
auto comp = &test_component[test_comp];
|
||||
|
||||
Component_ResizeArray (comp, (void **) &test_array, 10);
|
||||
if (test_rotation (comp, test_array, 10, 2, 2, 3, expect1))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 2, 6, 3, expect2))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 2, 4, 5, expect3))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 4, 1, 5, expect4))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 6, 1, 3, expect5))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue