xluaホットパッチノート
5564 ワード
これは数ヶ月前に覚えたもので、整理していません.しばらくはそうしましょう.後で具体的に使ってから整理しましょう.
1.xluaを使用する.hotfix置換方法、変数;xlua.hotfix(クラス名,{置換するメソッドを中間に書く})
xluaは、C#のコンストラクション関数、関数、プロパティ、イベントの置換をlua関数で置き換えることができます.lua実装は、属性がgetter関数とsetter関数のように、イベントがadd関数とremove関数に対応する関数です.関数 method_nameは関数名を伝え、リロードをサポートし、異なるリロードは同じlua関数に転送されます.
例:
静的関数とメンバー関数の違いは、メンバー関数にselfパラメータが追加されます.このselfはStateless方式ではC#オブジェクト自体(C#のthisに対応)であり、Stateful方式ではluaコンストラクション関数によって実現される戻り値(tableまたはnil)が伝達されます.
通常のパラメータはluaのパラメータに対して、refパラメータはluaの1つのパラメータと1つの戻り値に対応し、outパラメータはluaの1つの戻り値に対応する.
汎化関数のパッチ適用規則は通常の関数と同じです.構造関数 コンストラクション関数に対応するmethod_nameは「.ctor」です.
Stateful方式の場合、このオブジェクトの状態としてtableを返すことができます.
通常の関数とは異なり,構造関数のホットパッチは置換ではなく,既存の論理を実行してluaを呼び出す.属性 APropという名前のプロパティには、getter,method_が対応します.nameはget_に等しいAProp,setterのmethod_name=set_AProp. []オペレータ 割り当て対応set_Item、値対応get_Item.最初のパラメータはselfで、賦値の後ろにkey、valueが付いていて、取値はkeyパラメータだけで、戻り値は取り出した値です.その他のオペレータ C#のオペレータには、+番号のオペレータ関数名がop_であるなど、内部表示がセットされています.Addition(他のオペレータの内部表示は関連資料を参照してください)では、この関数を上書きするとC#の+番号オペレータが上書きされます.イベント たとえば、イベント「AEvent」の場合、+=オペレータはadd_AEvent,-=対応はremove_AEvent.この2つの関数はいずれも1番目のパラメータがselfであり、2番目のパラメータはオペレータの後に続くdelegateである.
xluaを通過する.private_アクセステーブルは、イベントに対応するプライベートdelegateの直接アクセスに直接アクセスした後、オブジェクトの「&イベント名」フィールドでイベントを直接トリガーすることができます.たとえばself['&MyEvent']()で、MyEventはイベント名です.解析関数 method_nameは「Finalize」でselfパラメータが渡されます.
通常の関数とは異なり,構造関数のホットパッチは置換ではなくlua関数を呼び出して元の論理を継続する.汎化タイプ 他のルールは一致しています.各汎化タイプはインスタンス化された後に独立したタイプであり、インスタンス化されたタイプに対してのみパッチが適用されます.例:
ジェネリッククラス、ジェネリッククラスではなくジェネリッククラスにのみパッチを適用できます.
また、一般化されたタイプのネーミング方法に注意しなければならない.例えば、GenericClassのネーミングはGenericClass`1[System.Double]であり、具体的にはMSDNを見ることができる.
GenericClassのパッチ適用例は次のとおりです. Unity連携 utilを通ります.cs_generatorは1つのfunctionでIEnumeratorをシミュレートすることができ、その中でcoroutineを使用することができる.yieldは、C#の中のyield returnに似ています.例えば次のC#コードと対応するhotfixコードは同等効果ですクラス全体 クラス全体を置き換えるにはxluaを何度も呼び出す必要はありません.hotfixは置き換えられ、一度に完成することができます.tableを1つあげるだけでmethod_を押しますname=function組織でよい
selfは自分のクラスを表し、thisと同じ理屈を表しています.
1.xluaを使用する.hotfix置換方法、変数;xlua.hotfix(クラス名,{置換するメソッドを中間に書く})
xlua.hotfix(CS.HotfixCalc, {
Test1 = function(self)
print('Test1', self)
return 1
end;
Test2 = function(self, a, b)
print('Test1', self, a, b)
return a + 10, 1024, b
end;
Test3 = function(a)
print(a)
return 10
end;
Test4 = function(a)
print(a)
end;
Test5 = function(self, a, ...)
print('Test4', self, a, ...)
end
})
つぎを打つ
xluaは、C#のコンストラクション関数、関数、プロパティ、イベントの置換をlua関数で置き換えることができます.lua実装は、属性がgetter関数とsetter関数のように、イベントがadd関数とremove関数に対応する関数です.
例:
// fix C#
[Hotfix]
public class HotfixCalc
{
public int Add(int a, int b)
{
return a - b;
}
public Vector3 Add(Vector3 a, Vector3 b)
{
return a - b;
}
}
xlua.hotfix(CS.HotfixCalc, 'Add', function(self, a, b)
return a + b
end)
静的関数とメンバー関数の違いは、メンバー関数にselfパラメータが追加されます.このselfはStateless方式ではC#オブジェクト自体(C#のthisに対応)であり、Stateful方式ではluaコンストラクション関数によって実現される戻り値(tableまたはnil)が伝達されます.
通常のパラメータはluaのパラメータに対して、refパラメータはluaの1つのパラメータと1つの戻り値に対応し、outパラメータはluaの1つの戻り値に対応する.
汎化関数のパッチ適用規則は通常の関数と同じです.
Stateful方式の場合、このオブジェクトの状態としてtableを返すことができます.
通常の関数とは異なり,構造関数のホットパッチは置換ではなく,既存の論理を実行してluaを呼び出す.
xluaを通過する.private_アクセステーブルは、イベントに対応するプライベートdelegateの直接アクセスに直接アクセスした後、オブジェクトの「&イベント名」フィールドでイベントを直接トリガーすることができます.たとえばself['&MyEvent']()で、MyEventはイベント名です.
通常の関数とは異なり,構造関数のホットパッチは置換ではなくlua関数を呼び出して元の論理を継続する.
public class GenericClass
{
}
ジェネリッククラス、ジェネリッククラスではなくジェネリッククラスにのみパッチを適用できます.
また、一般化されたタイプのネーミング方法に注意しなければならない.例えば、GenericClassのネーミングはGenericClass`1[System.Double]であり、具体的にはMSDNを見ることができる.
GenericClassのパッチ適用例は次のとおりです.
luaenv.DoString(@"
xlua.hotfix(CS['GenericClass`1[System.Double]'], {
['.ctor'] = function(obj, a)
print('GenericClass', obj, a)
end;
Func1 = function(obj)
print('GenericClass.Func1', obj)
end;
Func2 = function(obj)
print('GenericClass.Func2', obj)
return 1314
end
})
");
[XLua.Hotfix]
public class HotFixSubClass : MonoBehaviour {
IEnumerator Start()
{
while (true)
{
yield return new WaitForSeconds(3);
Debug.Log("Wait for 3 seconds");
}
}
}
luaenv.DoString(@"
local util = require 'xlua.util'
xlua.hotfix(CS.HotFixSubClass,{
Start = function(self)
return util.cs_generator(function()
while true do
coroutine.yield(CS.UnityEngine.WaitForSeconds(3))
print('Wait for 3 seconds')
end
end
end;
})
");
xlua.hotfix(CS.StatefullTest, {
['.ctor'] = function(csobj)
return {evt = {}, start = 0}
end;
set_AProp = function(self, v)
print('set_AProp', v)
self.AProp = v
end;
get_AProp = function(self)
return self.AProp
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;
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;
Finalize = function(self)
print('Finalize', self)
end
})
selfは自分のクラスを表し、thisと同じ理屈を表しています.