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

Add Constructors Separately #1361

Open
dhkatz opened this issue May 29, 2022 · 0 comments
Open

Add Constructors Separately #1361

dhkatz opened this issue May 29, 2022 · 0 comments

Comments

@dhkatz
Copy link

dhkatz commented May 29, 2022

Is it possible to add constructors at different times instead of all at once when registering the user type?

I was playing around with RTTR, since I plan to use the metadata for an editor later on, and it would be nice if I could also register classes in Lua using that same information.

Everything seems to work using a visitor pattern I found in an example, but RTTR visits each constructor separately.

For example, this is how I've been handling the constructors with Sol2 at the moment. This works with one constructor, but when there are multiple, they start overriding each other:

        template <typename T, typename... Args>
        void visit_constructor(const constructor_info<T>& info) {
            using Class = typename constructor_info<T>::declaring_type;

            auto table = info.ctor_item.get_declaring_type().get_name().to_string();

            sol::usertype<Class> usertype = lua.get<sol::usertype<Class>>(table);

            auto ctor = sol::constructors<T(Args...)>();

            usertype[sol::meta_function::construct] = ctor;
        }

My C++ knowledge might be a bit limited in terms of templates so I'm not really sure what I could do here.

One of my first thoughts was to start storing constructors in visit_type_begin because that's where I first register the type:

        template <typename T, typename... Bases>
        void visit_type_begin(const type_info<T>& info) {
            using Class = typename type_info<T>::declaring_type;

            auto name = info.type_item.get_name().to_string();

            lua.new_usertype<Class>(name);

            // Can I create a way to store constructors for later?
        }

and then maybe in visit_type_end to finally register them all at once?

        template <typename T, typename... Bases>
        void visit_type_end(const type_info<T>& info) {
            // Register constructors now that we know we've seen them all?
        }

Again, my knowledge of templates/generics in C++ is a bit limited so I'm not even sure this is possible because of type erasure when storing types and such.

I saw this project get around this by instead storing a type containing all the constructors on every class it expects to register with Sol2 but this seems like kind of a bandaid solution:

    struct position_2d : public math::vec2f
    {
        template <typename... Args>
        position_2d(Args&&... args) noexcept : math::vec2f(std::forward<Args>(args)...)
        {
        }

        position_2d() noexcept = default;

        position_2d(const position_2d& other) noexcept = default;

        position_2d& operator=(const position_2d& other) noexcept = default;

        position_2d(math::vec2f pos) noexcept : math::vec2f(pos)
        {
        }

        position_2d(float x, float y) noexcept : math::vec2f(x, y)
        {
        }

       // Storing the sol constructors here for later
        using constructors = sol::constructors<
            position_2d(),

            position_2d(math::vec2f pos), position_2d(float x, float y)

            >;
    };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant