繁体   English   中英

是否可以将完整的“路径”保存到C函数中的Lua表字段?

[英]Is it possible to save the complete “path” to a Lua table field in a C function?

如果我在Lua中有这样的全局对象:

global_object = { }
global_object.stat_group_1 = { }
global_object.stat_group_2 = { }
global_object.stat_group_3 = { }
global_object.stat_group_1.stat_1 = 1 -- value changes with time
global_object.stat_group_1.stat_2 = 2 -- value changes with time
global_object.stat_group_1.stat_3 = 3 -- value changes with time
-- ... and same thing for other stat_groups

我的问题是关于luaL_reflua_rawgetilua_getfield 我可以使用luaL_ref来保存每个stat的路径,以避免在堆栈上显式调用所有stat ,如下所示:

int global_object_ref;
int stat_group_1_ref;
int stat_1_ref;

//assume this function has been called before any of the get_* functions
int start ( lua_State * L )
{
    lua_getfield ( L, LUA_RIDX_GLOBALS, "global_object" );
    lua_pushvalue ( L, -1 );
    global_object_ref = LuaL_ref ( L, LUA_REGISTRYINDEX );

    lua_getfield ( L, -1, "stat_group_1" );
    lua_pushvalue ( L, -1 );
    stat_group_1_ref = LuaL_ref ( L, LUA_REGISTRYINDEX );

    lua_getfield ( L, -1, "stat_1" );
    lua_pushvalue ( L, -1 );
    stat_group_1_ref = LuaL_ref ( L, LUA_REGISTRYINDEX );

    return 0;
}

//this is the prefered option. I would like this to be possible
int get_stat1_v1 ( lua_State * L )
{
    //stat_1 can have different values in the Lua table at different moments
    lua_rawgeti ( L, LUA_REGISTRYINDEX, stat_1_ref );

    //is this the value of the field stat_1?
    int value_of_stat_1 = lua_tointeger ( L, -1 );

    return 1;
}

//this is an alternative, in case v1 doesn't work. Would this work?
//again, remember stat_1 can have different values at different moments.
int get_stat1_v2 ( lua_State * L )
{
    lua_rawgeti ( L, LUA_REGISTRYINDEX, global_object_ref );
    lua_rawgeti ( L, LUA_REGISTRYINDEX, stat_group_1_ref );
    lua_rawgeti ( L, LUA_REGISTRYINDEX, stat_1_ref );

    //is this the value of the field stat_1?
    int value_of_stat_1 = lua_tointeger ( L, -1 );

    return 1;
}

请注意, v2将所有已保存的引用调用到堆栈上。 那样有用吗?

编辑:根据@Nicol Bolas的回答,我想提出一个v3 如果表和子表从不进行垃圾回收,但是它们的值不断更新(想象一下子表的整个结构像一棵树,每个子表是一个分支,每个基本值是一个叶子。树的结构保持不变在执行期间相同,但叶子得到更新)。

//this is the v3, where I learned how the Lua registry interacts with C, and propose
//a direct leaf access, but indirect branch access.
int get_stat1_v3 ( lua_State * L )
{
    //can I skip the line bellow and go directly to the next? Or do I have
    //to follow the whole hierarchy of branches?
    lua_rawgeti ( L, LUA_REGISTRYINDEX, global_object_ref );//is this needed?

    //I know I'm repeating myself, but I want to know if the call above
    //is necessary or not. Can I directly cut to the chase by calling this function?
    lua_rawgeti ( L, LUA_REGISTRYINDEX, stat_group_1_ref );

    //Notice that for this to work I'd have to removed the reference to stat_1
    //from the registry of my proven flawed implementation, so I wouldn't
    //freeze and pin down the value of stat_1, which means stat_1_ref gets
    //removed from the code.
    lua_getfield ( L, -1, "stat_1" );

    //is this the dynamically up to date value of the field stat_1?
    int value_of_stat_1 = lua_tointeger ( L, -1 );

    return 1;
}

您可以这样做,但是基本上您将放弃任何形式的垃圾收集。 注册表是Lua状态的一部分,因此只要这些表在注册表中,它们就必须存在。 因此,它们所引用的任何对象都将存在,直到您注销它们或关闭Lua状态为止。

您并没有真正保存“路径”。 您将在这些位置的表中保存实际值。 因此,如果表的值发生更改,则不会更新注册表中存储的内容。 保存stat_1的值将保存为当前值,而不是可能更改为的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM