on_replace: set other_table and set_fields in flecs_invoke_replace_hook#2137
Open
Indra-db wants to merge 6 commits into
Open
on_replace: set other_table and set_fields in flecs_invoke_replace_hook#2137Indra-db wants to merge 6 commits into
Indra-db wants to merge 6 commits into
Conversation
4707977 to
5f3b50e
Compare
Contributor
Author
|
had to add the param for a set fix, if this is not acceptable, you can close this. I don't see any other way around it. |
| it.offset = 0; /* Don't set row because we don't want to offset ptrs */ | ||
| it.flags = EcsIterIsValid; | ||
| it.other_table = prev_table; | ||
| it.set_fields = (prev_table != NULL && ecs_table_has_id(world, prev_table, id)) ? 3 : 2; |
Owner
There was a problem hiding this comment.
Invoking ecs_table_has_id is not feasible here as it would add way too much overhead to on_replace hooks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: Populate
other_tableandset_fieldsinon_replacehook iteratorProblem
on_replacecallbacks had no way to tell whetherprevheld a valid existing value or uninitialized memory.it.other_tablewas always NULL andit.set_fieldswas always 0.Several call sites also passed
r->tableafterflecs_ensurehad already moved the entity, so the table reflected post-move state — making new adds and replacements indistinguishable.Fix
flecs_invoke_replace_hook— newprev_tableparameterit.tableserves two purposes: component storage access (used internally byflecs_on_replace_parentto find name data) and the informationalother_tablefield for user hooks. For the entity-init path these must be different values, so they are now decoupled via an explicitprev_tableparameter:it.tablestays as the final committed table (required for internal storage access).it.other_tablegets the pre-move table.set_fields = 3means bothprevandnextare valid (replacement).set_fields = 2means onlynextis valid (new add).Pre-move table at all call sites
flecs_set_id_move,ecs_set_id,ecs_cpp_set,ecs_cpp_assign: captureprev_table = r->tablebeforeflecs_ensure/flecs_get_mut, pass asprev_table.flecs_cmd_batch_for_entitysecond-pass: passstart_table(table before any commands in the batch ran).EcsCmdAddModified): passesr->table— entity already has the component at this point, soset_fields = 3is correct.ecs_entity()with.set): capturesinit_table = r->tablebefore any components are added, passes asprev_table.flecs_copy_idrefactorflecs_copy_idpreviously contained its own hook call usingr->table(always post-ensure). Removed it —flecs_copy_idis now a pure copy-and-notify function. Both call sites fire the hook beforeflecs_copy_idwith the correct pre-move table. Thenon_trivial_setfast path is safe: it is onlyfalsewhen no non-trivial hooks includingon_replaceare registered.Semantics
set_fieldsbit 0ecs_set/ecs_cpp_set, component not yet on entityecs_set/ecs_cpp_set, component already on entityecs_cpp_assign(requires component to exist)EcsCmdAddModified(fires at insertion).setvaluesTests
All tests register
on_replacewith a raw hook that capturesit->other_tableandit->set_fields, then assert both match expected values.Core (
ComponentLifecycle):on_replace_other_table_new_entity,on_replace_other_table_existing_entity,on_replace_other_table_set_existing,on_replace_other_table_batched_new_entity,on_replace_other_table_batched_existing,on_replace_other_table_entity_init.C++ (
Entity):on_replace_other_table_set_new,on_replace_other_table_set_existing,on_replace_other_table_assign_new,on_replace_other_table_assign_existing.Compatibility
No public API or ABI change.
flecs_invoke_replace_hookis an internal function. Callbacks that ignoreother_tableandset_fieldsare entirely unaffected.