C++和Lua的通用类型

我有一个Entity类,其中包含一些属性(数据片段)。这些属性存储在从名称=>值的映射中。

我有一个创建或覆盖属性的方法和另一个根据指定名称返回属性的方法。前两种方法暴露给了Lua。最后两个方法用于从我的c++源代码中访问和修改属性。问题是属性可以是任何类型。例如,我希望能够执行以下操作:

可以从我的c++源文件和Lua脚本中读取和修改属性。我以前使用过ChaiScript,在其中将Boxed_Value类用作我的“GenericType”。这很有效,但过多的编译时间迫使我寻找其他地方。

是否有办法使用LuaBind(或任何其他Lua绑定库)实现此目标?'luabind :: object'类看起来很有前途,但它在它的构造函数中需要一个'lua_State'指针。这让我感到担心,因为我觉得Entity类真的不应该知道任何关于Lua状态的信息。

点赞
用户847349
用户847349

在 LuaBind 中,实体类不需要知道关于 lua 状态的任何东西。Lua绑定不必在语法上与 C++ API 1对1相同,因为这些语言非常不同。

在你的情况下,我宁愿将 API 拆分为 getters 和 setters。在所示的 Entity 类中,你可能会遇到让 LuaBind 明确做你想要做的事情的困难。你可以在 C++ 侧编写一个包装类来解决这个问题,这个包装类将具有 LuaBind 符合规范的简单接口,即使用明确的名称拆分 getters 和 setters。

Blufs 是一个示例,演示了我所说的。

作为简单示例,使用 LuaBridge

要创建一个简单、非手动编写的绑定有些棘手:

class Entity {
    std::map<std::string, int> attributes;

public:
    void attribute(std::string const& key,int value) {
        attributes[key] = value;
    }

    int& attribute(std::string const& key) {
        return attributes[key];
    }
};

绑定一个包装类:

class EntityWrapper {
    Entity entity;
public:
    void set_int(std::string const& key,int value) {
        entity.attribute(key,value);
    }

    int get_int(std::string const& key) {
        return entity.attribute(key);
    }
};

一个简单的绑定:

void luabridge_bind(lua_State *L) {
    luabridge::getGlobalNamespace(L)
    .beginClass<EntityWrapper>("Entity")
    .addConstructor<void(*)(), RefCountedPtr<EntityWrapper> /* creation policy */ >()
        .addFunction("get_int", &EntityWrapper::get_int)
        .addFunction("set_int", &EntityWrapper::set_int)
    .endClass()
    ;
}

在 Lua 中:

local e = Entity()
e:set_int("bla",42)
print(e:get_int("bla"))

如果你需要让 Entity 与其他 API 交互,请编写小型包装器,获取原始封装对象并将其传递给其他函数。

2014-11-29 23:15:24