目录
0.代码备注
自己划分了一下模块,方便学习debug测试
1.C# StatefullTest
using UnityEngine;
namespace XLuaTest
{
[XLua.Hotfix]
public class StatefullTest
{
public StatefullTest()
{
}
public StatefullTest(int a, int b)
{
if (a > 0)
{
return;
}
Debug.Log("a=" + a);
if (b > 0)
{
return;
}
else
{
if (a + b > 0)
{
return;
}
}
Debug.Log("b=" + b);
}
public int AProp
{
get;
set;
}
public event System.Action<int, double> AEvent;
public int this[string field]
{
get
{
return 1;
}
set
{
}
}
public void Start()
{
}
void Update()
{
}
public void GenericTest<T>(T a)
{
}
static public void StaticFunc(int a, int b)
{
}
static public void StaticFunc(string a, int b, int c)
{
}
~StatefullTest()
{
Debug.Log("~StatefullTest");
}
}
}
2.C# HotfixTest2
using UnityEngine;
using XLua;
namespace XLuaTest
{
[Hotfix]
public class HotfixCalc
{
public int Add(int a, int b)
{
return a - b;
}
public Vector3 Add(Vector3 a, Vector3 b)
{
return a - b;
}
public int TestOut(int a, out double b, ref string c)
{
b = a + 2;
c = "wrong version";
return a + 3;
}
public int TestOut(int a, out double b, ref string c, GameObject go)
{
return TestOut(a, out b, ref c);
}
public T Test1<T>()
{
return default(T);
}
public T1 Test2<T1, T2, T3>(T1 a, out T2 b, ref T3 c)
{
b = default(T2);
return a;
}
public static int Test3<T>(T a)
{
return 0;
}
public static void Test4<T>(T a)
{
}
public void Test5<T>(int a, params T[] arg)
{
}
}
public class NoHotfixCalc
{
public int Add(int a, int b)
{
return a + b;
}
}
[Hotfix]
public class GenericClass<T>
{
T a;
public GenericClass(T a)
{
this.a = a;
}
public void Func1()
{
Debug.Log("a=" + a);
}
public T Func2()
{
return default(T);
}
}
[Hotfix]
public class InnerTypeTest
{
public void Foo()
{
_InnerStruct ret = Bar();
Debug.Log("{x=" + ret.x + ",y= " + ret.y + "}");
}
struct _InnerStruct
{
public int x;
public int y;
}
_InnerStruct Bar()
{
return new _InnerStruct { x = 1, y = 2 };
}
}
public class BaseTestHelper
{
}
public class BaseTestBase<T> : BaseTestHelper
{
public virtual void Foo(int p)
{
Debug.Log("BaseTestBase<>.Foo, p = " + p);
}
}
[Hotfix]
[LuaCallCSharp]
public class BaseTest : BaseTestBase<InnerTypeTest>
{
public override void Foo(int p)
{
Debug.Log("BaseTest<>.Foo, p = " + p);
}
public void Proxy(int p)
{
base.Foo(p);
}
public override string ToString()
{
return base.ToString();
}
}
[Hotfix]
public struct StructTest
{
GameObject go;
public StructTest(GameObject go)
{
this.go = go;
}
public GameObject GetGo(int a, object b)
{
return go;
}
public override string ToString()
{
return base.ToString();
}
public string Proxy()
{
return base.ToString();
}
}
[Hotfix]
public struct GenericStruct<T>
{
T a;
public GenericStruct(T a)
{
this.a = a;
}
public T GetA(int p)
{
return a;
}
}
public class HotfixTest2 : MonoBehaviour
{
void Start()
{
LuaEnv luaenv = new LuaEnv();
HotfixCalc calc = new HotfixCalc();
NoHotfixCalc ordinaryCalc = new NoHotfixCalc();
#region 使用or不使用热更新性能对比
//int CALL_TIME = 100 * 1000 * 1000;
//var start = System.DateTime.Now;
//for (int i = 0; i < CALL_TIME; i++)
//{
// calc.Add(2, 1);
//}
//var d1 = (System.DateTime.Now - start).TotalMilliseconds;
//Debug.Log("Hotfix using:" + d1);
//start = System.DateTime.Now;
//for (int i = 0; i < CALL_TIME; i++)
//{
// ordinaryCalc.Add(2, 1);
//}
//var d2 = (System.DateTime.Now - start).TotalMilliseconds;
//Debug.Log("No Hotfix using:" + d2);
//Debug.Log("drop:" + ((d1 - d2) / d1));
#endregion
#region 热更修复HotfixCalc Add方法 支持重载
// Debug.Log("Before Fix: 2 + 1 = " + calc.Add(2, 1));
// Debug.Log("Before Fix: Vector3(2, 3, 4) + Vector3(1, 2, 3) = " + calc.Add(new Vector3(2, 3, 4), new Vector3(1, 2, 3)));
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.HotfixCalc, 'Add', function(self, a, b)
// return a + b
// end)
//");
// Debug.Log("After Fix: 2 + 1 = " + calc.Add(2, 1));
// Debug.Log("After Fix: Vector3(2, 3, 4) + Vector3(1, 2, 3) = " + calc.Add(new Vector3(2, 3, 4), new Vector3(1, 2, 3)));
#endregion
#region 热更修复HotfixCalc TestOut方法 函数返回值 ref out参数
double num;
string str = "hehe";
// int ret = calc.TestOut(100, out num, ref str);
// Debug.Log("ret = " + ret + ", num = " + num + ", str = " + str);
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.HotfixCalc, 'TestOut', function(self, a, c, go)
// print('TestOut', self, a, c, go)
// if go then error('test error') end
// return a + 10, a + 20, 'right version'
// end)
//");
// str = "hehe";
// ret = calc.TestOut(100, out num, ref str);
// Debug.Log("ret = " + ret + ", num = " + num + ", str = " + str);
#endregion
#region 热更修复HotfixCalc table提供一组函数 多个函数一起修复
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.HotfixCalc, {
// Test1 = function(self)
// print('Test1', self)
// return 1
// end;
// Test2 = function(self, a, b)
// print('Test2 a:', a )
// print('Test2 b:', b)
// return a + 10, 1024, 'this is third args'
// end;
// Test3 = function(a)
// print(a)
// return 10
// end;
// Test4 = function(a)
// print(a)
// end;
// Test5 = function(self, a, ...)
// print('Test4', self, a, ...)
// end
// })
//");
// int r1 = calc.Test1<int>();
// double r2 = calc.Test1<double>();
// Debug.Log("r1:" + r1 + ",r2:" + r2);
// string ss = "heihei";
// r2 = 2;
// int r3 = calc.Test2(r1,out r2, ref ss);
// Debug.Log("r1:" + r1 + ",r2:" + r2 + ",r3:" + r3 + ",ss:" + ss);
// r3 = HotfixCalc.Test3("test3");
// r3 = HotfixCalc.Test3(2);
// r3 = HotfixCalc.Test3(this);
// Debug.Log("r3:" + r3);
// HotfixCalc.Test4(this);
// HotfixCalc.Test4(2);
// calc.Test5(10, "a", "b", "c");//不定参数
// calc.Test5(10, 1, 3, 5);
#endregion
#region 热更修复StatefullTest 【类全部重构】 构造函数、属性、索引器、事件、费静态方法、静态方法、泛型方法、析构函数
/*
Debug.Log("----------------------before------------------------");
TestStateful();
System.GC.Collect();//手动GC 强制垃圾回收
System.GC.WaitForPendingFinalizers();//等待所有终结器完成后再继续
luaenv.DoString(@"
local util = require 'xlua.util'
xlua.hotfix(CS.XLuaTest.StatefullTest, {
--构造函数
['.ctor'] = function(csobj)
util.state(csobj, {evt = {}, start = 0, prop = 0})
end;
--属性
set_AProp = function(self, v)
print('set_AProp', v)
self.prop = v
end;
get_AProp = function(self)
return self.prop
end;
--索引器
get_Item = function(self, k)
print('get_Item', k)
return 1024
end;
set_Item = function(self, k, v)
print('set_Item', k, v)
end;
--event 事件
add_AEvent = function(self, cb)
print('add_AEvent', cb)
table.insert(self.evt, cb)
end;
remove_AEvent = function(self, cb)
print('remove_AEvent', cb)
for i, v in ipairs(self.evt) do
if v == cb then
table.remove(self.evt, i)
break
end
end
end;
--非静态方法
Start = function(self)
print('Start')
for _, cb in ipairs(self.evt) do
cb(self.start, 2)
end
self.start = self.start + 1
end;
--静态方法
StaticFunc = function(a, b, c)
print(a, b, c)
end;
--泛型方法
GenericTest = function(self, a)
print(self, a)
end;
--析构函数
Finalize = function(self)
print('Finalize', self)
end
})
");
Debug.Log("----------------------after------------------------");
TestStateful();
luaenv.FullGc();//lua GC、lua垃圾回收
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
*/
#endregion
#region 热更修复 泛型类
var genericObj = new GenericClass<double>(1.1);
// genericObj.Func1();
// Debug.Log(genericObj.Func2());
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.GenericClass(CS.System.Double), {
// ['.ctor'] = function(obj, a)
// print('GenericClass<double>', obj, a)
// end;
// Func1 = function(obj)
// print('GenericClass<double>.Func1', obj)
// end;
// Func2 = function(obj)
// print('GenericClass<double>.Func2', obj)
// return 1314
// end
// })
//");
// genericObj = new GenericClass<double>(1.1);
// genericObj.Func1();
// Debug.Log(genericObj.Func2());
#endregion
#region 热更修复 内置类型 结构体
// InnerTypeTest itt = new InnerTypeTest();
// itt.Foo();
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.InnerTypeTest, 'Bar', function(obj)
// print('lua Bar', obj)
// return {x = 10, y = 20}
// end)
//");
// itt.Foo();
#endregion
#region 热更修复 结构体、泛型结构体
// StructTest st = new StructTest(gameObject);
// Debug.Log("go=" + st.GetGo(123, "john"));
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.StructTest, 'GetGo', function(self, a, b)
// print('GetGo', self, a, b)
// return nil
// end)
//");
// Debug.Log("go=" + st.GetGo(123, "john"));
// GenericStruct<int> gs = new GenericStruct<int>(1);
// Debug.Log("gs.GetA()=" + gs.GetA(123));
// luaenv.DoString(@"
// xlua.hotfix(CS.XLuaTest.GenericStruct(CS.System.Int32), 'GetA', function(self, a)
// print('GetA',self, a)
// return 789
// end)
//");
// Debug.Log("gs.GetA()=" + gs.GetA(123));
// try
// {
// calc.TestOut(100, out num, ref str, gameObject);
// }
// catch (LuaException e)
// {
// Debug.Log("throw in lua an catch in c# ok, e.Message:" + e.Message);
// }
#endregion
#region 热更修复 基类
BaseTestBase<InnerTypeTest> bt = new BaseTest();
bt.Foo(1);
Debug.Log(bt);
luaenv.DoString(@"
xlua.hotfix(CS.XLuaTest.BaseTest, 'Foo', function(self, p)
print('BaseTest', p)
end)
xlua.hotfix(CS.XLuaTest.BaseTest, 'ToString', function(self)
return '>>>' .. base(self):ToString()
end)
");
bt.Foo(2);
Debug.Log(bt);
#endregion
}
void TestStateful()
{
StatefullTest sft = new StatefullTest();
sft.AProp = 10;
Debug.Log("sft.AProp:" + sft.AProp);
sft["1"] = 3;
Debug.Log("sft['1']:" + sft["1"]);
System.Action<int, double> cb = (a, b) =>
{
Debug.Log("a:" + a + ",b:" + b);
};
sft.AEvent += cb;
sft.Start();
sft.Start();
sft.AEvent -= cb;
sft.Start();
StatefullTest.StaticFunc(1, 2);
StatefullTest.StaticFunc("e", 3, 4);
sft.GenericTest(1);
sft.GenericTest("hehe");
}
}
}
3.调试
HotfixTest2挂载到场景运行即可,这个里面测试的方法比较多,把看懂的注释掉,这样看比较清晰