这是我想在C ++中使用Lua C API做的事情。
我正在尝试找出一种从基本userdata对象派生userdata的好方法。
我希望能够做到这一点:
local item = me:GetCurrentItem()
print(item:GetPos())
而不是:
local item = me:GetCurrentItem()
print(item:GetBaseObject():GetPos())
在这些示例中,我:GetCurrentItem()返回带有一些函数的userdata,但它缺少以下项:GetBaseObject()返回的基函数。
我在“孤岛危机”SDK中绑定Lua用于学习目的。 SDK提供了作为结构的基础实体的接口。 IItem结构(me:GetCurrentItem())是相同的。 由于这些是结构,我无法将它们转换为基础结构或调用其基本函数。我必须使用IEntity * GetEntity()函数。
我已经尝试在__index中查找自我指针,但它会导致局部变量“item”成为“实体”,这有点显而易见,但是我希望它在调用GetPos函数之后还原,这在某种程度上似乎是不合逻辑的。
有没有人能很好地解决这个问题?
答案 0 :(得分:2)
显而易见的解决方案是定义一个项目:GetPos()函数执行重定向。
function Item:GetPos()
return self:GetBaseObject():GetPos()
end
其中Item是项目的元表。
这与在metatable上进行更改一样有效,而且问题较少。
编辑:我也可以帮助你解决重复问题。您可以实现以下两个功能:
function delegate(klass, methodName, memberName)
klass[methodName] = function(self, ...)
local member = self[memberName]
if type(member) == 'function' then member = self[memberName](self) end
return member[methodName](member, ...)
end
end
然后像这样使用它:
delegate(Item, 'GetPos', 'GetBaseObject')
该单行与上面的Item:GetPos
3行定义相同。
如果您需要重复这一点,可以使用其他功能进一步优化:
function delegateMany(klass, methodNames, memberName)
for _,methodName in ipairs(methodNames) do
delegateMethod(klass, methodName, memberName)
end
end
应该允许你这样做:
deletageMany(Item, {'GetPost', 'SetPos', 'GetColor', 'SetColor'}, 'GetBaseObject')
我还没有测试过任何这些功能,所以要小心bug。它们应该与“获得的属性”(self:GetSomething()
以及简单访问self.something
)一起使用。该代码假定您始终使用“:”来调用委派的方法,因此在需要时添加self
。