【问题标题】:Is exposing some of SFML to lua with luabridge relatively easy?使用 luabridge 将一些 SFML 暴露给 lua 相对容易吗?
【发布时间】:2015-10-08 03:36:07
【问题描述】:

我了解如何将我自己的类公开给 lua,如下所示:

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

但是,由于我试图将尽可能多的代码移动到 lua 脚本中,因此我希望 lua 类具有 SFML 对象,例如 sf::Textsf::Texture。我没有对 Luabridge 做过很多实验,我不确定我是否能够做这样的事情:

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()

如果这样做不起作用(我担心它可能会),我是否需要创建一个包装类,如下所示:

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

更新:

尝试公开sf::Text 类后,尝试执行sf::Text::setPosition 函数时出现错误:

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()

错误信息:

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]

【问题讨论】:

  • 你试过了吗?我看不出它为什么适用于您自己的课程但不适用于 SFML 的课程的任何理由。
  • @Cornstalks 你见过 SFML 有多大吗?我宁愿确保甚至可以做到这一点,而不是花一天时间为每个 SFML 对象的函数做addFunction(),以发现我必须创建一个包装类。我不确定的原因纯粹是因为某些函数返回其他类/结构,例如 sf::Vector2sf::Color

标签: c++ lua sfml luabridge


【解决方案1】:

我不熟悉 luabridge,但听起来你有问题,因为 sf::Text::setPosition 过载。

直接来自 SFML 文档: void setPosition(浮点 x,浮点 y) 设置物体的位置

void setPosition (const Vector2f &position) 设置物体的位置

luabridge 无法确定您要为 setPosition 使用哪个。由于您对评论中的想法并不熟悉,因此我将澄清:在 C++ 中,函数签名是它的名称,以及它所采用的参数(参数的数量和参数的类型)。函数不能具有相同的签名,这意味着它们可以具有相同的名称,但是 C++ 编译器可以通过它们的参数来区分它们。 sf::Text有两个函数setPosition,一个取vector2f,另一个直接取两个float。

但是,你在做什么就像这个链接? http://oberon00.github.io/luabind/functions.html

它在哪里谈到重载函数,你能同样提供签名吗?

所以你会有类似的东西:

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

如果不是,您需要对重载进行包装并赋予不同的名称。

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

LuaBridge 不支持重载函数,将来也不可能支持。由于 Lua 是动态类型的,任何尝试解析从脚本传递的一组参数的系统在尝试选择适当匹配的 C++ 函数签名时都会面临相当大的歧义。

您需要包装一下,这听起来是一个有趣的下午!您需要为函数指定不同的名称,或者只包含一个。

另外,我怀疑当参数或返回值是其他 SFML 对象时会有一些诡计。我想他们需要先定义?请注意,像 Vector2i 和 Vector2f 之类的东西是 sf::Vector2 和 sf::Vector2 的类型定义,以节省用户输入的时间。

【讨论】:

  • 我偷偷地怀疑我必须包装一些类(sigh),但对于其他解决方案,我也不确定如何/是否可以提供一个签名,因为尝试你的代码会给我一个错误(没有上下文类型信息的重载函数的地址)而且我对 C++ 中的签名一点也不熟悉
  • 加速谷歌搜索,查看链接
  • 因为我可能不得不包装所有的 SFML 类,我可能会尽量避免 sf::Colorsf::Vector2,所以 getPosition() 将是 getXPosition() 和 @987654328 @ 和 getColor() 将是 getRValue()getGValue 等。
猜你喜欢
  • 2010-12-01
  • 2015-10-26
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
相关资源
最近更新 更多