当前位置: 首页 > news >正文

如何构建个人网站安阳贴吧论坛

如何构建个人网站,安阳贴吧论坛,wordpress搬家后访问异常,网站后台登陆不进去xlua源码分析#xff08;五#xff09; struct类型优化 上一节我们分析了xlua是如何实现lua层访问C#值类型的#xff0c;其中我们重点提到了xlua默认实现方式下#xff0c;struct访问的效率问题。实际上#xff0c;xlua还提供了两种优化的方式#xff0c;可以大大提高str… xlua源码分析五 struct类型优化 上一节我们分析了xlua是如何实现lua层访问C#值类型的其中我们重点提到了xlua默认实现方式下struct访问的效率问题。实际上xlua还提供了两种优化的方式可以大大提高struct访问的性能。具体例子在Examples 12_ReImplementInLua中。 第一种优化方式就是在lua层改造C#的structC# struct push到lua层时仍为userdata但它的metatable不指向C#层struct而是lua层自己实现的 function test_vector3(title, v1, v2)print(title)v1.x 100print(v1.x, v1.y, v1.z)print(v1, v2)print(v1 v2)v1:Set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)print(v1)print(CS.UnityEngine.Vector3.Normalize(v1)) endlocal get_x, set_x xlua.genaccessor(0, 8) local get_y, set_y xlua.genaccessor(4, 8) local get_z, set_z xlua.genaccessor(8, 8)local fields_getters {x get_x, y get_y, z get_z } local fields_setters {x set_x, y set_y, z set_z }local ins_methods {Set function(o, x, y, z)set_x(o, x)set_y(o, y)set_z(o, z)end }local mt {__index function(o, k)--print(__index, k)if ins_methods[k] then return ins_methods[k] endreturn fields_getters[k] and fields_getters[k](o)end,__newindex function(o, k, v)if fields_setters[k] then fields_setters[k](o, v) else error(no such field .. k) endend,__tostring function(o)return string.format(vector3 { %f, %f, %f}, o.x, o.y, o.z)end,__add function(a, b)return CS.UnityEngine.Vector3(a.x b.x, a.y b.y, a.z b.z)end }xlua.setmetatable(CS.UnityEngine.Vector3, mt) test_vector3(----after change metatable----, CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))这里的代码就是在lua层实现了一下Vector3的get/set属性和方法然后替换掉原先的metatablexlua.setmetatable就是做这个工作的替换的逻辑很简单就是找到要替换类的type id重新设置到registry表里 public static int XLuaMetatableOperation(RealStatePtr L) {try{ObjectTranslator translator ObjectTranslatorPool.Instance.Find(L);Type type getType(L, translator, 1);if (type null){return LuaAPI.luaL_error(L, xlua.metatable_operation, can not find c# type);}bool is_first false;int type_id translator.getTypeId(L, type, out is_first);var param_num LuaAPI.lua_gettop(L);if (param_num 1) //get{LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);return 1;}else if (param_num 2) //set{if (LuaAPI.lua_type(L, 2) ! LuaTypes.LUA_TTABLE){return LuaAPI.luaL_error(L, argument #2 must be a table);}LuaAPI.lua_pushnumber(L, type_id);LuaAPI.xlua_rawseti(L, 2, 1);LuaAPI.xlua_rawseti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);return 0;}else{return LuaAPI.luaL_error(L, invalid argument num for xlua.metatable_operation: param_num);}}catch (Exception e){return LuaAPI.luaL_error(L, c# exception in xlua.metatable_operation: e);} }不过lua层的Vector3依旧是userdata如何在lua层对userdata设置/获取数据呢为此xlua提供了xlua.genaccessor函数它接受两个参数第一个参数表示要设置/获取的字段相对于struct的内存偏移第二个参数表示要设置/获取的字段类型对于Vector3xyz的偏移分别为048而它们的类型均为floatfloat在xlua预先定义的类型ID为8 #define T_INT8 0 #define T_UINT8 1 #define T_INT16 2 #define T_UINT16 3 #define T_INT32 4 #define T_UINT32 5 #define T_INT64 6 #define T_UINT64 7 #define T_FLOAT 8 #define T_DOUBLE 9genaccessor函数是在C层实现的那其实很简单了就是把userdata作为要访问内存的首地址加上偏移量offset执行memcpy即可如果是get就是从userdata拷贝到value再push到lua栈如果是set就先从lua栈上取出value再拷贝到userdata。 #define DIRECT_ACCESS(type, push_func, to_func) \ int xlua_struct_get_##type(lua_State *L) {\CSharpStruct *css (CSharpStruct *)lua_touserdata(L, 1);\int offset xlua_tointeger(L, lua_upvalueindex(1));\type val;\if (css NULL || css-fake_id ! -1 || css-len offset sizeof(type)) {\return luaL_error(L, invalid c# struct!);\} else {\memcpy(val, ((css-data[0]) offset), sizeof(type));\push_func(L, val);\return 1;\}\ }\ \ int xlua_struct_set_##type(lua_State *L) { \CSharpStruct *css (CSharpStruct *)lua_touserdata(L, 1);\int offset xlua_tointeger(L, lua_upvalueindex(1));\type val;\if (css NULL || css-fake_id ! -1 || css-len offset sizeof(type)) {\return luaL_error(L, invalid c# struct!);\} else {\val (type)to_func(L, 2);\memcpy(((css-data[0]) offset), val, sizeof(type));\return 0;\}\ }\上面例子的运行结果如下 第二种优化方式是将struct映射成table即C#层push到lua层的struct不再为userdata而是一个tablexlua提供了PackAsTable这个attribute指示生成代码时采用映射table的方式 [GCOptimize(OptimizeFlag.PackAsTable)] public struct PushAsTableStruct {public int x;public int y; }然后lua层也需要实现配套的代码即struct的object metatable和class metatable相当于在lua层实现struct local mt {__index {SwapXY function(o) --成员函数o.x, o.y o.y, o.xend},__tostring function(o) --打印格式化函数return string.format(struct { %d, %d}, o.x, o.y)end, }xlua.setmetatable(CS.XLuaTest.PushAsTableStruct, mt)local PushAsTableStruct {Print function(o) --静态函数print(o.x, o.y)end }setmetatable(PushAsTableStruct, {__call function(_, x, y) --构造函数return setmetatable({x x, y y}, mt)end })xlua.setclass(CS.XLuaTest, PushAsTableStruct, PushAsTableStruct)在测试代码中我们先在C#层push一下struct PushAsTableStruct test; test.x 100; test.y 200; luaenv.Global.Set(from_cs, test);然后再在lua层进行测试 print(--------------from csharp---------------------) assert(type(from_cs) table) print(from_cs) CS.XLuaTest.PushAsTableStruct.Print(from_cs) from_cs:SwapXY() print(from_cs)print(--------------from lua---------------------) local from_lua CS.XLuaTest.PushAsTableStruct(4, 5) assert(type(from_lua) table) print(from_lua) CS.XLuaTest.PushAsTableStruct.Print(from_lua) from_lua:SwapXY() print(from_lua)此时C#层push时不会再生成userdata而是生成一个table然后设置字段x和字段y public void PushXLuaTestPushAsTableStruct(RealStatePtr L, XLuaTest.PushAsTableStruct val) {if (XLuaTestPushAsTableStruct_TypeID -1){bool is_first;XLuaTestPushAsTableStruct_TypeID getTypeId(L, typeof(XLuaTest.PushAsTableStruct), out is_first);}LuaAPI.xlua_pushcstable(L, 2, XLuaTestPushAsTableStruct_TypeID);LuaAPI.xlua_pushasciistring(L, x);LuaAPI.xlua_pushinteger(L, val.x);LuaAPI.lua_rawset(L, -3);LuaAPI.xlua_pushasciistring(L, y);LuaAPI.xlua_pushinteger(L, val.y);LuaAPI.lua_rawset(L, -3);}同样的道理要从lua层把struct传递到C#层就要获取lua层的table把它的字段x和字段y取出依次赋值到C#对象上 public static void UnPack(ObjectTranslator translator, RealStatePtr L, int idx, out XLuaTest.PushAsTableStruct val) {val new XLuaTest.PushAsTableStruct();int top LuaAPI.lua_gettop(L);if (Utils.LoadField(L, idx, x)){translator.Get(L, top 1, out val.x);}LuaAPI.lua_pop(L, 1);if (Utils.LoadField(L, idx, y)){translator.Get(L, top 1, out val.y);}LuaAPI.lua_pop(L, 1);}例子的输出结果如下 这两种优化方式各有优劣第一种方式userdata比table更加省内存而第二种方式使用原始table操作性能上要比使用userdata要好。两种方式都需要额外生成一些代码。与tolua相比tolua的struct是采用了类似第二种的方式tolua的struct在lua层就是个table需要完整按照C#层实现一遍struct。而数据传输的逻辑稍微不太相同tolua是使用lua函数进行数据传输例如Vector3tolua可以通过一个get函数直接返回3个float*给C#层也可以通过一个new函数直接使用xyz三个参数构造出一个lua层的structpack和unpack的逻辑都放在了lua层里。 function Vector3.New(x, y, z) local t {x x or 0, y y or 0, z z or 0}setmetatable(t, Vector3) return t endfunction Vector3.Get(v) return v.x, v.y, v.z end
http://www.yayakq.cn/news/2450/

