用 Selene 包装枚举以在 Lua 中访问

我正在使用 Selene 将 C++ 类和函数包装成可从 Lua 访问。我有一个简单的枚举类:

enum class Motion {
    UP = 0,
    DOWN = 1,
    REPEAT = 2,
};

我想将其包装在 Lua 状态中,这样我就可以在 Lua 中说 "Motion.DOWN" 并得到 1。

第一次尝试:

void register(sel::State &L) {
    L["Motion"].SetClass< Motion >();
}

编译器抱怨它不是一个类。

...
/source/desktop/../external/Selene/include/selene/Class.h:41:10:
    error: creating pointer to member of non-class type 'Motion'
 void _register_member(lua_State *state,
...

第二次尝试:

void register(sel::State &L) {
    L["Motion"] = Motion;
}

这不会编译,会收到有关“预期主表达式”的错误,它不是有效的 C++。如果我尝试使用&Motion,则会收到相同的错误。

有没有一种方法可以做到这一点?最好不要让我再次列出所有枚举常量。

原文链接 https://stackoverflow.com/questions/36185075

点赞
stackoverflow用户232725
stackoverflow用户232725

这在Selene中是不可能的。

我采用的解决方案是定义一个DynEnum类,内部使用映射来跟踪标签和值。

/**
 * 用于枚举值的简单类
 */
class DynEnum {
  public:
    DynEnum(std::map<std::string, int> tbl) : tbl(tbl) {}

    int of(std::string tag) {
        if (tbl.count(tag) > 0) {
            return tbl[tag];
        }
        throw std::runtime_error("Enum tag not found");
    }

    std::string lookup(int v) {
        for (auto &p : tbl) {
            if (p.second == v) {
                return p.first;
            }
        }
        throw std::runtime_error("Enum value not found");
    }

  private:
    std::map<std::string, int> tbl;
};

然后像这样实例化对象:

DynEnum Motion({
    {"UP", 0},
    {"DOWN", 1},
    {"REPEAT", 2},
});

然后使用Selene绑定:

L["Motion"].SetObj(Motion,
    "of", &DynEnum::of,
    "lookup", &DynEnum::lookup);

这种方法有性能开销,但在我的应用程序中并不重要。它还具有允许在Lua中从数字转换为字符串的优点,这有助于调试。

2016-03-23 18:47:28