ReImplementInLua

ReImplementInLua.cs

  1. using UnityEngine;
  2. using System.Collections;
  3. using XLua;
  4. [GCOptimize(OptimizeFlag.PackAsTable)]
  5. public struct PushAsTableStruct
  6. {
  7. public int x;
  8. public int y;
  9. }
  10. public class ReImplementInLua : MonoBehaviour {
  11. // Use this for initialization
  12. void Start () {
  13. LuaEnv luaenv = new LuaEnv();
  14. //这两个例子都必须生成代码才能正常运行
  15. //例子1:改造Vector3
  16. //沿用Vector3原来的映射方案Vector3 -> userdata,但是把Vector3的方法实现改为lua实现,通过xlua.genaccessor实现不经过C#直接操作内存
  17. //改为不经过C#的好处是性能更高,而且你可以省掉相应的生成代码以达成省text段的效果
  18. //映射仍然沿用的好处是userdata比table更省内存,但操作字段比table性能稍低,当然,你也可以结合例子2的思路,把Vector3也改为映射到table
  19. luaenv.DoString(@"
  20. function test_vector3(title, v1, v2)
  21. print(title)
  22. print(v1.x, v1.y, v1.z)
  23. print(v1, v2)
  24. print(v1 + v2)
  25. v1:Set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
  26. print(v1)
  27. print(CS.UnityEngine.Vector3.Normalize(v1))
  28. end
  29. test_vector3('----before change metatable----', CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))
  30. local get_x, set_x = xlua.genaccessor(0, 8)
  31. local get_y, set_y = xlua.genaccessor(4, 8)
  32. local get_z, set_z = xlua.genaccessor(8, 8)
  33. local fields_getters = {
  34. x = get_x, y = get_y, z = get_z
  35. }
  36. local fields_setters = {
  37. x = set_x, y = set_y, z = set_z
  38. }
  39. local ins_methods = {
  40. Set = function(o, x, y, z)
  41. set_x(o, x)
  42. set_y(o, y)
  43. set_z(o, z)
  44. end
  45. }
  46. local mt = {
  47. __index = function(o, k)
  48. --print('__index', k)
  49. if ins_methods[k] then return ins_methods[k] end
  50. return fields_getters[k] and fields_getters[k](o)
  51. end,
  52. __newindex = function(o, k, v)
  53. return fields_setters[k] and fields_setters[k](o, v) or error('no such field ' .. k)
  54. end,
  55. __tostring = function(o)
  56. return string.format('vector3 { %f, %f, %f}', o.x, o.y, o.z)
  57. end,
  58. __add = function(a, b)
  59. return CS.UnityEngine.Vector3(a.x + b.x, a.y + b.y, a.z + b.z)
  60. end
  61. }
  62. xlua.setmetatable(CS.UnityEngine.Vector3, mt)
  63. test_vector3('----after change metatable----', CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))
  64. ");
  65. Debug.Log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  66. //例子2:struct映射到table改造
  67. //PushAsTableStruct传送到lua侧将会是table,例子里头还为这个table添加了一个成员方法SwapXY,静态方法Print,打印格式化,以及构造函数
  68. luaenv.DoString(@"
  69. local mt = {
  70. __index = {
  71. SwapXY = function(o) --成员函数
  72. o.x, o.y = o.y, o.x
  73. end
  74. },
  75. __tostring = function(o) --打印格式化函数
  76. return string.format('struct { %d, %d}', o.x, o.y)
  77. end,
  78. }
  79. xlua.setmetatable(CS.PushAsTableStruct, mt)
  80. local PushAsTableStruct = {
  81. Print = function(o) --静态函数
  82. print(o.x, o.y)
  83. end
  84. }
  85. setmetatable(PushAsTableStruct, {
  86. __call = function(_, x, y) --构造函数
  87. return setmetatable({x = x, y = y}, mt)
  88. end
  89. })
  90. xlua.setclass(CS, 'PushAsTableStruct', PushAsTableStruct)
  91. ");
  92. PushAsTableStruct test;
  93. test.x = 100;
  94. test.y = 200;
  95. luaenv.Global.Set("from_cs", test);
  96. luaenv.DoString(@"
  97. print('--------------from csharp---------------------')
  98. assert(type(from_cs) == 'table')
  99. print(from_cs)
  100. CS.PushAsTableStruct.Print(from_cs)
  101. from_cs:SwapXY()
  102. print(from_cs)
  103. print('--------------from lua---------------------')
  104. local from_lua = CS.PushAsTableStruct(4, 5)
  105. assert(type(from_lua) == 'table')
  106. print(from_lua)
  107. CS.PushAsTableStruct.Print(from_lua)
  108. from_lua:SwapXY()
  109. print(from_lua)
  110. ");
  111. luaenv.Dispose();
  112. }
  113. // Update is called once per frame
  114. void Update () {
  115. }
  116. }

?