Skip to content

Commit

Permalink
Merge branch 'Tencent:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnoChenFx authored Jun 22, 2024
2 parents 0c36b4b + 5437e38 commit 2f506c7
Show file tree
Hide file tree
Showing 48 changed files with 329 additions and 183 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@

---

## Select Script Engine

Currently puerts supports three script engines: v8, quickjs, nodejs, choose the one that suits you.

* V8 (default): Generally excellent performance, moderate code size, only includes the implementation of the ECMAScript specification, does not include Node.js API or browser API.

* QuickJS: Performance is not as good as V8, does not support debugging, but has a small code size, suitable for scenarios where code size is critical.

* Node.js: Supports Node.js API (OpenSSL-related APIs are not supported on Unreal Engine's mobile platform), but has a larger code size.


| Script Engine | Node api | Performance | Code Size | Debugging | Notes |
| --- | --- | --- | --- | --- | --- |
| V8 || `*****` | `***` | ✔️ | |
| QuickJS || `**` | `*` || |
| Node.js | ✔️ | `*****` | `*****` | ✔️ | OpenSSL may be disabled |

## Avaliable on these Engine

* unreal engine 4.22 ~ latest
Expand All @@ -64,6 +81,7 @@

* iOS
* Android
* OpenHarmony
* Windows
* Macos

Expand Down Expand Up @@ -119,6 +137,22 @@ PuerTS是 Unity/Unreal/Dotnet 下的TypeScript编程解决方案

---

## 脚本引擎选择

目前puerts支持三种脚本引擎:v8、quickjs、nodejs,选择合适你的那个。

* v8(默认):综合比较优秀,高性能,代码体积适中,仅包含ecmascript规范的实现,不包含nodejs api、浏览器 api

* quickjs: 性能不如v8,不支持调试,但代码体积小,适用于代码段大小敏感型业务

* nodejs:支持nodejs api(unreal engine的移动平台下不支持openssl相关api),代码体积较大

| 脚本引擎 | Node api | 性能 | 代码体积 | 调试 | 补充 |
| --- | --- | --- | --- | --- | --- |
| V8 || `*****` | `***` | ✔️ | |
| QuickJS || `**` | `*` || |
| Node.js | ✔️ | `*****` | `*****` | ✔️ | OpenSSL 可能被禁用 |

## 可用引擎

* unreal engine 4.22 ~ latest
Expand All @@ -131,6 +165,7 @@ PuerTS是 Unity/Unreal/Dotnet 下的TypeScript编程解决方案

* iOS
* Android
* 鸿蒙(OpenHarmony)
* Windows
* Macos

Expand Down
4 changes: 4 additions & 0 deletions doc/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@
]
}
~~~

## vscode 1.82.x-1.85.x之间的版本不能调试

据说是vscode本身的bug: https://github.com/microsoft/vscode-js-debug/issues/1848#issuecomment-1765152784
68 changes: 35 additions & 33 deletions doc/unreal/en/install.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
### 源码安装方式
## Source Code Installation Method

* git clone https://github.com/Tencent/puerts.git
1. Clone the repository:
```sh
git clone https://github.com/Tencent/puerts.git
```

* 拷贝puerts/unreal下的Puerts目录到您项目的Plugins目录下,可以参考[unreal demo](https://github.com/chexiongsheng/puerts_unreal_demo)
2. Copy the `Puerts` directory from `puerts/unreal` to your project's `Plugins` directory. You can refer to the Unreal demo for guidance.
* 下载v8
3. Download V8:
- For UE4.25 and above, choose one: [8.4.371.19](https://github.com/puerts/backend-v8/releases/download/V8_8.4.371.19_230822/v8_bin_8.4.371.19.tgz), [9.4.146.24](https://github.com/puerts/backend-v8/releases/download/V8_9.4.146.24_240430/v8_bin_9.4.146.24.tgz), [10.6.194](https://github.com/puerts/backend-v8/releases/download/V8_10.6.194_240612/v8_bin_10.6.194.tgz)
- For UE4.24 and below: [V8 for ue 4.24 or below](https://github.com/puerts/backend-v8/releases/download/v8_for_ue424_or_below/v8_for_ue424_or_below.tgz)
- UE4.25及以上版本:[V8 backends](https://github.com/puerts/backend-v8/releases)

- UE4.24及以下版本:[V8 for ue 4.24 or below](https://github.com/puerts/backend-v8/releases/tag/v8_for_ue424_or_below)

* 解压到`YouProject/Plugins/Puerts/ThirdParty`,如果下载的是9.4版本请手动重命名v8_9.4目录为v8
4. Extract the downloaded V8 to `YourProject/Plugins/Puerts/ThirdParty`, And Change the UseV8Version setting in JsEnv.build.cs according to version you downloaded.
### 发布包安装方式
## Release Package Installation Method
[releases](https://github.com/Tencent/puerts/releases)找到你需要的版本,注意,该页面也包含Unity的发布包,Unreal引擎使用版本会以Unreal开头。
1. Go to the [releases page](https://github.com/Tencent/puerts/releases) and find the version you need. Note that this page also includes release packages for Unity; Unreal Engine versions will start with "Unreal".
下载符合你UE版本的安装包,解压到YouProject/Plugins即可,已经内含v8库。
2. Download the package that matches your UE version and extract it to `YourProject/Plugins`. The V8 library is already included.
### 注意事项
## Notes
* mac下如果遇到移入废纸篓问题,请执行
1. **Mac Users:**
If you encounter the "Move to Trash" issue, execute the following commands:
```sh
cd Plugins/Puerts/ThirdParty
find . -name "*.dylib" | xargs sudo xattr -r -d com.apple.quarantine
```
~~~bash
cd Plugins/Puerts/ThirdParty
find . -name "*.dylib" | xargs sudo xattr -r -d com.apple.quarantine
~~~
2. **Blueprint-Only Projects:**
If you see the error "Plugin 'Puerts' failed to load because module 'JsEnv' could not be found,” it’s because pure Blueprint projects do not automatically compile Plugins. Since Puerts includes C++ source code, you need to convert your Blueprint project to a C++ project by adding a C++ class. Alternatively, you can compile the UE engine with Puerts included during the compilation.
* 纯蓝图工程提示“Plugin 'Puerts' failed to load because module 'JsEnv' could not be found.”
## Virtual Machine Switching
纯蓝图工程不会自动编译Plugins,而Puerts目前的源码或者发布包内,都是C++源码。
Puerts supports multiple script backends: V8, quickjs, nodejs.
一个纯蓝图如何使用一个C++ Plugins是个UE通用问题,目前已知可行的方式是添加一个C++代码把这纯蓝图工程转为C++工程,另外一个比较有可能(但未验证的方式)是自行编译UE引擎,而且编译引擎时把puerts放进去一起编译。
- **V8**: Provides a clean ECMAScript implementation.
- **Quickjs**: Suitable for scenarios with strict package size requirements.
- **Nodejs**: Supports more npm modules than the V8 version but results in a larger package size.
### 虚拟机切换
### Download Quickjs Backend
[Quickjs Download](https://github.com/Tencent/puerts/releases)
puerts支持多种脚本后端:V8,quickjs,nodejs
### Download Nodejs Backend
[Nodejs Download](https://github.com/Tencent/puerts/releases)
* v8提供了纯净的ECMAScript实现
* 对于包大小苛刻的场景,可以选用quickjs
* nodejs相比v8版本,可以使用更多的npm模块,但包体比v8还要大些
Extract the downloaded backend to `YourProject/Plugins/Puerts/ThirdParty`.
quickjs后端[下载](https://github.com/puerts/backend-quickjs/releases)

nodejs后端[下载](https://github.com/puerts/backend-nodejs/releases)

解压到`YouProject/Plugins/Puerts/ThirdParty`

修改[JsEnv.Build.cs](https://github.com/Tencent/puerts/blob/master/unreal/Puerts/Source/JsEnv/JsEnv.Build.cs) ,UseQuickjs为true表示用quickjs后端,UseNodejs表示用nodejs后端。
Modify `JsEnv.Build.cs`:
- Set `UseQuickjs` to `true` to use the Quickjs backend.
- Set `UseNodejs` to use the Nodejs backend.
1 change: 0 additions & 1 deletion doc/unreal/en/template_binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ If you want to use this feature outside of the `JsEnv` module itself, such as an
- Find the `JsEnv.Build.cs` file and change `UseNewV8` to `true`
- In the module's `*.Build.cs`
- Add a dependency to the `JsEnv` module
- Set `bEnableUndefinedIdentifierWarnings` to `false`

## Examples

Expand Down
6 changes: 3 additions & 3 deletions doc/unreal/zhcn/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

* 下载v8

- UE4.25及以上版本:[V8 backends](https://github.com/puerts/backend-v8/releases)
- UE4.25及以上版本有多个版本选择:[8.4.371.19](https://github.com/puerts/backend-v8/releases/download/V8_8.4.371.19_230822/v8_bin_8.4.371.19.tgz), [9.4.146.24](https://github.com/puerts/backend-v8/releases/download/V8_9.4.146.24_240430/v8_bin_9.4.146.24.tgz), [10.6.194](https://github.com/puerts/backend-v8/releases/download/V8_10.6.194_240612/v8_bin_10.6.194.tgz)

- UE4.24及以下版本:[V8 for ue 4.24 or below](https://github.com/puerts/backend-v8/releases/tag/v8_for_ue424_or_below)
- UE4.24及以下版本:[V8 for ue 4.24 or below](https://github.com/puerts/backend-v8/releases/download/v8_for_ue424_or_below/v8_for_ue424_or_below.tgz)

* 解压到`YouProject/Plugins/Puerts/ThirdParty`如果下载的是9.4版本请手动重命名v8_9.4目录为v8
* 解压到`YouProject/Plugins/Puerts/ThirdParty`并在JsEnv.build.cs中修改UseV8Version设置为你所下载的版本。

### 发布包安装方式

Expand Down
35 changes: 18 additions & 17 deletions doc/unreal/zhcn/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ puerts里js的宿主环境是游戏引擎,又添加了哪些api呢?
puerts并未重定义引擎,只是定义了ts和引擎相互调用的规则。puerts的demo也倾向于演示这些规则,而不是做一个游戏。


## 虚拟机启动
## puerts::FJsEnv

### 自行构造puerts::FJsEnv
一个puerts::FJsEnv实例代表一个虚拟机实例(可以类比一个nodejs进程)

* 在合适的地方(比如GameInstance)根据需要构造一个或者多个虚拟机
- 如果启动多个虚拟机,这些虚拟机间是相互隔离的
- 如果启动多个虚拟机,这些虚拟机间是相互隔离的(可以类比多个nodejs进程间数据是隔离的)

* 通过Start函数启动一个脚本,作为脚本逻辑的入口(类似c的main函数)
- Start可以传入一些数据作为参数,供脚本获取使用
- Start可以传入一些数据作为参数,供脚本获取使用(可以类比为nodejs命令输入的入口脚本)

示例,在GameInstance的OnStart构造虚拟机,并在Shutdown删除

Expand Down Expand Up @@ -65,19 +65,6 @@ import {argv} from 'puerts';
let world = (argv.getByName("GameInstance") as UE.GameInstance).GetWorld();
~~~

### 开启“继承引擎类功能”

开启该功能,Puerts会构造一个默认的虚拟机

* 引擎构造一个继承了UE类TypeScript类(代理对象)时,这个TypeScript类以及其引用的代码,都是跑在这个默认虚拟机上

- 这个虚拟机本身相比自行构造的虚拟机没什么两样,和UE的交互规则都一样

- 由于虚拟机间相互隔离,所以如果你自己创建了虚拟机,你会发现那里的代码和继承了UE类TypeScript类相互访问不了

* 该虚拟机不会启动一个启动脚本,也不会传参数,因而argv不可用,也没必要用

* 原来的入口脚本可以通过覆盖ReceiveBeginPlay之类的回调来实现

## TypeScript和引擎的相互调用

Expand Down Expand Up @@ -132,3 +119,17 @@ UE里头,支持反射的API(标注了UCLASS,UPPROPERTY,UFUNCTION,USTRU

实际上该功能建议使用场景是:项目已经开发了挺久了,已经是一个成型的项目,要贸然添加脚本对原有架构冲击很大,于是可以用这功能,写些继承ue类的ts类作为原有系统和新脚本系统间的边界(原有系统能认识这种ts类生成的代理蓝图),而且在这个场景下也是作为边界有限的使用,仍然切记不要滥用。

## puerts::FJsEnv、蓝图mixin功能、继承引擎类功能间的关系

* 一个puerts::FJsEnv就是一个虚拟机实例,虚拟机间数据是隔离的。

* 蓝图mixin功能是puerts::FJsEnv的一个特性,或者说任意一个puerts::FJsEnv都有蓝图mixin功能。

* 继承引擎类功能是基于puerts::FJsEnv之上构建的功能

- 它会分析ts类,并生成相应的(代理)蓝图,代理蓝图的特点是只有数据,没有逻辑(空函数);

- 代理蓝图启动,空函数会被重定向到ts(准确来说是ts编译后的js),对于ue引擎来说,代理蓝图就是普通蓝图,并无特殊性;

- 由于(代理)蓝图由ue引擎实例化,其构建就关联到某个虚拟机上的js逻辑,并需要执行构造逻辑,于是该功能需要启动一个默认的puerts::FJsEnv,这个puerts::FJsEnv和你new的puerts::FJsEnv实例没有区别,也有蓝图mixin功能,而且根据第一条,和其它地方new的puerts::FJsEnv是相互隔离的。

2 changes: 0 additions & 2 deletions doc/unreal/zhcn/template_binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@

* 在该模块的“.Build.cs”文件中加入对JsEnv模块的依赖

* 该模块的“.Build.cs”文件中,将bEnableUndefinedIdentifierWarnings设置为false

## helloworld

以一个最简单的普通c++ class为例
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
const __keep_incompatibility: unique symbol;
interface $Ref<T> {
value: T
__doNoAccess: T
}
namespace System {
interface Array$1<T> extends System.Array {
Expand Down
11 changes: 10 additions & 1 deletion unity/Assets/core/upm/Runtime/Src/PathHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public class PathHelper
{
private static char SLASH = (char)47;
private static char DOT = (char)46;
#if ENABLE_IL2CPP
[UnityEngine.Scripting.Preserve]
#endif
public static bool IsRelative(string filepath)
{
if (filepath[0] == '.') {
Expand All @@ -24,6 +27,9 @@ public static bool IsRelative(string filepath)
}
return false;
}
#if ENABLE_IL2CPP
[UnityEngine.Scripting.Preserve]
#endif
public static string Dirname(string filepath)
{
if (filepath.Length == 0) return ".";
Expand Down Expand Up @@ -173,6 +179,9 @@ protected static string decode(string s)
}
}

#if ENABLE_IL2CPP
[UnityEngine.Scripting.Preserve]
#endif
public static string normalize(string p)
{
if (p == null) throw new Exception("invalid filepath");
Expand Down Expand Up @@ -375,4 +384,4 @@ let code
})()
";
}
}
}
12 changes: 8 additions & 4 deletions unity/native_src/Src/BackendEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,12 +719,16 @@ v8::MaybeLocal<v8::Module> FBackendEnv::FetchModuleTree(v8::Isolate* isolate, v8
FV8Utils::ThrowException(isolate, "source_text is not a string!");
return v8::MaybeLocal<v8::Module>();
}
v8::Local<v8::String> script_url = absolute_file_path;
if (pathForDebug.size() > 0 )
{
script_url = FV8Utils::V8String(isolate, pathForDebug.c_str());
}
#if defined(V8_94_OR_NEWER) && !defined(WITH_QUICKJS)
v8::ScriptOrigin origin(isolate, absolute_file_path, 0, 0, true, -1, v8::Local<v8::Value>(), false, false, true);
v8::ScriptOrigin origin(isolate, script_url, 0, 0, true, -1, v8::Local<v8::Value>(), false, false, true);
#else
v8::ScriptOrigin origin(absolute_file_path, v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0), v8::True(isolate),
v8::Local<v8::Integer>(), v8::Local<v8::Value>(), v8::False(isolate), v8::False(isolate), v8::True(isolate),
v8::PrimitiveArray::New(isolate, 10));
v8::ScriptOrigin origin(script_url, v8::Integer::New(isolate, 0), v8::Integer::New(isolate, 0), v8::True(isolate),
v8::Local<v8::Integer>(), v8::Local<v8::Value>(), v8::False(isolate), v8::False(isolate), v8::True(isolate));
#endif
v8::ScriptCompiler::Source source(source_text.As<v8::String>(), origin);
v8::Local<v8::Module> module;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ public class DeclarationGenerator : ModuleRules
{
public DeclarationGenerator(ReadOnlyTargetRules Target) : base(Target)
{
#if UE_5_3_OR_LATER
PCHUsage = PCHUsageMode.NoPCHs;
#endif
PublicIncludePaths.AddRange(
new string[] {
"Programs/UnrealHeaderTool/Public",
Expand Down Expand Up @@ -57,8 +54,6 @@ public DeclarationGenerator(ReadOnlyTargetRules Target) : base(Target)
{
PrivateDependencyModuleNames.Add("PuertsEditor");
}

bEnableUndefinedIdentifierWarnings = false; // 避免在VS 2017编译时出现C4668错误

//PublicDefinitions.Add(string.Format("DECL_OUTPUT_PATH={0}", Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "Content", "Scripts"))));
}
Expand Down
Loading

0 comments on commit 2f506c7

Please sign in to comment.