Skip to content

Commit

Permalink
docs: 优化文档内容 (#1108)
Browse files Browse the repository at this point in the history
* fix: 修复在 Unity 2022 下生成代码报 Span 无法作泛型参数的问题

* docs: 优化文档

* docs: 基于 markdown 语法规范, 优化部分文档内容
  • Loading branch information
SlimeNull authored Apr 19, 2024
1 parent 745fbf8 commit 611a5a3
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 326 deletions.
75 changes: 38 additions & 37 deletions Assets/XLua/Doc/XLua_API.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## C# API

### LuaEnv类

#### object[] DoString(string chunk, string chunkName = "chuck", LuaTable env = null)

描述:

执行一个代码块。
Expand All @@ -14,7 +17,7 @@

代码块里return语句的返回值;
比如:return 1, “hello”,DoString返回将包含两个object的数组, 一个是double类型的1, 一个是string类型的“hello”

例如:

LuaEnv luaenv = new LuaEnv();
Expand All @@ -38,7 +41,7 @@

代表该代码块的delegate或者LuaFunction类;

#### LuaTable Global;
#### LuaTable Global

描述:

Expand All @@ -64,45 +67,44 @@
#### void Dispose()

描述:

Dispose该LuaEnv。

> LuaEnv的使用建议:全局就一个实例,并在Update中调用GC方法,完全不需要时调用Dispose
### LuaTable类

#### T Get<T>(string key)
#### `T Get<T>(string key)`

描述:

获取在key下,类型为T的value,如果不存在或者类型不匹配,返回null;


#### T GetInPath<T>(string path)
#### `T GetInPath<T>(string path)`

描述:

和Get的区别是,这个函数会识别path里头的“.”,比如var i = tbl.GetInPath<int>(“a.b.c”)相当于在lua里头执行i = tbl.a.b.c,避免仅为了获取中间变量而多次调用Get,执行效率更高。

#### void SetInPath<T>(string path, T val)
#### `void SetInPath<T>(string path, T val)`

描述:

和GetInPaht<T>对应的setter;

#### void Get<TKey, TValue>(TKey key, out TValue value)
#### `void Get<TKey, TValue>(TKey key, out TValue value)`

描述:

上面的API的Key都只能是string,而这个API无此限制;

#### void Set<TKey, TValue>(TKey key, TValue value)
#### `void Set<TKey, TValue>(TKey key, TValue value)`

描述:

对应Get<TKey, TValue>的setter;

#### T Cast<T>()
#### `T Cast<T>()`

描述:

Expand All @@ -111,12 +113,12 @@
#### void SetMetaTable(LuaTable metaTable)

描述:

设置metaTable为table的metatable

### LuaFunction类
### LuaFunction 类

> 注意:用该类访问Lua函数会有boxing,unboxing的开销,为了性能考虑,需要频繁调用的地方不要用该类。建议通过table.Get<ABCDelegate>获取一个delegate再调用(假设ABCDelegate是C#的一个delegate)。在使用使用table.Get<ABCDelegate>之前,请先把ABCDelegate加到代码生成列表。
> 注意:用该类访问Lua函数会有boxing,unboxing的开销,为了性能考虑,需要频繁调用的地方不要用该类。建议通过 `table.Get<ABCDelegate>` 获取一个 delegate 再调用(假设 `ABCDelegate` 是 C# 的一个 delegate)。在使用使用 `table.Get<ABCDelegate>` 之前,请先把ABCDelegate加到代码生成列表。
#### object[] Call(params object[] args)

Expand Down Expand Up @@ -155,29 +157,27 @@
描述:

访问一个C#静态成员

例如:

Print(CS.UnityEngine.Vector3.one)


#### CS.namespace.enum.field

描述:

访问一个枚举值

#### typeof函数

描述:

类似C#里头的typeof关键字,返回一个Type对象,比如GameObject.AddComponent其中一个重载需要一个Type参数

例如:

newGameObj:AddComponent(typeof(CS.UnityEngine.ParticleSystem))


#### 无符号64位支持

##### uint64.tostring
Expand All @@ -201,9 +201,9 @@
##### uint64.remainder

描述:

无符号数取模。

##### uint64.parse

描述:
Expand All @@ -212,24 +212,26 @@
#### xlua.structclone

描述:

克隆一个c#结构体

#### xlua.private_accessible(class)

#### xlua.private_accessible(class)

描述:

让一个类的私有字段,属性,方法等可用
例子:

xlua.private_accessible(CS.UnityEngine.GameObject)
xlua.private_accessible(CS.UnityEngine.GameObject)

#### xlua.get_generic_method

描述:

获取一个泛型方法
例子:

~~~lua
```lua
local foo_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Foo')
local bar_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Bar')

Expand All @@ -243,16 +245,16 @@ print(ret)

-- call static method
bar(2, nil)
~~~
```

#### cast函数

描述:

指明以特定的接口访问对象,这在实现类无法访问的时候(比如internal修饰)很有用,这时可以这么来(假设下面的calc对象实现了C#的PerformentTest.ICalc接口)

例子:

cast(calc, typeof(CS.PerformentTest.ICalc))

然后就木有其它API了
Expand All @@ -272,7 +274,6 @@ bar(2, nil)

### 基本数据类型


|C#类型|Lua类型|
|-|-|
|sbyte,byte,short,ushort,int,uint,double,char,float|number|
Expand All @@ -291,24 +292,24 @@ bar(2, nil)
|class或者 struct的实例|userdata,table|
|method,delegate|function|

#### LuaTable
#### LuaTable

C#侧指明从Lua侧输入(包括C#方法的输入参数或者Lua方法的返回值)LuaTable类型,则要求Lua侧为table。或者Lua侧的table,在C#侧未指明类型的情况下转换成LuaTable。

#### LuaFunction
#### LuaFunction

C#侧指明从Lua侧输入(包括C#方法的输入参数或者Lua方法的返回值)LuaFunction类型,则要求Lua侧为function。或者Lua侧的function,在C#侧未指明类型的情况下转换成LuaFunction。

#### LuaUserData
#### LuaUserData

对应非C# Managered对象的lua userdata。
对应非 C# Managered 对象的lua userdata。

#### class或者 struct的实例:
#### class 或者 struct 的实例

从C#传一个class或者struct的实例,将映射到Lua的userdata,并通过__index访问该userdata的成员
C#侧指明从Lua侧输入指定类型对象,Lua侧为该类型实例的userdata可以直接使用;如果该指明类型有默认构造函数,Lua侧是table则会自动转换,转换规则是:调用构造函数构造实例,并用table对应字段转换到c#对应值后赋值各成员。

#### method, delegate
#### method, delegate

成员方法以及delegate都是对应lua侧的函数。
C#侧的普通参数以及引用参数,对应lua侧函数参数;C#侧的返回值对应于Lua的第一个返回值;引用参数和out参数则按序对应于Lua的第2到第N个参数。
Expand Down
12 changes: 7 additions & 5 deletions Assets/XLua/Doc/XLua教程.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

1. 获取一个全局基本数据类型
访问LuaEnv.Global就可以了,上面有个模版Get方法,可指定返回的类型。

luaenv.Global.Get<int>("a")
luaenv.Global.Get<string>("b")
luaenv.Global.Get<bool>("c")
Expand All @@ -66,15 +66,15 @@
那有没有引用方式的映射呢?有,下面这个就是:

2. 映射到一个interface

这种方式依赖于生成代码(如果没生成代码会抛InvalidCastException异常),代码生成器会生成这个interface的实例,如果get一个属性,生成代码会get对应的table字段,如果set属性也会设置对应的字段。甚至可以通过interface的方法访问lua的函数。

3. 更轻量级的by value方式:映射到Dictionary<>,List<>

不想定义class或者interface的话,可以考虑用这个,前提table下key和value的类型都是一致的。

4. 另外一种by ref方式:映射到LuaTable类

这种方式好处是不需要生成代码,但也有一些问题,比如慢,比方式2要慢一个数量级,比如没有类型检查。

3. 访问一个全局的function
Expand All @@ -93,7 +93,7 @@
delegate的使用就更简单了,直接像个函数那样用就可以了。

2. 映射到LuaFunction

这种方式的优缺点刚好和第一种相反。
使用也简单,LuaFunction上有个变参的Call函数,可以传任意类型,任意个数的参数,返回值是object的数组,对应于lua的多返回值。

Expand All @@ -103,7 +103,7 @@

2. 如果lua侧的实现的部分都以delegate和interface的方式提供,使用方可以完全和xLua解耦:由一个专门的模块负责xlua的初始化以及delegate、interface的映射,然后把这些delegate和interface设置到要用到它们的地方。

### Lua调用C#
### Lua 调用 C#

> 本章节涉及到的实例均在XLua\Tutorial\LuaCallCSharp下
Expand Down Expand Up @@ -172,6 +172,7 @@ Lua调用侧的参数处理规则:C#的普通参数算一个输入形参,ref
Lua调用侧的返回值处理规则:C#函数的返回值(如果有的话)算一个返回值,out算一个返回值,ref算一个返回值,然后从左往右对应lua的多返回值。

##### 重载方法

直接通过不同的参数类型进行重载函数的访问,例如:

testobj:TestFunc(100)
Expand All @@ -190,6 +191,7 @@ Lua调用侧的返回值处理规则:C#函数的返回值(如果有的话)
和C#调用有默认值参数的函数一样,如果所给的实参少于形参,则会用默认值补上。

##### 可变参数方法

对于C#的如下方法:

void VariableParamsFunc(int a, params string[] strs)
Expand Down
24 changes: 12 additions & 12 deletions Assets/XLua/Doc/compatible_bytecode.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
# 通用字节码

不少项目希望把项目的lua源码通过luac编译后加载,但官方lua有个缺陷:字节码是分32位和64位版本的,换句话你32位lua环境只能跑32位luac编译出来的东西
不少项目希望把项目的 lua 源码通过 luac 编译后加载,但官方 lua 有个缺陷:字节码是分 32 位和 64 位版本的,换句话你 32 位 lua 环境只能跑 32 位 luac 编译出来的东西

为此,xLua尝试对lua源码做了少许改造,可以编译一份字节码,跨平台使用。
为此,xLua 尝试对 lua 源码做了少许改造,可以编译一份字节码,跨平台使用。

## 注意事项

* 1、如果你做了本文所描述的改动,你的xLua将加载不了官方luac所编译的字节码
* 1、如果你做了本文所描述的改动,你的 xLua 将加载不了官方 luac 所编译的字节码

* 2、截至2018/9/14,已知此改法在一个上线一个多月的项目正常运行,但不代表此改法在任何情况都没问题。
* 2、截至 2018/9/14,已知此改法在一个上线一个多月的项目正常运行,但不代表此改法在任何情况都没问题。

## 操作指南

### 1、编译xlua的Plugins
### 1、编译 xlua 的 Plugins

修改各平台编译脚本,在cmake命令加上-DLUAC_COMPATIBLE_FORMAT=ON参数,以make_win64_lua53.bat为例,修改后是这样的:
修改各平台编译脚本,在 cmake 命令加上 `-DLUAC_COMPATIBLE_FORMAT=ON` 参数,以 make_win64_lua53.bat 为例,修改后是这样的:

~~~bash
```bash
mkdir build64 & pushd build64
cmake -DLUAC_COMPATIBLE_FORMAT=ON -G "Visual Studio 14 2015 Win64" ..
popd
cmake --build build64 --config Release
md plugin_lua53\Plugins\x86_64
copy /Y build64\Release\xlua.dll plugin_lua53\Plugins\x86_64\xlua.dll
pause
~~~
```

用修改后的编译脚本重新编译各平台的xlua库,并覆盖原Plugins目录下对应文件
用修改后的编译脚本重新编译各平台的 xlua 库,并覆盖原 Plugins 目录下对应文件

## 2、编译能生成兼容格式的luac(后续只能用这特定的luac和步骤1的Plugins配套使用)

[这里](../../../build/luac/)如果你想编译window版本的,执行make_win64.bat,如果你要编译mac或者linux的,用make_unix.sh
[这里](../../../build/luac/)如果你想编译 Windows 版本的,执行 make_win64.bat,如果你要编译 Mac 或者 Linux 的,用make_unix.sh

## 3、加载字节码

通过CustomLoader加载即可,CustomLoader的详细情况请看教程。这个步骤常犯的错误是用某种Encoding去加载二进制文件,这会破坏lua字节码文件格式。谨记得以二进制方式加载。
通过 CustomLoader 加载即可,CustomLoader 的详细情况请看教程。这个步骤常犯的错误是用某种Encoding去加载二进制文件,这会破坏lua字节码文件格式。谨记得以二进制方式加载。

## PS: OpCode修改

有项目想修改为专用格式的字节码,直接在lua源码(目前是lua-5.3.5)上修改后,重新执行上述1、2操作步骤即可。
有项目想修改为专用格式的字节码,直接在 lua 源码(目前是lua-5.3.5)上修改后,重新执行上述1、2操作步骤即可。
Loading

0 comments on commit 611a5a3

Please sign in to comment.