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

asp网站建设与设计WordPress qinmei影视主题

asp网站建设与设计,WordPress qinmei影视主题,长春网站设计长春网络推广,东莞最新招聘信息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.w-s-a.com/news/197160/

相关文章:

  • 网站重新搭建程序要多少钱移动互联网应用的使用情况
  • 学建站论坛给别人做网站怎么赚钱吗
  • 响应式网站代码校友会网站建设的目的
  • 北京公司网站网站建设html模板
  • 专门做医疗器械的网站免费网页制作系统团队
  • 网站开发技术 html临夏网站建设
  • flash网站模板免费下载拍卖网站开发多少钱
  • 北京网站建设制作颍州网站建设
  • 网站制作报价表做网站上海公司
  • 简洁大气蓝色文章资讯网站百度搜索广告推广
  • 河南建设工程协会网站网站收银系统建设
  • 网站制作 服务企业网站案例展示
  • 咸宁网站建设wordpress手动降级
  • 昆明做网站建设怎么样做网站赚钱全攻略
  • 企业网站建设实战教程微信如何注册小程序
  • 做一件代发网站百度seo服务
  • 小说网站开发 公司可以做行程的网站
  • 古交市网站建设公司apk连接wordpress
  • 网页 网 址网站区别wordpress菜单居右
  • 网站建设搭建运营一台云服务器做多个网站
  • 用php做网站用什么框架推广网站推荐
  • 如何用二级域名做网站多用户网上商城
  • 河南省建设科技网站浅谈电子商务网站建设与规划
  • 网站空间需要续费青海网站建设推广
  • 网站开发本地环境企业网站建设排名口碑
  • 做新闻的网站怎样赚钱个人网站课程设计报告
  • 网站设计样例那个网站做图片好看
  • 小型公司网站建设深圳网络营销策划有限公司
  • 国内优秀企业网站做视频网站用什么系统
  • 网站建设入门pdfwordpress网站标题