Skip to content

Signals for inherited registry #1078

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

Closed
actondev opened this issue Oct 17, 2023 · 2 comments
Closed

Signals for inherited registry #1078

actondev opened this issue Oct 17, 2023 · 2 comments
Assignees
Labels
feature request feature request not yet accepted

Comments

@actondev
Copy link

actondev commented Oct 17, 2023

In a project I've been working on we plan on inheriting (via protected inheritance) registry, so that we provide a more restricted public API. For example, registry.get<Foo>(e) would only give back a const reference to disable mutations outside of an API call.

When doing that work, it seemed that signals are a paint point, since they define the callback signature to pass a basic_registry & as the first argument. We are heavily using signals & the are very powerful, but they expose the underlying basic_registry& in the callback, which can then do any mutation that the inherited registry would not allow in the first place.
The desired behavior would be to get the inherited type of registry as the first argument in the callback.

I'm preparing a PR for this as a possible approach, but glad to hear your thoughts on the issue at hand

Current scenario

What's possible right now is this:

enum class CustomEntity : std::uint32_t
{
};


// This could be used to add custom methods to the registry or, in case of non-public inheritance,
// to restrict the access to the registry.
class CustomRegistry: public entt::basic_registry<CustomEntity> {
  public:
    using registry_type = entt::basic_registry<CustomEntity>;
};

template<typename Component>
struct entt::storage_type<Component, CustomEntity>
{
  using type = entt::sigh_mixin<entt::basic_storage<Component, CustomEntity>>;
};

struct counter {
    int value{};
};

// Note: this callback gets access to the basic_registry itself, not to the custom registry.
void custom_registry_listener(counter &counter, CustomRegistry::registry_type &, CustomEntity) {
    ++counter.value;
}

And usage

    CustomRegistry registry;

    counter on_construct_int{};
    registry.on_construct<int>().connect<&custom_registry_listener>(on_construct_int);

Desired scenario

void custom_registry_listener(counter &counter, CustomRegistry &, CustomEntity) {
    ++counter.value;
}

registry.on_construct<int>().connect<&custom_registry_listener>(on_construct_int);
@skypjack skypjack self-assigned this Oct 18, 2023
@skypjack skypjack added the feature request feature request not yet accepted label Oct 18, 2023
@skypjack
Copy link
Owner

I DO love the fact that you used a curried function for your example! 😅
I'm closing this issue and moving the discussion to the PR in order to avoid confusion. 👍

@actondev
Copy link
Author

TBH I didn't know of this feature until I saw it in the tests 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request feature request not yet accepted
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants