Entt: [Feature request] view registry constructor for class members.

Created on 20 Nov 2018  Â·  11Comments  Â·  Source: skypjack/entt

from the gitter.

b) any way of declaring a view in header and then making it later? like typedef entt::view<Data::Player> PlayerView;
and then PlayerView view = reg.view();
instead of PlayerView view = reg.view<Data::Player>()

Indi Kernick @Kerndog73 16:52
I don’t know about A but B is totally doable. The syntax will look something like this auto view = reg.view();. It just requires unpacking a typelist which is fairly straightforward

Paul Gruenbacher @pgruenbacher 16:58
i want the opposite i believe though. cause if i have a class with view members, I don't want to have to retype the view arguments again in the constructor
i.e.

 class A {
    entt::view<EntityType, Data> _view;
    A(Registry& reg) : _view(reg) {}
}

instead of

class A {
    entt::view<EntityType, Data> _view;
    A(Registry& reg) : _view(reg.view<Data>()) {}
}

I know it's finicky bu shrug
oh nvm i see what you mean @Kerndog73

Paul Gruenbacher @pgruenbacher 17:03
can view types be made to be constructed from registry maybe?

Indi Kernick @Kerndog73 17:05
The view constructor would just call reg.view with its component template parameters
Easy

Paul Gruenbacher @pgruenbacher 17:06
hm yea let me check
well it doesnt work out of the box due to private pools and stuff, but yea I think this seems feasible to have registry constructor...

enhancement

Most helpful comment

I see. Well, to add a constructor that accepts a registry to the views isn't a viable solution, mainly because it would require to know the type of the registry. This will lead directly to a circular inclusion. There are also other reasons, of course, but this one is enough to say - no, for obvious reasons in fact.

However, you can obtain exactly the same result with a sort of _converter_. I wrote a small example from which to start developing it. The class exploits some arcane features of the language, feel free to ask if you want more details.
I put it in the form of a test, so that you can copy and paste it in a .cpp of EnTT, then try to modify and compile the example:

template<typename Entity>
struct conv {
    conv(entt::registry<Entity> &reg): reg{reg} {}

    template<typename... Component>
    operator entt::view<Entity, Component...>() {
        return reg.template view<Component...>();
    }

    template<typename... Component>
    operator entt::view<Entity, Component...>() const {
        return reg.template view<Component...>();
    }

    // ...

private:
    entt::registry<Entity> &reg;
};

template<typename Entity>
conv(entt::registry<Entity> &) -> conv<Entity>;

TEST(Converter, RegistryToViewConverter) {
    entt::registry<> registry;
    using entity_type = typename entt::registry<>::entity_type;
    entt::view<entity_type, int, char> view = conv{registry};
    (void)view;
}

Let me know if it solves your problem. As you can see, you can construct a view as it follows:

entt::view<entity_type, int, char> view = conv{registry};

That's also quite easy to extend to persistent views and the others if needed. This is more or less what you asked. Right?

All 11 comments

but so ultimately i'm hoping we can get registry constructor so that I can declare view types in my class members and then initialize all of them from registry in the member list initialization.

Constructing a view is a cheap operation. Why do you want to store them aside at all?

It allows for me to declare classe scope of what components it reads and
writes, by only allowing the class to have view members instead of a global
registry member.

On Tuesday, November 20, 2018, Michele Caini notifications@github.com
wrote:

Constructing a view is a cheap operation. Why do you want to store them
aside at all?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/157#issuecomment-440450578, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ADLZ9sFwEKOBAGAyNOicH8lGAi0IGx8_ks5uxICmgaJpZM4YsBbK
.

I see. Well, to add a constructor that accepts a registry to the views isn't a viable solution, mainly because it would require to know the type of the registry. This will lead directly to a circular inclusion. There are also other reasons, of course, but this one is enough to say - no, for obvious reasons in fact.

However, you can obtain exactly the same result with a sort of _converter_. I wrote a small example from which to start developing it. The class exploits some arcane features of the language, feel free to ask if you want more details.
I put it in the form of a test, so that you can copy and paste it in a .cpp of EnTT, then try to modify and compile the example:

template<typename Entity>
struct conv {
    conv(entt::registry<Entity> &reg): reg{reg} {}

    template<typename... Component>
    operator entt::view<Entity, Component...>() {
        return reg.template view<Component...>();
    }

    template<typename... Component>
    operator entt::view<Entity, Component...>() const {
        return reg.template view<Component...>();
    }

    // ...

private:
    entt::registry<Entity> &reg;
};

template<typename Entity>
conv(entt::registry<Entity> &) -> conv<Entity>;

TEST(Converter, RegistryToViewConverter) {
    entt::registry<> registry;
    using entity_type = typename entt::registry<>::entity_type;
    entt::view<entity_type, int, char> view = conv{registry};
    (void)view;
}

Let me know if it solves your problem. As you can see, you can construct a view as it follows:

entt::view<entity_type, int, char> view = conv{registry};

That's also quite easy to extend to persistent views and the others if needed. This is more or less what you asked. Right?

@skypjack Genius!

Actually, we could think of writing a full-featured version of this utility so as to include it in EnTT. It could help also other users.
Not a priority of mine, but it shouldn't take much time.

ah I wish I had thought of that approach, I've yet to really implement my own type cast operators so I hadn't considered them as a strategy. This is definitely helping me learn more c++.

I'm glad you like it. Unfortunately, there isn't an easy way to flip the problem on its head and let the views accept a registry as an argument. On the other side, it doesn't make much sense to me that a registry has a cast operator to a view, no matter the type. This way we get the best of the two worlds: we have the cast operators and we get rid of circular dependencies. :+1:

Well, let's find a good name for such a class. I'll write it in my free time probably. It can be useful also for other users, so why not? I'm not that sure I'll use it actually, but who knows. Suggestions?

maybe just "getView" struct? succint.

See branch experimental for a full implementation. It doesn't support runtime views for several reasons.
In case of positive or no feedback, I'll merge it on master later today or tomorrow. Then I'll close the issue.


Converter is as_view class within helper.hpp.

Was this page helpful?
0 / 5 - 0 ratings