You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.8 KiB
140 lines
4.8 KiB
using UnityEngine;
|
|
using System.Collections;
|
|
using XLua;
|
|
|
|
[GCOptimize(OptimizeFlag.PackAsTable)]
|
|
public struct PushAsTableStruct
|
|
{
|
|
public int x;
|
|
public int y;
|
|
}
|
|
|
|
public class ReImplementInLua : MonoBehaviour {
|
|
|
|
// Use this for initialization
|
|
void Start () {
|
|
LuaEnv luaenv = new LuaEnv();
|
|
//这两个例子都必须生成代码才能正常运行
|
|
//例子1:改造Vector3
|
|
//沿用Vector3原来的映射方案Vector3 -> userdata,但是把Vector3的方法实现改为lua实现,通过xlua.genaccessor实现不经过C#直接操作内存
|
|
//改为不经过C#的好处是性能更高,而且你可以省掉相应的生成代码以达成省text段的效果
|
|
//仍然沿用映射方案的好处是userdata比table更省内存,但操作字段比table性能稍低,当然,你也可以结合例子2的思路,把Vector3也改为映射到table
|
|
luaenv.DoString(@"
|
|
function test_vector3(title, v1, v2)
|
|
print(title)
|
|
print(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))
|
|
end
|
|
test_vector3('----before change metatable----', CS.UnityEngine.Vector3(1, 2, 3), CS.UnityEngine.Vector3(7, 8, 9))
|
|
|
|
local 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] end
|
|
return fields_getters[k] and fields_getters[k](o)
|
|
end,
|
|
|
|
__newindex = function(o, k, v)
|
|
return fields_setters[k] and fields_setters[k](o, v) or error('no such field ' .. k)
|
|
end,
|
|
|
|
__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))
|
|
");
|
|
|
|
Debug.Log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
|
|
|
//例子2:struct映射到table改造
|
|
//PushAsTableStruct传送到lua侧将会是table,例子里头还为这个table添加了一个成员方法SwapXY,静态方法Print,打印格式化,以及构造函数
|
|
luaenv.DoString(@"
|
|
local mt = {
|
|
__index = {
|
|
SwapXY = function(o) --成员函数
|
|
o.x, o.y = o.y, o.x
|
|
end
|
|
},
|
|
|
|
__tostring = function(o) --打印格式化函数
|
|
return string.format('struct { %d, %d}', o.x, o.y)
|
|
end,
|
|
}
|
|
|
|
xlua.setmetatable(CS.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, 'PushAsTableStruct', PushAsTableStruct)
|
|
");
|
|
|
|
PushAsTableStruct test;
|
|
test.x = 100;
|
|
test.y = 200;
|
|
luaenv.Global.Set("from_cs", test);
|
|
|
|
luaenv.DoString(@"
|
|
print('--------------from csharp---------------------')
|
|
assert(type(from_cs) == 'table')
|
|
print(from_cs)
|
|
CS.PushAsTableStruct.Print(from_cs)
|
|
from_cs:SwapXY()
|
|
print(from_cs)
|
|
|
|
print('--------------from lua---------------------')
|
|
local from_lua = CS.PushAsTableStruct(4, 5)
|
|
assert(type(from_lua) == 'table')
|
|
print(from_lua)
|
|
CS.PushAsTableStruct.Print(from_lua)
|
|
from_lua:SwapXY()
|
|
print(from_lua)
|
|
");
|
|
|
|
luaenv.Dispose();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update () {
|
|
|
|
}
|
|
}
|
|
|