[英]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_ref
, lua_rawgeti
和lua_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.