使用 LuaJIT,我如何将多个元表与一个 C 结构关联起来?

问题描述 投票:0回答:1

我目前正在开发自己的游戏引擎,它使用 C 和 LuaJIT,并且正在为我的实体层次结构编写脚本。作为层次结构设计的一部分,我在这里有一个节点结构,并且使用指向特定于节点的数据的空指针。

typedef struct game_node_t game_node;
typedef struct game_node_vector_t game_node_vec;

struct game_node_t {
    const char *name;
    game_node* parent;
    game_node_vec children;

    enum GAME_NODE_TYPES type;
    void *data;
};

但是,在我的脚本中,我想对不同的节点类型使用元表,以便类似于面向对象的编程,但我当前的设计阻止我稍后这样做:

game.sound = ffi.metatype("game_node", sound_metatable)
game.sprite = ffi.metatype("game_node", sprite_metatable)

这将为节点类型声音和精灵提供特定的方法。由此产生的错误是“无法更改受保护的元表”,在阅读 LuaJIT 的文档后,这并不奇怪。

到目前为止,我只尝试将其放入我的 cdef 中:

typedef struct game_node_t game_sound_node;
typedef struct game_node_t game_sprite_node;

这样做:

game.sound = ffi.metatype("game_sound_node", sound_metatable)
game.sprite = ffi.metatype("game_sprite_node", sprite_metatable)

这仍然会导致“无法更改受保护的元表”。我应该考虑任何设计更改或潜在的解决方法吗?

c lua luajit
1个回答
0
投票

我想出了自己的解决方案。我编写了一个创建节点的函数,它替换了每种节点类型的新方法。

local type_table = {
    sound = sound_metatable.new,
    sprite = sprite_metatable.new
}

function create_node(type)
    return type_table[type]()
end

然后,我编写了一个新的元表,它根据节点的类型查找函数表。

local lookup_table = {
    [sound_enum] = sound_metatable,
    [sprite_enum] = sprite_metatable
}

local test_metatable = {
    __index = function (table, key)
        print(tonumber(table.type))
        return lookup_table[tonumber(table.type)][key]
    end
}

那么,我可以这样做:

game.node = ffi.metatype("game_node", test_metatable)

它增加了少量的开销,但它使我能够拥有一个 C 结构,该结构根据类型值具有不同的函数集。

© www.soinside.com 2019 - 2024. All rights reserved.