diff --git a/flecs.c b/flecs.c index fcbd701144..7fe72fe675 100644 --- a/flecs.c +++ b/flecs.c @@ -22291,6 +22291,103 @@ void sys_ctor_init_zero( memset(ptr, 0, size * (size_t)count); } +/* System move */ +static +void ecs_colsystem_move( + ecs_world_t *world, + ecs_entity_t component, + const ecs_entity_t *dst_entities, + const ecs_entity_t *src_entities, + void *dst_ptr, + void *src_ptr, + size_t size, + int32_t count, + void *ctx) +{ + (void)world; + (void)dst_entities; + (void)src_entities; + (void)component; + (void)ctx; + (void)size; + + EcsSystem *dst_data = dst_ptr; + EcsSystem *src_data = src_ptr; + + int i; + for (i = 0; i < count; i ++) { + EcsSystem *dst = &dst_data[i]; + EcsSystem *src = &src_data[i]; + // ecs_entity_t dst_e = dst_entities[i]; + // ecs_entity_t src_e = src_entities[i]; + + // if (!ecs_is_alive(world, dst_e)) { + // /* This can happen when a set is deferred while a system is being + // * cleaned up. The operation will be discarded, but the destructor + // * still needs to be invoked for the value */ + // continue; + // } + + // /* Invoke Deactivated action for active systems */ + // if (dst->query && dst->query != src->query && ecs_query_table_count(dst->query)) { + // invoke_status_action(world, dst_e, dst, EcsSystemDeactivated); + // } + + // /* Invoke Disabled action for enabled systems */ + // if (!ecs_has_id(world, dst_e, EcsDisabled)) { + // invoke_status_action(world, dst_e, dst, EcsSystemDisabled); + // } + + if (dst->ctx != src->ctx && dst->ctx_free) { + dst->ctx_free(dst->ctx); + } + + if (dst->status_ctx != src->status_ctx && dst->status_ctx_free) { + dst->status_ctx_free(dst->status_ctx); + } + + if (dst->binding_ctx != src->binding_ctx && dst->binding_ctx_free) { + dst->binding_ctx_free(dst->binding_ctx); + } + + if (dst->query && dst->query != src->query) { + ecs_query_fini(dst->query); + } + + dst->action = src->action; + dst->entity = src->entity; + dst->query = src->query; + dst->status_action = src->status_action; + dst->tick_source = src->tick_source; + dst->invoke_count = src->invoke_count; + dst->time_spent = src->time_spent; + dst->time_passed = src->time_passed; + dst->self = src->self; + dst->ctx = src->ctx; + dst->status_ctx = src->status_ctx; + dst->binding_ctx = src->binding_ctx; + dst->ctx_free = src->ctx_free; + dst->status_ctx_free = src->status_ctx_free; + dst->binding_ctx_free = src->binding_ctx_free; + + src->action = NULL; + src->entity = 0; + src->query = NULL; + src->status_action = NULL; + src->tick_source = 0; + src->invoke_count = 0; + src->time_spent = 0; + src->time_passed = 0; + src->self = 0; + src->ctx = NULL; + src->status_ctx = NULL; + src->binding_ctx = NULL; + src->ctx_free = NULL; + src->status_ctx_free = NULL; + src->binding_ctx_free = NULL; + } +} + /* System destructor */ static void ecs_colsystem_dtor( @@ -22538,6 +22635,7 @@ void FlecsSystemImport( ecs_set_component_actions_w_id(world, ecs_id(EcsSystem), &(EcsComponentLifecycle) { .ctor = sys_ctor_init_zero, + .move = ecs_colsystem_move, .dtor = ecs_colsystem_dtor }); @@ -22866,6 +22964,20 @@ static ECS_CTOR(EcsPipelineQuery, ptr, { memset(ptr, 0, _size); }) +static ECS_MOVE(EcsPipelineQuery, dst, src, { + ecs_vector_free(dst->ops); + + dst->query = src->query; + dst->build_query = src->build_query; + dst->match_count = src->match_count; + dst->ops = src->ops; + + src->query = NULL; + src->build_query = NULL; + src->match_count = 0; + src->ops = NULL; +}) + static ECS_DTOR(EcsPipelineQuery, ptr, { ecs_vector_free(ptr->ops); }) @@ -23573,6 +23685,7 @@ void FlecsPipelineImport( /* Set ctor and dtor for PipelineQuery */ ecs_set(world, ecs_id(EcsPipelineQuery), EcsComponentLifecycle, { .ctor = ecs_ctor(EcsPipelineQuery), + .move = ecs_move(EcsPipelineQuery), .dtor = ecs_dtor(EcsPipelineQuery) }); @@ -33807,10 +33920,10 @@ ecs_entity_t assign_ptr_w_id( const ecs_type_info_t *cdata = get_c_info(world, real_id); if (cdata) { if (is_move) { - ecs_move_t move = cdata->lifecycle.move; - if (move) { - move(world, real_id, &entity, &entity, dst, ptr, size, 1, - cdata->lifecycle.ctx); + ecs_move_ctor_t move_dtor = cdata->lifecycle.move_dtor; + if (move_dtor) { + move_dtor(world, real_id, &cdata->lifecycle, &entity, + &entity, dst, ptr, size, 1, cdata->lifecycle.ctx); } else { ecs_os_memcpy(dst, ptr, flecs_from_size_t(size)); } diff --git a/src/addons/pipeline/pipeline.c b/src/addons/pipeline/pipeline.c index f9e3d3249f..0a363cb128 100644 --- a/src/addons/pipeline/pipeline.c +++ b/src/addons/pipeline/pipeline.c @@ -8,6 +8,20 @@ static ECS_CTOR(EcsPipelineQuery, ptr, { memset(ptr, 0, _size); }) +static ECS_MOVE(EcsPipelineQuery, dst, src, { + ecs_vector_free(dst->ops); + + dst->query = src->query; + dst->build_query = src->build_query; + dst->match_count = src->match_count; + dst->ops = src->ops; + + src->query = NULL; + src->build_query = NULL; + src->match_count = 0; + src->ops = NULL; +}) + static ECS_DTOR(EcsPipelineQuery, ptr, { ecs_vector_free(ptr->ops); }) @@ -715,6 +729,7 @@ void FlecsPipelineImport( /* Set ctor and dtor for PipelineQuery */ ecs_set(world, ecs_id(EcsPipelineQuery), EcsComponentLifecycle, { .ctor = ecs_ctor(EcsPipelineQuery), + .move = ecs_move(EcsPipelineQuery), .dtor = ecs_dtor(EcsPipelineQuery) }); diff --git a/src/addons/system/system.c b/src/addons/system/system.c index 1a1866fceb..121814fe39 100644 --- a/src/addons/system/system.c +++ b/src/addons/system/system.c @@ -309,6 +309,103 @@ void sys_ctor_init_zero( memset(ptr, 0, size * (size_t)count); } +/* System move */ +static +void ecs_colsystem_move( + ecs_world_t *world, + ecs_entity_t component, + const ecs_entity_t *dst_entities, + const ecs_entity_t *src_entities, + void *dst_ptr, + void *src_ptr, + size_t size, + int32_t count, + void *ctx) +{ + (void)world; + (void)dst_entities; + (void)src_entities; + (void)component; + (void)ctx; + (void)size; + + EcsSystem *dst_data = dst_ptr; + EcsSystem *src_data = src_ptr; + + int i; + for (i = 0; i < count; i ++) { + EcsSystem *dst = &dst_data[i]; + EcsSystem *src = &src_data[i]; + // ecs_entity_t dst_e = dst_entities[i]; + // ecs_entity_t src_e = src_entities[i]; + + // if (!ecs_is_alive(world, dst_e)) { + // /* This can happen when a set is deferred while a system is being + // * cleaned up. The operation will be discarded, but the destructor + // * still needs to be invoked for the value */ + // continue; + // } + + // /* Invoke Deactivated action for active systems */ + // if (dst->query && dst->query != src->query && ecs_query_table_count(dst->query)) { + // invoke_status_action(world, dst_e, dst, EcsSystemDeactivated); + // } + + // /* Invoke Disabled action for enabled systems */ + // if (!ecs_has_id(world, dst_e, EcsDisabled)) { + // invoke_status_action(world, dst_e, dst, EcsSystemDisabled); + // } + + if (dst->ctx != src->ctx && dst->ctx_free) { + dst->ctx_free(dst->ctx); + } + + if (dst->status_ctx != src->status_ctx && dst->status_ctx_free) { + dst->status_ctx_free(dst->status_ctx); + } + + if (dst->binding_ctx != src->binding_ctx && dst->binding_ctx_free) { + dst->binding_ctx_free(dst->binding_ctx); + } + + if (dst->query && dst->query != src->query) { + ecs_query_fini(dst->query); + } + + dst->action = src->action; + dst->entity = src->entity; + dst->query = src->query; + dst->status_action = src->status_action; + dst->tick_source = src->tick_source; + dst->invoke_count = src->invoke_count; + dst->time_spent = src->time_spent; + dst->time_passed = src->time_passed; + dst->self = src->self; + dst->ctx = src->ctx; + dst->status_ctx = src->status_ctx; + dst->binding_ctx = src->binding_ctx; + dst->ctx_free = src->ctx_free; + dst->status_ctx_free = src->status_ctx_free; + dst->binding_ctx_free = src->binding_ctx_free; + + src->action = NULL; + src->entity = 0; + src->query = NULL; + src->status_action = NULL; + src->tick_source = 0; + src->invoke_count = 0; + src->time_spent = 0; + src->time_passed = 0; + src->self = 0; + src->ctx = NULL; + src->status_ctx = NULL; + src->binding_ctx = NULL; + src->ctx_free = NULL; + src->status_ctx_free = NULL; + src->binding_ctx_free = NULL; + } +} + /* System destructor */ static void ecs_colsystem_dtor( @@ -556,6 +653,7 @@ void FlecsSystemImport( ecs_set_component_actions_w_id(world, ecs_id(EcsSystem), &(EcsComponentLifecycle) { .ctor = sys_ctor_init_zero, + .move = ecs_colsystem_move, .dtor = ecs_colsystem_dtor }); diff --git a/src/entity.c b/src/entity.c index 809260b8a5..13c5a6d301 100644 --- a/src/entity.c +++ b/src/entity.c @@ -2816,10 +2816,10 @@ ecs_entity_t assign_ptr_w_id( const ecs_type_info_t *cdata = get_c_info(world, real_id); if (cdata) { if (is_move) { - ecs_move_t move = cdata->lifecycle.move; - if (move) { - move(world, real_id, &entity, &entity, dst, ptr, size, 1, - cdata->lifecycle.ctx); + ecs_move_ctor_t move_dtor = cdata->lifecycle.move_dtor; + if (move_dtor) { + move_dtor(world, real_id, &cdata->lifecycle, &entity, + &entity, dst, ptr, size, 1, cdata->lifecycle.ctx); } else { ecs_os_memcpy(dst, ptr, flecs_from_size_t(size)); }