From e209cb0f6229a33d3e4f06ad3f0f77a8b992a6cb Mon Sep 17 00:00:00 2001 From: yuatpocketgems Date: Tue, 15 Dec 2020 17:54:17 -0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=96=84=E8=B0=83=E8=AF=95=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=EF=BC=8C=E4=BB=A5=E5=8F=8A=E4=BF=AE=E5=A4=8Dv8?= =?UTF-8?q?=E7=BC=96=E8=AF=91=20(#114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Have Unity auto import .cjs files as TextAssets. These files are recognized by IDEs as JavaScript files (for syntax highlighting and debugging), and can be used directly with NodeJS. * Update CJS module import logic, so debugger (in VSCode) correctly points to the file on disk and stops at correct lines. * Support clearing module cache * Auto clear JS module cache on .cjs file change to streamline debugging process. * Fix build v8 after Github Actions changed their environment. * Code review commit. * Force build and publish workflow to use Xcode12.0 too. The new tool chain builds for arm architecture, which breaks linker step. Will need to add steps for arm specifically in the future so Unity works on the new Macs. * Fix casing. --- .github/workflows/build.yml | 4 +++ .github/workflows/build_v8.yml | 6 ++++ .github/workflows/publish.yml | 4 +++ unity/Assets/Puerts/Src/Editor/CJSImporter.cs | 21 +++++++++++ unity/Assets/Puerts/Src/JsEnv.cs | 18 +++++++++- unity/Assets/Puerts/Src/Loader.cs | 15 ++++++-- .../Src/Resources/puerts/cjsload.js.txt | 1 + .../Src/Resources/puerts/modular.js.txt | 35 +++++++++++++------ 8 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 unity/Assets/Puerts/Src/Editor/CJSImporter.cs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e52fa6248..96ecb432c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,6 +49,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src @@ -69,6 +71,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src diff --git a/.github/workflows/build_v8.yml b/.github/workflows/build_v8.yml index 65872cfe04..e5742f91d7 100644 --- a/.github/workflows/build_v8.yml +++ b/.github/workflows/build_v8.yml @@ -107,6 +107,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE @@ -121,6 +123,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE @@ -135,6 +139,8 @@ jobs: runs-on: macos-10.15 steps: - uses: actions/checkout@v2 + - name: Use Xcode 12.0 to use SDK 10.15 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Run build script run: | cd $GITHUB_WORKSPACE diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 822ebe66c5..9715a5e6d5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,6 +47,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src @@ -67,6 +69,8 @@ jobs: workflow: build_v8.yml name: v8_bin path: unity/native_src/ + - name: Use Xcode 12.0 for x86 + run: sudo xcode-select -switch "/Applications/Xcode_12.app" - name: Build run: | cd unity/native_src diff --git a/unity/Assets/Puerts/Src/Editor/CJSImporter.cs b/unity/Assets/Puerts/Src/Editor/CJSImporter.cs new file mode 100644 index 0000000000..ce642e96b8 --- /dev/null +++ b/unity/Assets/Puerts/Src/Editor/CJSImporter.cs @@ -0,0 +1,21 @@ +#if UNITY_2018_1_OR_NEWER +using System.IO; +using UnityEditor.Experimental.AssetImporters; +using UnityEngine; + +[ScriptedImporter(1, "cjs")] +public class CJSImporter : ScriptedImporter +{ + public override void OnImportAsset(AssetImportContext ctx) + { + TextAsset subAsset = new TextAsset(File.ReadAllText(ctx.assetPath)); + ctx.AddObjectToAsset("text", subAsset); + ctx.SetMainObject(subAsset); + +#if ENABLE_CJS_AUTO_RELOAD + Puerts.JsEnv.ClearAllModuleCaches(); +#endif + } +} + +#endif diff --git a/unity/Assets/Puerts/Src/JsEnv.cs b/unity/Assets/Puerts/Src/JsEnv.cs index 09cbbd469c..a8c6435ad3 100644 --- a/unity/Assets/Puerts/Src/JsEnv.cs +++ b/unity/Assets/Puerts/Src/JsEnv.cs @@ -172,6 +172,22 @@ public TResult Eval(string chunk, string chunkName = "chunk") #endif } + public void ClearModuleCache () + { + Eval("global.clearModuleCache()"); + } + + public static void ClearAllModuleCaches () + { + lock (jsEnvs) + { + foreach (var jsEnv in jsEnvs) + { + jsEnv.ClearModuleCache(); + } + } + } + public void AddLazyStaticWrapLoader(Type type, Func lazyStaticWrapLoader) { #if THREAD_SAFE @@ -597,4 +613,4 @@ internal void ReleasePendingJSFunctions() } } } -} \ No newline at end of file +} diff --git a/unity/Assets/Puerts/Src/Loader.cs b/unity/Assets/Puerts/Src/Loader.cs index a10daaf277..6df5c275fa 100644 --- a/unity/Assets/Puerts/Src/Loader.cs +++ b/unity/Assets/Puerts/Src/Loader.cs @@ -30,12 +30,20 @@ public DefaultLoader(string root) this.root = root; } + private string PathToUse(string filepath) + { + return filepath.EndsWith(".cjs") ? + filepath.Substring(0, filepath.Length - 4) : + filepath; + } + public bool FileExists(string filepath) { #if PUERTS_GENERAL return File.Exists(Path.Combine(root, filepath)); #else - return UnityEngine.Resources.Load(filepath) != null; + string pathToUse = this.PathToUse(filepath); + return UnityEngine.Resources.Load(pathToUse) != null; #endif } @@ -45,7 +53,8 @@ public string ReadFile(string filepath, out string debugpath) debugpath = Path.Combine(root, filepath); return File.ReadAllText(debugpath); #else - UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(filepath); + string pathToUse = this.PathToUse(filepath); + UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(pathToUse); debugpath = System.IO.Path.Combine(root, filepath); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN debugpath = debugpath.Replace("/", "\\"); @@ -54,4 +63,4 @@ public string ReadFile(string filepath, out string debugpath) #endif } } -} \ No newline at end of file +} diff --git a/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt b/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt index bcd5205fd3..3dc4421099 100644 --- a/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt +++ b/unity/Assets/Puerts/Src/Resources/puerts/cjsload.js.txt @@ -53,6 +53,7 @@ var global = global || (function () { return this; }()); return searchModuleInDirWithExt(dir, requiredModule); } else { return searchModuleInDirWithExt(dir, requiredModule + ".js") + || searchModuleInDirWithExt(dir, requiredModule + ".cjs") || searchModuleInDirWithExt(dir, requiredModule + "/index.js") || searchModuleInDirWithExt(dir, requiredModule + "/package.json"); } diff --git a/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt b/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt index 6047567773..dc8ffa8036 100644 --- a/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt +++ b/unity/Assets/Puerts/Src/Resources/puerts/modular.js.txt @@ -16,8 +16,9 @@ var global = global || (function () { return this; }()); return {fullPath: path, debugPath: debugPath, script: context} } - let tmpModuleStorage = []; - + let moduleCache = Object.create(null); // key to sid + let tmpModuleStorage = []; // sid to module + function addModule(m) { for (var i = 0; i < tmpModuleStorage.length; i++) { if (!tmpModuleStorage[i]) { @@ -32,18 +33,22 @@ var global = global || (function () { return this; }()); return tmpModuleStorage[id]; } - let moduleCache = Object.create(null); let buildinModule = Object.create(null); function executeModule(fullPath, script, debugPath, sid) { sid = (typeof sid == 'undefined') ? 0 : sid; let fullPathInJs = fullPath.replace(/\\/g, '\\\\'); let fullDirInJs = (fullPath.indexOf('/') != -1) ? fullPath.substring(0, fullPath.lastIndexOf("/")) : fullPath.substring(0, fullPath.lastIndexOf("\\")).replace(/\\/g, '\\\\'); - let executeScript = "(function() { var __filename = '" - + fullPathInJs + "', __dirname = '" - + fullDirInJs + "', module = puerts.getModuleBySID(" + sid + "), exports = module.exports; module.filename = __filename ; (function (exports, require, console, prompt) { " - + script + "\n})(exports, puerts.genRequire('" - + fullDirInJs + "'), puerts.console); return module.exports})()"; - return puerts.evalScript(executeScript, debugPath); + let exports = {}; + let module = puerts.getModuleBySID(sid); + module.exports = exports; + let wrapped = puerts.evalScript( + // Wrap the script in the same way NodeJS does it. It is important since IDEs (VSCode) will use this wrapper pattern + // to enable stepping through original source in-place. + "(function (exports, require, module, __filename, __dirname) { " + script + "\n});", + debugPath + ) + wrapped(exports, puerts.genRequire(fullDirInJs), module, fullPathInJs, fullDirInJs) + return module.exports; } function genRequire(requiringDir) { @@ -75,6 +80,9 @@ var global = global || (function () { return this; }()); return m.exports; } } + require.clearModuleCache = () => { + localModuleCache = Object.create(null); + } return require; } @@ -92,4 +100,11 @@ var global = global || (function () { return this; }()); puerts.registerBuildinModule = registerBuildinModule; global.require = genRequire(""); -}(global)); \ No newline at end of file + + function clearModuleCache () { + tmpModuleStorage = []; + moduleCache = Object.create(null); + global.require.clearModuleCache(); + } + global.clearModuleCache = clearModuleCache; +}(global));