相关文章:

  • php精品网站建设连云港市建设工程安全监督站网站
  • 泰州营销型网站工程造价信息网官网信息价
  • 全国水利建设市场信用信息平台门户网站比较有设计感的网站
  • 寺庙网站开发建设方案安徽智能网站建设制作
  • 石家庄网站推广专业鑫菲互动网站建设公司
  • 网站名称写什么网易邮箱163登录入口
  • 成都网站排名app开发多少钱?
  • 网站导航插件wordpress第三方账号
  • 动画做a视频在线观看网站太原市手机微网站建设
  • 广告网站制作多少钱卓博人才网手机版
  • 网站开发技术有哪些网站推广具体内容
  • 不用买服务器可以做网站wordpress 不同侧边栏
  • 网站主视觉网站开发岗位群
  • 网上做任务挣钱的网站北大青鸟网站建设
  • 如何优化网站代码梁平网站建设
  • 如何做网站不容易被攻击企业招聘
  • 网站开发例子网络黄页推广软件下载
  • 自己做优惠劵网站赚钱吗wix做的网站能扒下来
  • 汕头建站服务张裕网站建设的目标
  • o2o网站建设好么深圳网站公司招聘
  • 做网站能用的字体如何搭建一个企业子账号网站
  • 做网站用框架么网站备案必须在公司注册地
  • 电子商务网站设计的基本要求管理系统门户网站开发路线
  • 做网站软件有哪些东莞市建设网
  • 苏州比较大的网站公司网站建设项目管理
  • 厦门网站设计制作购物网站服务中心
  • 有没有做卡商的网站wordpress 好慢哪
  • 网站开发实战网络课建一网站要多少钱
  • 网站域名到期后不续费会怎样小学生小发明小制作大全
  • 大理建设工程招聘信息网站做pc端网站平台