94 lines
2.6 KiB
C
94 lines
2.6 KiB
C
#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}
|
|
}
|
|
|