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

Passing nil as userdata to C++ to reset a variable #1592

Closed
diath opened this issue Mar 26, 2024 · 3 comments
Closed

Passing nil as userdata to C++ to reset a variable #1592

diath opened this issue Mar 26, 2024 · 3 comments

Comments

@diath
Copy link

diath commented Mar 26, 2024

Hi, I have a C++ function that accepts std::shared_ptr<Type> as an argument, I want to also be able to call the function with nil from Lua, to reset the said pointer, however it's not possible because sol expects actual userdata type on the stack, is there a way to work around this without adding a separate function for resetting the pointer?

Example: https://godbolt.org/z/s964fx36e

@Rochet2
Copy link

Rochet2 commented Mar 26, 2024

This would work, so take sol::optional<std::shared_ptr<Widget>> as argument or make a wrapper for the binding if you cant change setActiveWidget.

#include <memory>
#include <limits>

#include <sol/sol.hpp>

struct Widget
{
};

std::shared_ptr<Widget> active;

void setActiveWidget(sol::optional<std::shared_ptr<Widget>> w)
{
    if (w)
        active = *w;
    else
        active.reset();
}

int main(int, char **)
{
    sol::state state;
    state.new_usertype<Widget>("Widget",
		sol::factories([]() {
			return std::make_shared<Widget>();
		})
    );
    state["setActiveWidget"] = &setActiveWidget;

    state.script("setActiveWidget(Widget.new())");
    state.script("setActiveWidget(nil)");

    return 0;
}

@diath
Copy link
Author

diath commented Mar 26, 2024

I can change the API, so that works, just a bit unfortunate that I need to include the sol header in that class now which adds a bit of compile time overhead. Thanks.

@diath diath closed this as completed Mar 26, 2024
@Rochet2
Copy link

Rochet2 commented Mar 26, 2024

You can also just do this instead to avoid the compile overhead but have a wrapper.

state["setActiveWidget"] = [](sol::optional<std::shared_ptr<Widget>> w){ return setActiveWidget(w ? *w : std::shared_ptr<Widget>()); };

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

2 participants