一个C#纯值类型(注:指的是一个只包含值类型的struct,可以嵌套其它只包含值类型的struct)或者C#枚举值加上了这个配置。xLua会为该类型生成gc优化代码,效果是该值类型在lua和c#间传递不产生(C#)gc alloc,该类型的数组访问也不产生gc
除枚举之外,包含无参构造函数的复杂类型,都会生成lua table到该类型,以及改类型的一维数组的转换代码,这将会优化这个转换的性能,包括更少的gc alloc。
using UnityEngine;
using System;
using XLua;
namespace XLuaTest
{
[GCOptimize]
[LuaCallCSharp]
public struct Pedding
{
public byte c;
}
[GCOptimize]
[LuaCallCSharp]
public struct MyStruct
{
public MyStruct(int p1, int p2)
{
a = p1;
b = p2;
c = p2;
e.c = (byte)p1;
}
public int a;
public int b;
public decimal c;
public Pedding e;
}
[LuaCallCSharp]
public enum MyEnum
{
E1,
E2
}
[CSharpCallLua]
public delegate int IntParam(int p);
[CSharpCallLua]
public delegate Vector3 Vector3Param(Vector3 p);
[CSharpCallLua]
public delegate MyStruct CustomValueTypeParam(MyStruct p);
[CSharpCallLua]
public delegate MyEnum EnumParam(MyEnum p);
[CSharpCallLua]
public delegate decimal DecimalParam(decimal p);
[CSharpCallLua]
public delegate void ArrayAccess(Array arr);
[CSharpCallLua]
public interface IExchanger
{
void exchange(Array arr);
}
[LuaCallCSharp]
public class NoGc : MonoBehaviour
{
LuaEnv luaenv = new LuaEnv();
IntParam f1;
Vector3Param f2;
CustomValueTypeParam f3;
EnumParam f4;
DecimalParam f5;
ArrayAccess farr;
Action flua;
IExchanger ie;
LuaFunction add;
[NonSerialized]
public double[] a1 = new double[] { 1, 2 };
[NonSerialized]
public Vector3[] a2 = new Vector3[] { new Vector3(1, 2, 3), new Vector3(4, 5, 6) };
[NonSerialized]
public MyStruct[] a3 = new MyStruct[] { new MyStruct(1, 2), new MyStruct(3, 4) };
[NonSerialized]
public MyEnum[] a4 = new MyEnum[] { MyEnum.E1, MyEnum.E2 };
[NonSerialized]
public decimal[] a5 = new decimal[] { 1.00001M, 2.00002M };
public float FloatParamMethod(float p)
{
return p;
}
public Vector3 Vector3ParamMethod(Vector3 p)
{
return p;
}
public MyStruct StructParamMethod(MyStruct p)
{
return p;
}
public MyEnum EnumParamMethod(MyEnum p)
{
return p;
}
public decimal DecimalParamMethod(decimal p)
{
return p;
}
void Start()
{
luaenv.DoString(@"
function id(...)
return ...
end
function add(a, b) return a + b end
function array_exchange(arr)
arr[0], arr[1] = arr[1], arr[0]
end
--获取一个vector3对象
local v3 = CS.UnityEngine.Vector3(7, 8, 9)
--获取XLuaTest空间下的MyStruct结构体
local vt = CS.XLuaTest.MyStruct(5, 6)
--访问c#,加了[LuaCallCSharp]特性
function lua_access_csharp()
monoBehaviour:FloatParamMethod(123) --primitive
monoBehaviour:Vector3ParamMethod(v3) --vector3
local rnd = math.random(1, 100)
local r = monoBehaviour:Vector3ParamMethod({x = 1, y = 2, z = rnd}) --vector3
assert(r.x == 1 and r.y == 2 and r.z == rnd)
monoBehaviour:StructParamMethod(vt) --custom struct
r = monoBehaviour:StructParamMethod({a = 1, b = rnd, e = {c = rnd}})
assert(r.b == rnd and r.e.c == rnd)
monoBehaviour:EnumParamMethod(CS.XLuaTest.MyEnum.E2) --enum
monoBehaviour:DecimalParamMethod(monoBehaviour.a5[0])
monoBehaviour.a1[0], monoBehaviour.a1[1] = monoBehaviour.a1[1], monoBehaviour.a1[0] -- field
end
exchanger = {
exchange = function(self, arr)
array_exchange(arr)
end
}
A = { B = { C = 789}}
GDATA = 1234;
");
luaenv.Global.Set("monoBehaviour", this);
luaenv.Global.Get("id", out f1);
luaenv.Global.Get("id", out f2);
luaenv.Global.Get("id", out f3);
luaenv.Global.Get("id", out f4);
luaenv.Global.Get("id", out f5);
luaenv.Global.Get("array_exchange", out farr);
luaenv.Global.Get("lua_access_csharp", out flua);
luaenv.Global.Get("add", out add);
luaenv.Global.Get("exchanger", out ie);
luaenv.Global.Set("g_int", 123);
luaenv.Global.Set(123, 456);
int i;
luaenv.Global.Get("g_int", out i);
Debug.Log("g_int:" + i);
luaenv.Global.Get(123, out i);
Debug.Log("123:" + i);
}
void Update()
{
f1(1);
Vector3 v3 = new Vector3(1, 2, 3);
f2(v3);
MyStruct mystruct = new MyStruct(5, 6);
f3(mystruct);
f4(MyEnum.E1);
decimal d = -32132143143100109.00010001010M;
decimal dr = f5(d);
System.Diagnostics.Debug.Assert(d == dr);
System.Diagnostics.Debug.Assert(add.Func<int, int, int>(34, 56) == (34 + 56));
farr(a1);
farr(a2);
farr(a3);
farr(a4);
farr(a5);
flua();
ie.exchange(a2);
luaenv.Global.Set("g_int", 456);
int i;
luaenv.Global.Get("g_int", out i);
System.Diagnostics.Debug.Assert(i == 456);
luaenv.Global.Set(123.0001, mystruct);
MyStruct mystruct2;
luaenv.Global.Get(123.0001, out mystruct2);
System.Diagnostics.Debug.Assert(mystruct2.b == mystruct.b);
decimal dr2 = 0.0000001M;
luaenv.Global.Set((byte)12, d);
luaenv.Global.Get((byte)12, out dr2);
System.Diagnostics.Debug.Assert(d == dr2);
int gdata = luaenv.Global.Get<int>("GDATA");
luaenv.Global.SetInPath("GDATA", gdata + 1);
System.Diagnostics.Debug.Assert(luaenv.Global.Get<int>("GDATA") == gdata + 1);
int abc = luaenv.Global.GetInPath<int>("A.B.C");
luaenv.Global.SetInPath("A.B.C", abc + 1);
System.Diagnostics.Debug.Assert(luaenv.Global.GetInPath<int>("A.B.C") == abc + 1);
luaenv.Tick();
}
void OnDestroy()
{
f1 = null;
f2 = null;
f3 = null;
f4 = null;
f5 = null;
farr = null;
flua = null;
ie = null;
add = null;
luaenv.Dispose();
}
}
}