Skip to content

Commit 78a6ae3

Browse files
committed
[xlua][1.1] fullfil
1 parent d71a4bc commit 78a6ae3

File tree

230 files changed

+15051
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+15051
-0
lines changed

Assets/XLua/CHANGELOG.txt

Lines changed: 464 additions & 0 deletions
Large diffs are not rendered by default.

Assets/XLua/CHANGELOG.txt.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/XLua/Doc.meta

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/XLua/Doc/Add_Remove_Lua_Lib.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
## What & Why
2+
3+
XLua's currently built-in extension libraries:
4+
5+
* LuaJIT support for 64-bit integers;
6+
* Positioning tool for function call times and memory leaks;
7+
* LuaSocket library for supporting ZeroBraneStudio;
8+
* tdr 4 lua;
9+
10+
With the increasing extensiveness and intensiveness of project use, the current extension libraries have been unable to meet the project team needs. Since various projects require very different extension libraries, and since mobile phone platforms are sensitive to the size of the installation package, xLua is unable to meet these needs through pre-integration. That is why we are offering this tutorial.
11+
12+
In this tutorial, we will use lua-rapidjson as an example to explain step by step how to add C/C++ extensions to xLua. Once you know how to add them, you will also know how to delete them naturally. The project team can delete those pre-integrated extensions if they are not used any more.
13+
14+
## How it is done
15+
16+
There are three steps:
17+
18+
1. Modify the build file and project settings. Compile the extensions you want to integrate into the XLua Plugin directory.
19+
2. Call the C# APIs on xLua so that the extensions can be loaded as needed (when required in the Lua code).
20+
3. (Optional) If you need to use 64-bit integers in your extensions, you can use xLua's 64-bit extension library to work with C#.
21+
22+
### First, add extensions & compile.
23+
24+
Preparations
25+
26+
1. Extract the xLua’s C source code package to the same level directory as the Assets of your Unity project.
27+
28+
Download the lua-rapidjson code and place it anywhere you like. In this tutorial, we place the rapidjson header file in the $UnityProj\build\lua-rapidjson\include directory, and place the extended source code rapidjson.cpp in the $UnityProj\build\lua-rapidjson\source directory (Note: $UnityProj refers to your project directory).
29+
30+
2. Add extensions to CMakeLists.txt
31+
32+
xLua’s platform Plugins are compiled using CMake. The advantage of this is that the compilations of all platforms are written in a makefile, and most compilation processing logic is cross-platform.
33+
34+
XLua's CMakeLists.txt provides extension points (all lists) for third-party extensions:
35+
1. THIRDPART_INC: Third-party extension header search path.
36+
2. THIRDPART_SRC: Third-party extended source code.
37+
3. THIRDPART_LIB: The library on which third-party extensions rely.
38+
39+
The following is added with RapidJSON:
40+
41+
#begin lua-rapidjson
42+
set (RAPIDJSON_SRC lua-rapidjson/source/rapidjson.cpp)
43+
set_property(
44+
SOURCE ${RAPIDJSON_SRC}
45+
APPEND
46+
PROPERTY COMPILE_DEFINITIONS
47+
LUA_LIB
48+
)
49+
list(APPEND THIRDPART_INC lua-rapidjson/include)
50+
set (THIRDPART_SRC ${THIRDPART_SRC} ${RAPIDJSON_SRC})
51+
#end lua-rapidjson
52+
53+
See the attachment for the complete code.
54+
55+
3. Compile platforms
56+
57+
All compiled scripts are named with this format: make_platform_lua version.extension name.
58+
59+
For example, the name of the Windows 64-bit Lua 5.3 version is make_win64_lua53.bat, and the name of the Android LuaJIT version is make_android_luajit.sh. you can execute the corresponding script to compile the target version.
60+
61+
The compiled scripts are automatically copied to the plugin_lua53 or plugin_luajit directory. The former is for Lua 5.3 and the latter for LuaJIT.
62+
63+
The supporting Android script is used on Linux. The NDK path at the beginning of the script must be modified accordingly.
64+
65+
### Second, C# side integration:
66+
67+
Each C extension library on Lua will provide a function, luaopen_xxx, where xxx is the name of the dynamic library. For example, the function for the Lua-RapidJSON library is luaopen_rapidjson. Such functions are automatically called by the Lua virtual machine when loading the dynamic library. In the mobile platform, we cannot load the dynamic library due to iOS restrictions. They are compiled directly into the process instead.
68+
69+
For this purpose, xLua provides an API to replace this feature (LuaEnv's member methods):
70+
71+
public void AddBuildin(string name, LuaCSFunction initer)
72+
73+
Parameters:
74+
75+
Name: name of the buildin module, a parameter entered during require;
76+
initer: the initialization function; Its prototype is public delegate int lua_CSFunction(IntPtr L); This must be a static function and be modified with the property MonoPInvokeCallbackProperty; This API will check these two conditions.
77+
78+
We use calling luaopen_rapidjson to show how to use it.
79+
80+
Extend the LuaDLL.Lua type, export luaopen_rapidjson to C# via pinvoke, and then write a static function that satisfies the definition of lua_CSFunction. You can write initialization work in it, such as calling luaopen_rapidjson. Here is the complete code:
81+
82+
namespace LuaDLL
83+
{
84+
public partial class Lua
85+
{
86+
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
87+
public static extern int luaopen_rapidjson(System.IntPtr L);
88+
89+
[MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]
90+
public static int LoadRapidJson(System.IntPtr L)
91+
{
92+
return luaopen_rapidjson(L);
93+
}
94+
}
95+
}
96+
97+
Then call AddBuildin:
98+
99+
luaenv.AddBuildin("rapidjson", LuaDLL.Lua.LoadRapidJson);
100+
101+
After this, it should work properly. Try the extension in the Lua code:
102+
103+
local rapidjson = require('rapidjson')
104+
local t = rapidjson.decode('{"a":123}')
105+
print(t.a)
106+
t.a = 456
107+
local s = rapidjson.encode(t)
108+
print('json', s)
109+
110+
### Third, 64-bit transformation
111+
112+
Include the i64lib.h file in a file that requires a 64-bit transformation.
113+
The header file include these APIs:
114+
115+
//Place an int64 on stack/uint64
116+
void lua_pushint64(lua_State* L, int64_t n);
117+
void lua_pushuint64(lua_State* L, uint64_t n);
118+
//Judge whether int64 is at the pos position on stack/uint64
119+
int lua_isint64(lua_State* L, int pos);
120+
int lua_isuint64(lua_State* L, int pos);
121+
//Get an int64 from the pos position on stack/uint64
122+
int64_t lua_toint64(lua_State* L, int pos);
123+
uint64_t lua_touint64(lua_State* L, int pos);
124+
125+
The usage of these APIs varies depending on the actual situation. See the attached file (rapidjson.cpp file).
126+
127+
Compile project related modifications
128+

Assets/XLua/Doc/Add_Remove_Lua_Lib.md.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/XLua/Doc/Configure_EN.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# XLua configuration
2+
3+
All xLua configurations support three methods: tagging, static lists, and dynamic lists.
4+
5+
There are two requirements and two recommended items for configuration:
6+
7+
* List mode must use static fields/properties.
8+
* List mode must be placed in a static type.
9+
* Using tagging is not recommended.
10+
* Placing the list mode configuration in the Editor directory is recommended.
11+
12+
**Tagging**
13+
14+
xLua uses a whitelist to indicate which code is to be generated, and the whitelist is configured via attributes. For example, if you want to call a C# type from Lua or you want to generate the adaptation code, you can add a LuaCallCSharp tag for this type:
15+
16+
~~~csharp
17+
[LuaCallCSharp]
18+
publicclassA
19+
{
20+
21+
}
22+
~~~
23+
24+
This mode is convenient, but it will increase the code on the il2cpp and therefore is not recommended.
25+
26+
**Static list**
27+
28+
Sometimes we cannot directly tag a type, such as a system API, a library without source code, or an instantiated generic type. In this case, you can declare a static field in a static type. This field can be any type except for BlackList and AdditionalProperties, as long as IEnumerable<Type> is implemented (these two exceptions will be specifically described later). Then add a tag to this field:
29+
30+
~~~csharp
31+
[LuaCallCSharp]
32+
public static List<Type> mymodule_lua_call_cs_list = new List<Type>()
33+
{
34+
typeof(GameObject),
35+
typeof(Dictionary<string, int>),
36+
};
37+
~~~
38+
39+
This field needs to be placed in a **static type** and placing it in the **Editor directory** is recommended.
40+
41+
**Dynamic list**
42+
43+
Declare a static property and tag it accordingly.
44+
45+
~~~csharp
46+
[Hotfix]
47+
public static List<Type> by_property
48+
{
49+
get
50+
{
51+
return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
52+
where type.Namespace == "XXXX"
53+
select type).ToList();
54+
}
55+
}
56+
~~~
57+
58+
Getter is code. You can use it to implement a lot of results, such as configuration by namespace, configuration by assembly, and so on.
59+
60+
This property needs to be placed in a **static type** and placing it in the **Editor directory** is recommended.
61+
62+
### XLua.LuaCallCSharp
63+
64+
When adding this configuration for a C# type, xLua will generate the adapter code for this type (including constructing an instance for the type, and accessing its member properties & methods and static properties & methods). Otherwise, it will try to gain access using the reflection mode with lower performance.
65+
66+
Adding this configuration to the Extension Methods of a type will also generate the adaptation code and append it to the member methods of the extended type.
67+
68+
XLua will only generate the type loaded with this configuration. It will not automatically generate the adaptation code of its parent type. When accessing the parent type method of the child type object, if the parent type has the LuaCallCSharp configuration, the parent type's adaptation code will be executed. Otherwise it will try to gain access using the reflection mode.
69+
70+
The reflection mode access not only has poor performance, but also may cause failed access on the il2cpp due to code stripping. This problem can be avoided through the ReflectionUse tag, which is described below.
71+
72+
### XLua.ReflectionUse
73+
74+
When adding this configuration to a C# type, xLua generates a link.xml to block code stripping on the il2cpp.
75+
76+
For extension methods, you must add LuaCallCSharp or ReflectionUse to make them accessible.
77+
78+
It is recommended that all types to be accessed in Lua have the LuaCallCSharp or ReflectionUse tag, to insure their proper operation on all platforms.
79+
80+
### XLua.DoNotGen
81+
82+
This indicates that some of the functions, fields, and properties in a type do not generate code and are accessed through the reflection mode.
83+
84+
Only the fields or properties in the standard Dictionary<Type, List<string>> can be used. The key indicates the effective type. Value is a list. The name of the functions, fields, and properties with no code generated are configured.
85+
86+
The differences from ReflectionUse are: 1. ReflectionUse specifies the entire type; 2. Upon the first access to a function (field, property), ReflectionUse will wrap the entire type, while DoNotGen will only wrap the function (field, property). In other words, DoNotGen is lazier.
87+
88+
The differences from BlackList are: 1. BlackList cannot be used when it is configured. 2. BlackList can specify an overloaded function, while DoNotGen cannot.
89+
90+
### XLua.CSharpCallLua
91+
92+
This allows you to adapt a Lua function to a C# delegate (one scenario is various callbacks at the C# side: UI events, delegate parameters, such as List&lt;T&gt;:ForEach; another scenario is to use the Get function of LuaTable to indicate that a Lua function is bound to a delegate), or to adapt a Lua table to a C# interface. The delegate or interface needs this configuration.
93+
94+
### XLua.GCOptimize
95+
96+
A C# pure value type (Note: It refers to a struct that contains only the value type, and it can nest other structs that contain only the value type) or a C# enumerated value has this configuration. xLua generates gc-optimized code for this type. The result is that the value type is passed between Lua and C# with no (C#)gc alloc generated, and that no gc is generated during array access to this type. For various GC-free scenarios, refer to the 05\_NoGc example.
97+
98+
Any type except enumeration (including the complex types that contain parameterless constructors) will generate Lua tables for that type, as well as the conversion code of a one-dimensional array with modified type. This will optimize the performance of this conversion, including fewer gc allocs.
99+
100+
### XLua.AdditionalProperties
101+
102+
This is GCOptimize's extended configuration. Sometimes, some structs want to make the field private and access the field through the property. In this case, you need to use this configuration (by default, GCOptimize only packetizes/depacketizes the public field).
103+
104+
The tagging mode is relatively simple and the configuration mode is complicated. The requirements are that Dictionary&lt;Type, List&lt;string&gt;&gt; type, and the Key of the Dictionary are effective types; and value is the list of property names. See xLua's configuration of several UnityEngine value types and the SysGCOptimize type.
105+
106+
### XLua.BlackList
107+
108+
If you do not want to generate an adaption code for a member of a type, you can implement it with this configuration.
109+
110+
The tagging method is relatively simple, and the corresponding member can be added.
111+
112+
Considering that it may be necessary to add one of the overloaded functions to the blacklist, the configuration is more complicated. The type is List&lt;List&lt;string&gt;&gt;. For each member, the first-level list has only one entry and the second-level list is a string list. The first string is the full path name of the type, the second string is the member name. If the member is a method, you also need to list the full path of the type of its parameters starting from the third string.
113+
114+
For example, the following adds a property of GameObject and a method of FileInfo to the blacklist:
115+
116+
~~~csharp
117+
[BlackList]
118+
public static List<List<string>> BlackList = new List<List<string>>() {
119+
new List<string>(){"UnityEngine.GameObject", "networkView"},
120+
new List<string>(){"System.IO.FileInfo", "GetAccessControl", "System.Security.AccessControl.AccessControlSections"},
121+
};
122+
~~~
123+
124+
### The following is the generator configuration, which must be placed in the Editor directory.
125+
126+
### CSObjectWrapEditor.GenPath
127+
128+
Configures the path of the generated code, with the type being a string. By default, it is plated in &quot;Assets/XLua/Gen/&quot;.
129+
130+
### CSObjectWrapEditor.GenCodeMenu
131+
132+
This configuration is used for secondary development of the build engine. When adding this tag to a parameterless function, it will trigger calling the function when executing the &quot;XLua/Generate Code&quot; menu.
133+

Assets/XLua/Doc/Configure_EN.md.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)