Add ecs defer test
This commit is contained in:
@@ -8,6 +8,9 @@ target_link_libraries(window_test LINK_PRIVATE Breeze)
|
||||
add_executable(cute_tiled_test cute_tiled_test.c)
|
||||
target_link_libraries(cute_tiled_test LINK_PRIVATE Breeze)
|
||||
|
||||
add_executable(ecs_defer_test ecs_defer_test.c)
|
||||
target_link_libraries(ecs_defer_test LINK_PRIVATE Breeze)
|
||||
|
||||
add_executable(heap_test heap_test.c)
|
||||
target_link_libraries(heap_test LINK_PRIVATE Breeze)
|
||||
|
||||
|
||||
93
engine/tests/ecs_defer_test.c
Normal file
93
engine/tests/ecs_defer_test.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <flecs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct Data {
|
||||
int x;
|
||||
} Data;
|
||||
|
||||
typedef struct Test {
|
||||
Data* ptr;
|
||||
} Test;
|
||||
|
||||
ECS_COMPONENT_DECLARE(Test);
|
||||
|
||||
ECS_CTOR(Test, ptr, {
|
||||
ptr->ptr = ecs_os_malloc(sizeof(Data));
|
||||
ptr->ptr->x = 0; // Default value
|
||||
printf("ctor: %d\n", ptr->ptr->x);
|
||||
})
|
||||
ECS_DTOR(Test, ptr, {
|
||||
printf("dtor: %d\n", ptr->ptr->x);
|
||||
ecs_os_free(ptr->ptr);
|
||||
})
|
||||
ECS_MOVE(Test, dst, src, {
|
||||
printf("move: %d->%d\n", src->ptr->x, dst->ptr->x);
|
||||
dst->ptr = src->ptr;
|
||||
// Clear the pointer in src since it's been moved tp dst and we
|
||||
// don't want to free it when `src` ges destroyed
|
||||
src->ptr = NULL;
|
||||
})
|
||||
|
||||
void testRemoved(ecs_iter_t *it) {
|
||||
Test *test = ecs_field(it, Test, 1);
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
printf("on_remove: %d\n", test[i].ptr->x);
|
||||
}
|
||||
}
|
||||
void testSet(ecs_iter_t *it) {
|
||||
Test *test = ecs_field(it, Test, 1);
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
printf("on_set: %d\n", test[i].ptr->x);
|
||||
}
|
||||
}
|
||||
|
||||
void ecs_copy_illegal(void *dst, const void *src, int32_t c, const ecs_type_info_t *ti) {
|
||||
ecs_abort(ECS_INVALID_OPERATION, "invalid copy assignment for %s", ti->name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
ecs_world_t *ecs = ecs_init();
|
||||
ECS_COMPONENT_DEFINE(ecs, Test);
|
||||
|
||||
ecs_set_hooks(ecs, Test, {
|
||||
.ctor = ecs_ctor(Test),
|
||||
.dtor = ecs_dtor(Test),
|
||||
.move = ecs_move(Test),
|
||||
.copy = ecs_copy_illegal, // Prevent Test from being copied so that they never share the same pointer
|
||||
|
||||
.on_remove = testRemoved,
|
||||
.on_set = testSet
|
||||
});
|
||||
|
||||
ecs_entity_t entity = ecs_new_id(ecs);
|
||||
Test* test = ecs_emplace(ecs, entity, Test); // Emplace the component, this doesn't call the ctor allowing us to initialize the data in the table directly
|
||||
Data* ptr = ecs_os_malloc(sizeof(Data));
|
||||
ptr->x = 1;
|
||||
test->ptr = ptr;
|
||||
ecs_modified(ecs, entity, Test); // Tell the ECS that we are done with modifying the component
|
||||
|
||||
// Modify the data in the component without doing any copy/move
|
||||
test = ecs_get_mut(ecs, entity, Test);
|
||||
test->ptr->x = 2;
|
||||
ecs_modified(ecs, entity, Test);
|
||||
|
||||
ecs_remove(ecs, entity, Test); // testRemoved called for {2}
|
||||
|
||||
// Since the component was previously removed this will call the constructor to initialize the
|
||||
// default value in the table, and then return that.
|
||||
test = ecs_get_mut(ecs, entity, Test);
|
||||
test->ptr->x = 3;
|
||||
ecs_modified(ecs, entity, Test);
|
||||
|
||||
ecs_defer_begin(ecs);
|
||||
ecs_remove(ecs, entity, Test);
|
||||
|
||||
test = ecs_get_mut(ecs, entity, Test);
|
||||
test->ptr->x = 4;
|
||||
ecs_modified(ecs, entity, Test);
|
||||
|
||||
ecs_defer_end(ecs);
|
||||
|
||||
ecs_fini(ecs); // testRemoved called for {4}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user