Is exposing some of SFML to lua with luabridge relatively easy?

711 Views Asked by At

I understand how to expose my own classes to lua, like this:

lua_State* L = luaL_newstate();
luaL_openlibs(L);
getGlobalNamespace(L)
    .beginClass<Foo>("Foo")
        .addConstructor<void(*)(void)>()
        .addProperty(/*Property Definition*/)
        .addFunction(/*Function Definition*/)
    .endClass()

But, since I am trying to move as much of my code into lua scripts as possible, I would like to have lua classes that have SFML objects, like sf::Text or sf::Texture. I haven't done very much experimentation with Luabridge, and I'm not sure if I'd be able to do something like this:

lua_State* L = luaL_newstate();
luaL_openlibs(L);
getGlobalNamespace(L)
    .beginClass<sf::Text>("Text")
        .addConstructor<void(*)(void)>()
        .addFunction("setCharacterSize", &sf::Text::setCharacterSize)
        .addFunction("getCharacterSize", &sf::Text::getCharacterSize)
        //ETC...
    .endClass()

If doing this doesn't work (as I worry it may), would I need to create a wrapper class, like this:

class Text
{
    private:
        sf::Text textObj;

    public:
        void setCharacterSize(const int& size) {textObj.setCharacterSize(size);}
        int& getCharacterSize() {return textObj.getCharacterSize();}
}

//Then do the same as the second snippet, without sf::Text but with Text class

UPDATE:

After attempting to expose the sf::Text class, I get an error when trying to do the sf::Text::setPosition function:

lua_State* L = luaL_newstate();
luaL_openlibs(L);
luabridge::getGlobalNamespace(L)
.beginClass<sf::Text>("Text")
    .addConstructor<void(*)(void)>()
    .addFunction("setCharacterSize", &sf::Text::setCharacterSize)
    .addFunction("getCharacterSize", &sf::Text::getCharacterSize)
    .addFunction("setColor", &sf::Text::setColor)
    .addFunction("getColor", &sf::Text::getColor)
    .addFunction("setFont", &sf::Text::setFont)
    .addFunction("getFont", &sf::Text::getFont)
    .addFunction("setPosition", &sf::Text::setPosition)
    .addFunction("getPosition", &sf::Text::getPosition)
    .addFunction("setScale", &sf::Text::setScale)
    .addFunction("getScale", &sf::Text::getScale)
    .addFunction("setString", &sf::Text::setString)
    .addFunction("getString", &sf::Text::getString)
.endClass()

Error message:

no matching function for call to ‘luabridge::Namespace::Class<sf::Text>::addFunction(const char [12], <unresolved overloaded function type>)’
note: candidate is:
note: template<class MemFn> luabridge::Namespace::Class<T>& luabridge::Namespace::Class<T>::addFunction(const char*, MemFn) [with MemFn = MemFn; T = sf::Text]
1

There are 1 best solutions below

3
On BEST ANSWER

I'm not familiar with luabridge, but it sounds like you have a problem because sf::Text::setPosition is overloaded.

Straight from the SFML documentation: void setPosition (float x, float y) set the position of the object

void setPosition (const Vector2f &position) set the position of the object

There's no way luabridge can determine which you mean to use for setPosition. Since you didn't sound familiar with the idea in your comment, I'll clarify: In C++, a function signature is its name, and the arguments that it takes (both number of arguments and type of arguments). Functions can't have the same signature, which means they CAN have the same name, but the C++ compiler can tell them apart by their arguments. sf::Text has two functions named setPosition, one takes a vector2f, and the other takes two floats directly.

However, is what you're doing like this link? http://oberon00.github.io/luabind/functions.html

Where it talks about overloaded functions can you similarly provide the signature?

So you'd have something like:

 .addFunction("setPosition", (void(*)(float x, float y)) &sf::Text::setPosition) 

If not, you'll need to wrap and give the overloads a different name.

EDIT: https://github.com/vinniefalco/LuaBridgeDemo/blob/master/LuaBridge/README.md

LuaBridge does not support overloaded functions nor is it likely to in the future. Since Lua is dynamically typed, any system that tries to resolve a set of parameters passed from a script will face considerable ambiguity when trying to choose an appropriately matching C++ function signature.

You'll need to wrap, sounds like a fun afternoon! You'll need to give the functions distinct names, or just include one.

Also, I suspect there will be some trickery when the arguments or return values are other SFML objects. I guess they'll need to be defined first? Be aware that stuff like Vector2i and Vector2f are typedefs of sf::Vector2 and sf::Vector2 to save the user some typing.