Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

entity::emplace doesn't trigger on_add component hook #788

Closed
Evangel63 opened this issue Aug 21, 2022 · 2 comments
Closed

entity::emplace doesn't trigger on_add component hook #788

Evangel63 opened this issue Aug 21, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@Evangel63
Copy link

Describe the bug
When calling entity_builder::emplace<T>, the on_add hook is not called. The documentation states Emplace may only be called for components that have not yet been added to the entity, so my assumption is that emplacing should trigger the on_add hook. Emplace does trigger the on_set hook. When emplacing while deferred, it does trigger the on_add hook as well as the on_set when deferral ends, but I think that's because of the issue in #784.

The on_set hook being called makes it seem like this is intended behaviour, however the documentation saying emplace can only be called on entities without the component makes it seem like on_add should be called instead. ecs_type_hooks_t makes no mention of which ones are called on emplace, nor does ecs_emplace_id, only that it can only be called on entities without the component.

To Reproduce

#include "flecs.h"

#include <iostream>

struct TestStruct
{
    int i_ = 0;
    
    TestStruct() = default;
    TestStruct(int i) : i_(i) {}
};

int main()
{
    flecs::world ecs;
    
    ecs.component<TestStruct>()
        .on_add([](flecs::entity e, TestStruct& t) {
            std::cout << "Entity '" << e.name() << "' has value on_add hook '" << t.i_ << "'\n";
        })
        .on_set([](flecs::entity e, TestStruct& t) {
            std::cout << "Entity '" << e.name() << "' has value on_set hook '" << t.i_ << "'\n";
        });
    
//     ecs.defer_begin(); // 1
    auto e1 = ecs.entity("e1").add<TestStruct>();
    auto e2 = ecs.entity("e2").emplace<TestStruct>(1);
//     ecs.defer_end(); // 2
    auto e2_v = e2.get<TestStruct>();
    std::cout << "Entity '" << e2.name() << "' has value after '" << e2_v->i_ << "'\n";
}

Output of the above program is:

Entity 'e1' has value on_add hook '0'
Entity 'e2' has value on_set hook '1'
Entity 'e2' has value after '1'

With lines 1 and 2 uncommented, output is:

Entity 'e1' has value on_add hook '0'
Entity 'e2' has value on_add hook '0'
Entity 'e2' has value on_set hook '1'
Entity 'e2' has value after '1'

Expected behavior
Expected output:

Entity 'e1' has value on_add hook '0'
Entity 'e2' has value on_add hook '1'
Entity 'e2' has value after '1'

Additional context
Ubuntu 22.04, gcc-12 to compile flecs.c, g++-12 to compile the above.

@Evangel63 Evangel63 added the bug Something isn't working label Aug 21, 2022
@SanderMertens
Copy link
Owner

The on_add hook should be called for emplace, I'll take a look at it.

@SanderMertens
Copy link
Owner

Fixed!

One thing to keep in mind is that on_add hooks are called before the component value is assigned (either with emplace or set). This means reading/writing the value of a component in an on_add hook that does not have a default constructor is UB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants