我有一个Entity
类,其中包含一些属性(数据片段)。这些属性存储在名称=>的地图中。值。
class Entity
{
public:
// Sets the attribute with the specified name.
void attribute(const std::string& name, const GenericType& value) {
m_attributes[name] = value;
}
// Returns the attribute with the specified name.
GenericType& attribute(const std::string& name) {
return m_attributes[name];
}
template<typename AttributeType>
void attribute(const std::string& name, const AttributeType& value) {
m_attributes[name] = GenericType(value);
}
template<typename AttributeType>
AttributeType& attribute(const std::string& name) {
return generic_cast<AttributeType>(m_attributes[name]);
}
private:
// Map of attributes from name => value.
std::unordered_map<std::string, GenericType> m_attributes;
}
我有一个创建或覆盖属性的方法,另一个方法返回具有指定名称的属性。前两种方法暴露给Lua。最后两种方法用于从我的c ++源代码访问和修改属性。问题是属性可以是任何类型。例如,我希望能够:
entity.attribute("Health", 100)
entity.attribute("Position", Vector3(1,2,3))
entity.attribute("Position").x = 4
应该可以从我的c ++源文件和lua脚本中读取和修改属性。我以前一直在使用ChaiScript,我使用Boxed_Value类作为我的GenericType
。这很好用,但过多的编译时间迫使我去寻找其他地方。
有没有办法用LuaBind(或任何其他Lua绑定库)实现这一目的? luabind::object
类看起来很有希望但它的构造函数中需要一个lua_State
类。这令我担心,因为我觉得Entity
班级对Lua州一无所知。
答案 0 :(得分:1)
在LuaBind中,您的实体类不需要了解有关lua状态的任何信息。 Lua绑定不必在语法上与C ++ API一对一,因为它们是完全不同的语言。
在你的情况下,我宁愿将api拆分为getter和setter。通过显示的Entity
课程,您可能会努力让LuaBind明确地做您想做的事情。您可以做的是在C ++端为Entity编写一个包装类,它将具有符合LuaBind的简单接口,即使用明确的名称拆分getter和setter。
Blufs就是一个例子,展示了我的意思。
举个简单的例子,with 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进行交互,请编写获取原始包装对象的小包装器并将其传递给其他函数。