【问题标题】:Array index access from metatable field/method从元表字段/方法访问数组索引
【发布时间】:2014-06-17 02:09:46
【问题描述】:

我有一些反映一些 C++ 类/结构的元表。我通常依靠 __index 来调用对象的任何字段/方法并在一个函数中解析它们。

我遇到的困难是当我想将参数传递给一个字段时,就像这样:

anim = playerInfo.animations
while anim do

  print (anim)

  numstates = anim.numstates
  for i = 1, numstates do

    state = anim.states(i)  <--- This line right here is the issue
    print(state)

  end

  anim = anim.next

end

下面是相关的C代码:

static const struct luaL_Reg objanimationlib_m[] = {
    {"__tostring", objanimation2string},
    {"__index", objanimationget},
    {"__newindex", objanimationset},
    {NULL, NULL}
};

    luaL_newmetatable(L, "objanimation");
    lua_pushvalue(L, -1); // duplicates the metatable
    luaL_setfuncs(L, objanimationlib_m, 0);

__index 函数内部:

else if (!strcmp(field, "states"))
{
    int number = (int)luaL_checknumber(L, 3) - 1; // -1 cuz Lua is not 0-based
    if (number >= anim->numstates)
        return 0;

    PushUserdata(&anim->states[number], "objstate");
}

运行脚本,出现错误:

Warning: [string "test.lua"]:13: bad argument #3 to '__index' (number expected, got no value)

我觉得我错过了一些简单得愚蠢的东西。这是什么?

编辑:这是我的解决方案,在 __index 函数中:

else if (!strcmp(field, "states"))
{
    lua_newtable(L);

    int i;
    for (i = 0; i < anim->numstates; i++)
    {
          PushUserdata(&anim->states[i], "objstate");
          lua_rawseti(L, -2, i+1);
    }
}

这将返回一个充满用户数据元素的表。可能很昂贵,所以这也会提高性能:

anim = playerInfo.animations
while anim do

  print (anim)

  numstates = anim.numstates
  states = anim.states
  for i = 1, numstates do

    print(states[i])

  end

  anim = anim.next

end

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

    state = anim.states(i)

    等价于

    do local f=anim.states; state=f(i) end

    所以你的元方法永远不会看到i

    换句话说,索引元方法接收两个参数,表和键。它返回的内容不一定受任何元方法的约束,除非你明确地这样做。

    我会去定义__len返回numstates__call来处理anim.states(i),这样你的代码就可以编写了

      for i = 1, #anim do
        state = anim(i)
        print(state)
      end
    

    【讨论】:

    • 这是一个很好的解决方案,在其他情况下可能会派上用场。对于这个特定的,我不想破坏底层实现的语法,所以我只需要组成一个完整的用户数据表来返回。 (动画可能包含其他数组)。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多