c#读取lua嵌套表格
来源:互联网 发布:mac landesk 卸载 编辑:程序博客网 时间:2024/06/05 00:38
新项目,准备把行为树挪过来,需要解析行为树的xml配置。因为现在的项目使用的是lua配置,所以想可不可以使用嵌套table来实现xml的功能。
1 lua table 常用方法
lua与其他语言交互都是使用栈进行的,所以熟练掌握各种api对应的栈操作很重要。对于table比较重要的几个api和相应操作如下:
1.1 lua_gettable
lua_getglobal(L, "mytable") <== push mytablelua_pushnumber(L, 1) <== push key 1lua_gettable(L, -2) <== pop key 1, push mytable[1]
1.2 lua_settable
lua_getglobal(L, "mytable") <== push mytablelua_pushnumber(L, 1) <== push key 1lua_pushstring(L, "abc") <== push value "abc"lua_settable(L, -3) <== mytable[1] = "abc", pop key & value
1.3 lua_rawget:
用法同lua_gettable,但更快(因为当key不存在时不用访问元方法__index)
1.4 lua_rawset:
用法同lua_settable,但更快(因为当key不存在时不用访问元方法__newindex)
1.5 lua_rawgeti必须为数值键
lua_getglobal(L, "mytable") <== push mytablelua_rawgeti(L, -1, 1) <== push mytable[1],作用同下面两行调用--lua_pushnumber(L, 1) <== push key 1--lua_rawget(L,-2) <== pop key 1, push mytable[1]
1.6 lua_rawseti必须为数值键
lua_getglobal(L, "mytable") <== push mytablelua_pushstring(L, "abc") <== push value "abc"lua_rawseti(L, -2, 1) <== mytable[1] = "abc", pop value "abc"
1.7 lua_getfield必须为字符串键
lua_getglobal(L, "mytable") <== push mytablelua_getfield(L, -1, "x") <== push mytable["x"],作用同下面两行调用--lua_pushstring(L, "x") <== push key "x"--lua_gettable(L,-2) <== pop key "x", push mytable["x"]
1.8 lua_setfield必须为字符串键
lua_getglobal(L, "mytable") <== push mytablelua_pushstring(L, "abc") <== push value "abc"lua_setfield(L, -2, "x") <== mytable["x"] = "abc", pop value "abc"
2 迭代及递归遍历table
2.1 lua_next
上文中的api大多需要知道key,这个可以解析固定格式的k-v对,但是想要递归遍历嵌套表格,就需要在不知道具体key值的情况下进行迭代。这时候需要lua_next接口。
上图显示了lua_next在调用过程中栈的变化情况(这里省略了栈底元素table),整个过程分为以下几步:
1. 如果栈顶元素为nil,则弹出nil,将table第一个k-v对中的key和value先后入栈,返回true;
2. 如果栈顶元素为key,先弹出当前key,并以该key为基础,将table的下一个k-v对中的key和value先后入栈,返回true;
3. 如果栈顶元素为最后一个key,则弹出key,然后返回false;
再用代码示意一遍。
//循环遍历lua_pushnil(L);此时lua栈状态----------------------------------| -1 nil| -2 table NUMBER_TABLE----------------------------------while(lua_next(L,-2)){ 此时lua栈状态 ---------------------------------- | -1 value | -2 key | -3 table NUMBER_TABLE ---------------------------------- if(lua_isnumber(L,-2)) cout<<"key:"<<lua_tonumber(L,-2)<<'\t'; else if(lua_isstring(L,-2)) cout<<"key:"<<lua_tostring(L,-2)<<'\t'; if(lua_isnumber(L,-1)) cout<<"value:"<<lua_tonumber(L,-1)<<endl; else if(lua_isstring(L,-1)) cout<<"value:"<<lua_tostring(L,-1)<<endl; /*此时lua栈状态 ---------------------------------- | -1 value | -2 key | -3 table NUMBER_TABLE ---------------------------------- */ lua_pop(L,1); /*此时lua栈状态 ---------------------------------- | -1 key | -2 table NUMBER_TABLE ---------------------------------- */}/*此时lua栈状态----------------------------------| -1 table NUMBER_TABLE----------------------------------*/
2.2 递归访问lua_table
了解了lua_next的工作原理之后,我们可以使用其进行递归访问table。
void ParseLuaTable(lua_State *L){ if (!lua_istable(L, -1)) { return; } lua_pushnil(L); while (lua_next(L, -2)) { fprintf(stdout, "%s : %s ", luaL_typename(L,-2), luaL_typename(L,-1)); int nKeyType = lua_type(L, -2); int nValueType = lua_type(L, -1); if (nKeyType == LUA_TNUMBER) fprintf(stdout, "%g,", lua_tonumber(L, -2)); else if (nKeyType == LUA_TSTRING) fprintf(stdout, "\"%s\",", lua_tostring(L, -2)); if (nValueType == LUA_TNUMBER) fprintf(stdout, "%g", lua_tonumber(L, -1)); else if (nValueType == LUA_TSTRING) fprintf(stdout, "\"%s\"", lua_tostring(L, -1)); else if (nValueType == LUA_TTABLE) { fprintf(stdout, "\n"); // 这里进行递归访问table ParseLuaTable(L); } lua_pop(L, 1); fprintf(stdout, "\n"); }}int test(){ lua_State *L = luaL_newstate(); luaL_openlibs(L); int error = 0; // test.lua //s = { //g = "g", //b = "b", //r = 2, //t = { // width = 100, // height = 200, // path = "path", // te = { a = 1, b = 2} //}, // //3, //4, //5, //"test" //} // luaL_loadfile(L, "test.lua"); error = lua_pcall(L, 0, 0, 0); if (error) { fprintf(stderr, "%s", lua_tostring(L, -1)); lua_pop(L, 1);/* pop error message from the stack */ } lua_getglobal(L, "s"); ParseLuaTable(L); if (error) { fprintf(stderr, "%s", lua_tostring(L, -1)); lua_pop(L, 1);/* pop error message from the stack */ } return 0;}
了解了这些api的使用原理,使用table嵌套构造行为树配置就方便的多。而且,相比xml配置,lua配置更加简洁灵活。
这里要注意一个问题,lua_next在对表格中的k-v对进行遍历的时候,不保证顺序!!!
这里要注意一个问题,lua_next在对表格中的k-v对进行遍历的时候,不保证顺序!!!
这里要注意一个问题,lua_next在对表格中的k-v对进行遍历的时候,不保证顺序!!!
阅读全文
0 0
- c#读取lua嵌套表格
- C#读取Excel表格
- C#读取excel表格
- C#读取Word表格数据
- c#读取Execl表格数据
- lua table输出函数(可以输出嵌套表格)
- C#读取word表格保存到sql
- C#实现Word中表格信息读取
- 使用C#读取Word表格数据
- C#实现Word中表格信息读取
- C#读取word表格到DataTable
- C# 读取Excel表格中的内容
- C#实现Word中表格信息读取
- C#读取Excel表格的方法
- 嵌套读取
- 如何使用C#向Word文档中添加表格和嵌套表格
- HTML表格嵌套、合并表格
- lua 读取lua文件
- Head First JavaScript 存储数据
- 数据增强:DataAugmentation
- Java中管道报错:Write end dead
- java中static关键字理解
- oracle数据库存储迁移参考
- c#读取lua嵌套表格
- 解决ScrollView嵌套RecyclerView 滑动卡顿和嵌套多个RecyclerView 显示不全的问题
- Eclipse:An internal error occurred during: "Build Project". GC overhead limit exceeded
- Unix系统的发展简介
- python杂记
- eclipse下tomcat启动器执行两次
- 使用AWS遇到的一些问题
- pip 直接安装tar.gz zip文件包 (windows linux mac 可用)
- python基础之四