Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
东方怂天
xLua
提交
b9aad836
X
xLua
项目概览
东方怂天
/
xLua
通知
4
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
xLua
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b9aad836
编写于
3月 09, 2018
作者:
J
johnche(车雄生)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
支持在子类override函数通过base调用父类实现。
上级
a26aa61c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
161 addition
and
2 deletion
+161
-2
Assets/XLua/Doc/hotfix.md
Assets/XLua/Doc/hotfix.md
+15
-2
Assets/XLua/Examples/08_Hotfix/HotfixTest2.cs
Assets/XLua/Examples/08_Hotfix/HotfixTest2.cs
+29
-0
Assets/XLua/Src/Editor/Hotfix.cs
Assets/XLua/Src/Editor/Hotfix.cs
+104
-0
Assets/XLua/Src/LuaEnv.cs
Assets/XLua/Src/LuaEnv.cs
+13
-0
Tools/XLuaHotfixInject.exe
Tools/XLuaHotfixInject.exe
+0
-0
Tools/XLuaHotfixInject.pdb
Tools/XLuaHotfixInject.pdb
+0
-0
未找到文件。
Assets/XLua/Doc/hotfix.md
浏览文件 @
b9aad836
...
...
@@ -29,8 +29,6 @@ Win命令行 copy UnityPath\Editor\Data\Managed\Mono.Cecil.* Project\Assets\XLua
不支持静态构造函数。
不支持在子类override函数通过base调用父类实现。
目前只支持Assets下代码的热补丁,不支持引擎,c#系统库的热补丁。
## API
...
...
@@ -46,6 +44,21 @@ xlua.private_accessible(class)
*
描述 : 让一个类的私有字段,属性,方法等可用
*
class : 同xlua.hotfix的class参数
base(csobj)
*
描述 : 子类override函数通过base调用父类实现。
*
csobj : 对象
*
返回值 : 新对象,可以通过该对象base上的方法
例子(位于HotfixTest2.cs):
```
lua
xlua
.
hotfix
(
CS
.
BaseTest
,
'Foo'
,
function
(
self
,
p
)
print
(
'BaseTest'
,
p
)
base
(
self
):
Foo
(
p
)
end
)
```
util.hotfix_ex(class, method_name, fix)
*
描述 : xlua.hotfix的增强版本,可以在fix函数里头执行原来的函数,缺点是fix的执行会略慢。
...
...
Assets/XLua/Examples/08_Hotfix/HotfixTest2.cs
浏览文件 @
b9aad836
...
...
@@ -106,6 +106,23 @@ public class InnerTypeTest
}
}
public
class
BaseTestBase
{
public
virtual
void
Foo
(
int
p
)
{
Debug
.
Log
(
"BaseTestBase.Foo, p = "
+
p
);
}
}
[
Hotfix
]
public
class
BaseTest
:
BaseTestBase
{
public
override
void
Foo
(
int
p
)
{
Debug
.
Log
(
"BaseTest.Foo, p = "
+
p
);
}
}
[
Hotfix
]
public
struct
StructTest
{
...
...
@@ -350,6 +367,18 @@ public class HotfixTest2 : MonoBehaviour {
{
Debug
.
Log
(
"throw in lua an catch in c# ok, e.Message:"
+
e
.
Message
);
}
BaseTestBase
bt
=
new
BaseTest
();
bt
.
Foo
(
1
);
luaenv
.
DoString
(
@"
xlua.hotfix(CS.BaseTest, 'Foo', function(self, p)
print('BaseTest', p)
base(self):Foo(p)
end)
"
);
bt
.
Foo
(
2
);
}
void
TestStateful
()
...
...
Assets/XLua/Src/Editor/Hotfix.cs
浏览文件 @
b9aad836
...
...
@@ -431,6 +431,29 @@ namespace XLua
}
}
List
<
MethodDefinition
>
toAdd
=
new
List
<
MethodDefinition
>();
foreach
(
var
method
in
type
.
Methods
)
{
if
(
ignoreNotPublic
&&
!
method
.
IsPublic
)
{
continue
;
}
if
(
ignoreProperty
&&
method
.
IsSpecialName
&&
(
method
.
Name
.
StartsWith
(
"get_"
)
||
method
.
Name
.
StartsWith
(
"set_"
)))
{
continue
;
}
if
(
method
.
Name
!=
".cctor"
&&
!
method
.
IsAbstract
&&
!
method
.
IsPInvokeImpl
&&
method
.
Body
!=
null
&&
!
method
.
Name
.
Contains
(
"<"
))
{
var
proxyMethod
=
tryAddBaseProxy
(
method
.
DeclaringType
,
method
);
if
(
proxyMethod
!=
null
)
toAdd
.
Add
(
proxyMethod
);
}
}
foreach
(
var
md
in
toAdd
)
{
type
.
Methods
.
Add
(
md
);
}
return
true
;
}
...
...
@@ -591,6 +614,87 @@ namespace XLua
return
null
;
}
static
MethodDefinition
findOverride
(
TypeDefinition
type
,
MethodReference
vmethod
)
{
foreach
(
var
method
in
type
.
Methods
)
{
if
(
method
.
Name
==
vmethod
.
Name
&&
method
.
IsVirtual
&&
isSameType
(
method
.
ReturnType
,
vmethod
.
ReturnType
)
&&
method
.
Parameters
.
Count
==
vmethod
.
Parameters
.
Count
)
{
bool
isParamsMatch
=
true
;
for
(
int
i
=
0
;
i
<
method
.
Parameters
.
Count
;
i
++)
{
if
(
method
.
Parameters
[
i
].
Attributes
!=
vmethod
.
Parameters
[
i
].
Attributes
||
!
isSameType
(
method
.
Parameters
[
i
].
ParameterType
,
vmethod
.
Parameters
[
i
].
ParameterType
))
{
isParamsMatch
=
false
;
break
;
}
}
if
(
isParamsMatch
)
return
method
;
}
}
return
null
;
}
static
MethodReference
findBase
(
TypeDefinition
type
,
MethodDefinition
method
)
{
if
(
method
.
IsVirtual
&&
!
method
.
IsNewSlot
)
//表明override
{
try
{
TypeDefinition
tbase
=
type
.
BaseType
.
Resolve
();
while
(
tbase
!=
null
)
{
var
m
=
findOverride
(
tbase
,
method
);
if
(
m
!=
null
)
{
return
m
;
}
tbase
=
tbase
.
BaseType
.
Resolve
();
}
}
catch
{
}
}
return
null
;
}
const
string
BASE_RPOXY_PERFIX
=
"<>xLuaBaseProxy_"
;
static
MethodDefinition
tryAddBaseProxy
(
TypeDefinition
type
,
MethodDefinition
method
)
{
var
mbase
=
findBase
(
type
,
method
);
if
(
mbase
!=
null
)
{
var
proxyMethod
=
new
MethodDefinition
(
BASE_RPOXY_PERFIX
+
method
.
Name
,
Mono
.
Cecil
.
MethodAttributes
.
Public
,
method
.
ReturnType
);
for
(
int
i
=
0
;
i
<
method
.
Parameters
.
Count
;
i
++)
{
proxyMethod
.
Parameters
.
Add
(
new
ParameterDefinition
(
"P"
+
i
,
method
.
Parameters
[
i
].
IsOut
?
Mono
.
Cecil
.
ParameterAttributes
.
Out
:
Mono
.
Cecil
.
ParameterAttributes
.
None
,
method
.
Parameters
[
i
].
ParameterType
));
}
var
instructions
=
proxyMethod
.
Body
.
Instructions
;
var
processor
=
proxyMethod
.
Body
.
GetILProcessor
();
int
paramCount
=
method
.
Parameters
.
Count
+
1
;
for
(
int
i
=
0
;
i
<
paramCount
;
i
++)
{
if
(
i
<
ldargs
.
Length
)
{
instructions
.
Add
(
processor
.
Create
(
ldargs
[
i
]));
}
else
if
(
i
<
256
)
{
instructions
.
Add
(
processor
.
Create
(
OpCodes
.
Ldarg_S
,
(
byte
)
i
));
}
else
{
instructions
.
Add
(
processor
.
Create
(
OpCodes
.
Ldarg
,
(
short
)
i
));
}
}
instructions
.
Add
(
Instruction
.
Create
(
OpCodes
.
Call
,
mbase
));
instructions
.
Add
(
Instruction
.
Create
(
OpCodes
.
Ret
));
return
proxyMethod
;
}
return
null
;
}
static
bool
injectMethod
(
AssemblyDefinition
assembly
,
MethodDefinition
method
,
HotfixFlagInTool
hotfixType
,
FieldReference
stateTable
)
{
var
type
=
method
.
DeclaringType
;
...
...
Assets/XLua/Src/LuaEnv.cs
浏览文件 @
b9aad836
...
...
@@ -554,6 +554,19 @@ namespace XLua
impl.UnderlyingSystemType = parent[name].UnderlyingSystemType
rawset(parent, name, impl)
end
local base_mt = {
__index = function(t, k)
local csobj = t['__csobj']
local func = csobj['<>xLuaBaseProxy_'..k]
return function(_, ...)
func(csobj, ...)
end
end
}
base = function(csobj)
return setmetatable({__csobj = csobj}, base_mt)
end
"
;
public
delegate
byte
[]
CustomLoader
(
ref
string
filepath
);
...
...
Tools/XLuaHotfixInject.exe
浏览文件 @
b9aad836
无法预览此类型文件
Tools/XLuaHotfixInject.pdb
浏览文件 @
b9aad836
无法预览此类型文件
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录