如何将Lua变量直接映射到C变量?

前端之家收集整理的这篇文章主要介绍了如何将Lua变量直接映射到C变量?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Lua在C中使用游戏引擎来定义NPC.

我可以像这样定义一个原型NPC:

  1. orc =
  2. {
  3. name = "Generic Orc",health = 100
  4. }
  5.  
  6. function orc:onIdle()
  7. print("Orc idles...")
  8. end

然后使用entitySpawn(orc)生成“Orc”的实例.这是一个C函数,它从给定的表中读取健康和名称等值,在C中使用给定的值创建一个Entity对象,另外为特定的NPC创建一个Lua表.

现在,我想在Lua中的orc.health变量和C中相应的Entity对象的mHealth成员变量之间建立直接连接,因此我可以在Lua中分配一个值并立即在C中使用它,反之亦然.

这甚至可能吗?或者我是否必须使用setter / getter函数?我已经看了一下light userdata并且已经到了在Lua中存储指向C变量的指针,但无法分配值.

解决方法

这个有可能.我假设entitySpawn返回C为实体创建的表.我还假设您可以从C中公开一个函数,该函数接受实体的表并返回当前的运行状况,类似于设置. (您可以使用指向C对象的light userdata指针作为此表的成员来实现此目的.)

所以丑陋的方式看起来像这样:

  1. local myOrc = entitySpawn(orc)
  2. local curHealth = getEntityHealth(myOrc)
  3. setEntityHealth(myOrc,curHealth + 10)

为了使这个更漂亮,我们可以与Metatables有一些乐趣.首先,我们将为我们关心的所有属性设置访问器.

  1. entityGetters = {
  2. health = getEntityHealth,-- ...
  3. }
  4. entitySetters = {
  5. health = setEntityHealth,-- ...
  6. }

然后我们将创建一个使用这些函数来处理属性分配的metatable.

  1. entityMetatable = {}
  2.  
  3. function entityMetatable:__index(key)
  4. local getter = entityGetters[key]
  5. if getter then
  6. return getter(self)
  7. else
  8. return nil
  9. end
  10. end
  11.  
  12. function entityMetable:__newindex(key,value)
  13. local setter = entitySetters[key]
  14. if setter then
  15. return setter(self,value)
  16. end
  17. end

现在你需要让entitySpawn分配Metatable.您可以使用lua_setmetatable功能执行此操作.

  1. int entitySpawn(lua_State* L)
  2. {
  3. // ...
  4. // assuming that the returned table is on top of the stack
  5. lua_getglobal(L,"entityMetatable");
  6. lua_setMetatable(L,-2);
  7. return 1;
  8. }

现在你可以用很好的方式编写它:

  1. local myOrc = entitySpawn(orc)
  2. myOrc.health = myOrc.health + 10

请注意,这要求entitySpawn返回的表没有设置健康属性.如果确实如此,则永远不会为该属性咨询Metatable.

您可以在C中而不是Lua中创建entityGetters,entitySetters和entityMetatable表,以及__index和__newindex元方法,如果您感觉更干净,但总体思路是相同的.

猜你在找的Lua相关文章