示例:
public class BaseTestBase : BaseTestHelper //父类
{
public virtual void Foo(int p)
{
Debug.Log("BaseTestBase<>.Foo, p = " + p);
}
}
[Hotfix]
[LuaCallCSharp]
public class BaseTest : BaseTestBase //子类重写
{
public override void Foo(int p)
{
Debug.Log("BaseTest<>.Foo, p = " + p);
}
}
luaenv.DoString(@"
xlua.hotfix(CS.BaseTest, 'Foo', function(self, p)
print('BaseTest', p)
base(self):Foo(p) //调用父类的Foo函数,传参数为P
end)
");
bt.Foo(2);
输出:
方式一:直接在类里头打Hotfix标签;
方式二:在一个static类的static字段或者属性里头配置一个列表。属性可以用于实现的比较复杂的配置,比如根据Namespace做白名单。
public static class HotfixCfg
{
[Hotfix]
public static List<Type> by_field = new List<Type>()
{
typeof(HotFixSubClass),
typeof(GenericClass<>),
};
[Hotfix]
public static List<Type> by_property
{
get
{
return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
where type.Namespace == "XXXX"
select type).ToList();
}
}
}
Hotfix标签可以设置一些标志位对生成代码及插桩定制化
遗留设置,Stateful方式在新版本已经删除,因为这种方式可以用xlua.util.hotfix_state接口达到类似的效果,该接口的使用可以看下HotfixTest2.cs里的示例代码。
由于没Stateful,默认就是Stateless,所以也没必要设置该标志位。
值类型的适配delegate会收敛到object,好处是代码量更少,不好的是值类型会产生boxing及gc,适用于对text段敏感的业务。
不对属性注入及生成适配代码,一般而言,大多数属性的实现都很简单,出错几率比较小,建议不注入。
不对非public的方法注入及生成适配代码。除了像MonoBehaviour那种会被反射调用的私有方法必须得注入,其它仅被本类调用的非public方法可以不注入,只不过修复时会工作量稍大,所有引用到这个函数的public方法都要重写。
不生成适配delegate,直接在函数体注入处理代码。
不生成静态字段,而是把所有注入点放到一个数组集中管理。
好处:对text段影响小。
坏处:使用不像默认方式那么方便,需要通过id来指明hotfix哪个函数,而这个id是代码注入工具时分配的,函数到id的映射会保存在Gen/Resources/hotfix_id_map.lua.txt,并且自动加时间戳备份到hotfix_id_map.lua.txt同级目录,发布手机版本后请妥善保存该文件。
该文件的格式大概如下(注意:该文件仅IntKey模式使用,当你没类型指定IntKey模式注入,该文件只返回个空表):
return {
["HotfixTest"] = {
[".ctor"] = {
5
},
["Start"] = {
6
},
["Update"] = {
7
},
["FixedUpdate"] = {
8
},
["Add"] = {
9,10
},
["OnGUI"] = {
11
},
},
}
想要替换HotfixTest的Update函数,你得
CS.XLua.HotfixDelegateBridge.Set(7, func)
如果是重载函数,将会一个函数名对应多个id,比如上面的Add函数。
能不能自动化一些呢?可以,xlua.util提供了auto_id_map函数,执行一次后你就可以像以前那样直接用类,方法名去指明修补的函数。
(require 'xlua.util').auto_id_map()
xlua.hotfix(CS.HotfixTest, 'Update', function(self)
self.tick = self.tick + 1
if (self.tick % 50) == 0 then
print('<<<<<<<' .. self.tick)
end
end)
前提是hotfix_id_map.lua.txt放到可以通过require 'hotfix_id_map'引用到的地方。
这是由于带着xlua example一起打包才会有错,删除之后清理重新生成即可
1.首先开发业务代码
2.在所有可能出现问题的类上打上hotfix的标签,在所有lua调用CSharp的方法上打上LuaCallCSharp,在所有CSharp调用Lua的方法上打上CSharpCallLua
3.打包发布
4.修改bug时只需要更新Lua文件,修改资源时(声音,模型,贴图,图片,UI)只需要更新ab包。用户只需要去下载lua文件跟ab包。
注意:
1.在开发过程中尽量不要用明确的数字,最好使用变量,以便热更新修改,否则则每次函数都需在lua重写