skypjack / entt

Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more
https://github.com/skypjack/entt/wiki
MIT License
10.06k stars 882 forks source link

A proper way to create wrapper for group and view #1176

Open Diarica opened 5 days ago

Diarica commented 5 days ago

`class VTransformSystem : public VSystem { public:

void OnStartup(VEntityManager& manager) override;
void OnExecute(VEntityManager& manager, const VSystemExecutionContext& context) override;

void SetPosition(VTransformComponent& tran, const glm::vec3& position);
void SetRotation(VTransformComponent& tran, const glm::quat& rotation);
void SetScale(VTransformComponent& tran, const glm::vec3& scale);

static glm::mat4 CalculateTransformMatrix(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& scale);

auto trangroup = // 

}; `

I'm building a ECS inside my game engine using entt, for some particular reason, I can't just create groups just on the right hand side of group declaration like auto group = reg.group.... (there is multiple registry supported in my game engine, just like Worlds in Unity DOTS) std::optional is not working for this situation.

Any helps will be thanksful.

skypjack commented 4 days ago

I'd like to help you but I've to admit that I don't understand what your problem is. Can you provide more details? Does the registry.group call not work for you or do you just want to create an empty group to initialize later?

Diarica commented 4 days ago

I'd like to help you but I've to admit that I don't understand what your problem is. Can you provide more details? Does the registry.group call not work for you or do you just want to create an empty group to initialize later?

I'm sorry for unclear expression. Yes, I just want to create an empty group and initialize later, and before you replied me, I found as_view could work. But I originally want to create a wrapper of view and groups, Is there a fesiable approarch? Wrappers could just be type alias of entt things, like this `template<typename Get, typename Exclude> using View = entt::view<Get, Exclude>;

template<typename Owned, typename Get, typename Exclude> using Group = entt::group<Owned, Get, Exclude>;`

Really thanks for your helps.

skypjack commented 4 days ago

It's more similar to the following then:

template<typename... Owned, typename... Get, typename... Exclude>
using Group = entt::group<entt::type_list<Owned...>, entt::type_list<Get...>, entt::type_list<Exclude...>>;

Same for the view type.

Diarica commented 4 days ago

It's more similar to the following then:

template<typename... Owned, typename... Get, typename... Exclude>
using Group = entt::group<entt::type_list<Owned...>, entt::type_list<Get...>, entt::type_list<Exclude...>>;

Same for the view type.

Thanks, I have already done the wrapper, but I have one last question, in view and group function, auto is the only choice to store the return value? auto test = m_enttRegistry.view<component>(); Cannot store things like basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>> ?

skypjack commented 4 days ago

Of course, yes, you can use the explicit type in all cases if you want. That's about C++ though. It doesn't depend on EnTT.

Diarica commented 3 days ago
template<typename... Owned, typename... Get, typename... Exclude>

I'm sorry, but I have to back the original question, how to create an empty group and initialize it later?

`template<typename... Owned, typename... Get, typename... Exclude> class VQuery {

public: void InitializeQuery(VEntityManager& entity_manager) { m_Group = entt::as_group(entity_manager.GetNativeRegistry()); } operator auto&() { return m_Group; } private: entt::group<Owned...,Get...,Exclude...> m_Group;

};`

It may like that, but it seems like I cannot access any group functions(like contains(), size(), strorage()... )

skypjack commented 3 days ago

it seems like I cannot access any group functions(like contains(), size(), strorage()... )

What does it mean? Can you provide a minimal example that I can test and fix eventually? I don't even get what you're trying to do nor what the problem is.

Diarica commented 3 days ago
entt::type_list<Owned...>, entt::type_list<Get...>, entt::type_list<Exclude...>

Okay, sorry, I would like to create a wrapper of entt::group, and it's need be able to initialize group with registry later.

template<typename... Owned, typename... Get, typename... Exclude>
class VQuery
{

public:
    void InitializeQuery(VEntityManager& entity_manager)
    {
        m_Group = entt::as_group(entity_manager.GetNativeRegistry());
    }
    operator auto&()
    {
        return m_Group;
    }

    auto& GetTest()
    {
        return m_Group;
    }

private:
    entt::group<entt::type_list<Owned...>, entt::type_list<Get...>, entt::type_list<Exclude...>> m_Group;

};

I tried this, but it's not work for me, cannot be compiled.

skypjack commented 1 day ago

If you want to use entt::group, then it's something like this:

entt::group<entt::owned_t<Owned...>, entt::get_t<Get...>, entt::exclude_t<Exclude...>> m_Group;

As for:

cannot be compiled

If it doesn't work, please, post the relevant part of your error or a reproducible example. It saves time when helping. 👍

Diarica commented 14 hours ago

Thanks! You're so kind! Sorry for I get things complicated. But it's still cannot be compiled.

Here I wrote a simple wrapper class of entt::group, strictly followed your example.

template<typename... Owned, typename... Get, typename... Exclude>
class test_query
{
    entt::group<entt::owned_t<Owned...>, entt::get_t<Get...>, entt::exclude_t<Exclude...>> m_Group;
};

It's just a simple class with those template parameters and entt::group but it's still get compile errors, Error C3525 : 'Owned': if a class template has a template parameter pack it must appear at the end of the template parameter list

I even not sure if it's a C++ template restriction? Class templates only supported single variety parameters? But type alias actually supported multiple variety template parameters. Here's an example that I tested for 'using'

template<typename... Owned, typename... Get, typename... Exclude> using f = entt::group<entt::owned_t<Owned...>, entt::get_t<Get...>, entt::exclude_t<Exclude...>>; It's compiled successfully.

Sorry I'm not familiar with templates, It's really a restriction? (Class templates only supported single variety parameters?)

Is there a feasible way to create a wrapper of entt::group?

skypjack commented 12 hours ago

Consider this:

template<typename... Owned, typename... Get, typename... Exclude>
class test_query;

Then imagine the following:

test_query<int, char> q;

What pack int belongs to? Owned? Get? Exclude? What's the one for char then? The compiler cannot know what you want in case of ambiguity. So, yeah, the error is in your code and you should fix it.

Diarica commented 11 hours ago

Consider this:

template<typename... Owned, typename... Get, typename... Exclude>
class test_query;

Then imagine the following:

test_query<int, char> q;

What pack int belongs to? Owned? Get? Exclude? What's the one for char then? The compiler cannot know what you want in case of ambiguity. So, yeah, the error is in your code and you should fix it.

Understood, but I literally can't just use type alias to wrap entt::group. I need extra behaviors in my wrapper class, because I need to initialize group with registry later, and store it to a std::vector container.

So, Is there a possible way to create a wrapper class with same parameters than call entt::registry::group ? I mean, if I need to create a wrapped group, I can simply says

WrappedGroup<Transform,Tag> group; group.init(getRegistry()); // here to initialize group later. group.getNativeGroup().view([]) // here to access entt::group functions

Thanks for your kindness help again.

Innokentiy-Alaytsev commented 11 hours ago

Some options:

  1. Use opaque type lists in your class declaration, and pass them directly to the wrapped group.
  2. Use a factory function for creating your wrapper, similar to how entt:groups are created (in most cases?).