因「TypeScript 问题答疑及经验分享」产生了 对AssemblyScript的期待。

没必要,把typescript强制不用any,不用统合体,改动量比rust要小。
当然我也期待超高速的rust的,能全面超越unity的龟速。

只不过最终还有一个问题,我这次修改的代码,怎么整合到正规的cocoscreator editor去呢?(编辑器没开源,我只能在这个贴子里发感谢和一下技术细节吗?

我还是写出方法吧,
1,进入到CocosCreator\resources\app文件夹,里面有package.json,package-lock.json之类的文件
2,在这里输入 npm install assemblyscript,我这里版本是0.18.15
3,执行后了会多出CocosCreator/resources/app/node_modules/assemblyscript/文件夹
4,剩下的大部分文件,可以这么处理,比如 resources/app/editor/core/quick-compiler.js
里面有
isScript: function(e) {
return “javascript” === e || “coffeescript” === e || “typescript” === e;
},
把它替换成
isScript: function(e) {
return “javascript” === e || “assemblyscript” === e || “typescript” === e;
},
就是说把已经不用的coffeescript,替换成assemblyscript,这个全文件夹替换也可意

5,有个之前说的wasm.map不能正确取得的问题,这个通过修改 resources/app/editor/lib/preview-server/index.js得以实现
在文件中,sendFile前,给它设置application/wasm的content-type
i.get("/res/import/*", function(e, t) {
。。。
。。。
if (d.basename(i).endsWith(".wasm")) {
t.setHeader(“Content-Type”, “application/wasm”);
}
t.sendFile(i);
}),

6, resources/app/editor/core/init-builtin-assets.js文件,存储了扩展名和对应的cocos内使用名在这个里面你可以找到
[".coffee",“coffeescript”]
把它替换成
[".as", “assemblyscript”]
就可以了

7.resources/app/editor/share/assets/meta/assemblyscript.js
--------------------------------------------------------------------------------------------------这个是实际的编译处理
因为wasm内部调用模块的问题,wasm的文件名实际不能弄成uuid.wasm,而是 uuid的文件夹/main.wasm uuid的文件夹/main.wasm.map的形式

"use strict";
var e = require("fire-fs"),
  r = require("fire-path");
const asc = Editor.require("app://node_modules/assemblyscript/cli/asc");
module.exports = class extends require("./javascript") {
  static defaultType() {
    return "assemblyscript";
  }
  compile(t, c) {
    try {
      // see: https://github.com/AssemblyScript/examples/blob/master/sdk/index.html
      let wasmPath = r.join(
        Editor.assetdb._fspathToImportPathNoExt(t),
        "./main.wasm"
      );
      let sourceMap = wasmPath + ".map";
      let ascJson = Editor.require(
        "app://node_modules/assemblyscript/cli/asc.json"
      );
      console.log(r);
      let baseDir = r.join(
        Editor.Project.path,
        "assets/resources/AssemblyScript"
      );
      asc.ready.then(() => {
        asc.main(
          [
            r.relative(baseDir, t),
            "--binaryFile",
            r.relative(baseDir, wasmPath),
            "--optimize",
            "--baseDir",
            baseDir,
            "--sourceMap",
            "--measure",
            "--runtime",
            "stub",
            "--exportRuntime",
            "--extension",
            "as",
            "--config",
            Editor.url("app://node_modules/assemblyscript/std/assembly.json"),
          ],
          {},
          function(err) {
            if (err) throw err;
            let sourceMapText = e.readFileSync(sourceMap, {
              encoding: "utf-8",
            });
            let sourceMapObject = JSON.parse(sourceMapText);
            let outputModule = new WebAssembly.Module(e.readFileSync(wasmPath));
            let outPut = {
              sourceMapText: sourceMapText,
              sourceMapObject: sourceMapObject,
              outputModule: outputModule,
            };

            c(null, outPut);
          }
        );
      });
    } catch (e) {
      return c(e);
    }
  }
};

8,在 resources/app/editor/share/assets/meta/javascript.js和 resources/app/editor/share/assets/meta/precompile-script.js中,因为有些处理并不能完全考虑到assemblyscript的处理,所以,在

resources/app/editor/share/assets/meta/javascript.js

的this._assetdb.saveAssetToLibrary(this.uuid, t.outputText, “.js”),之前,加入

if (
            t.outputModule != null &&
            t.outputModule instanceof WebAssembly.Module
          ) {
            e(null);
            return;
          }

在 resources/app/editor/share/assets/meta/precompile-script.js的 var precompile = function(e, r, o, c) {的第一行,加入

if (
        o.outputModule != null &&
        o.outputModule instanceof WebAssembly.Module
      ) {
        return;
      }

9,注意,先阶段必须把assemblyscript文件,也就是.as文件放入到resources文件夹里,比如说
assets/resources/AssemblyScript/log.as·文件,这个as文件必须放在resources/AssemblyScript下才能被编译

log.as

export function send(msg: string): string {
  return msg + " world";
}

10,编译后文件的读取执行,一般用loader的instantiateStreaming进行载入

const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });

        AssemblyscriptLoader.instantiateStreaming(fetch(cc.url.raw("resources/AssemblyScript/log") + "/main.wasm"), {

            module: {},

            env: {

                abortStackOverflow: _ => {

                    throw new Error("overflow");

                },

                table: new WebAssembly.Table({ initial: 0, maximum: 0, element: "anyfunc" }),

                __table_base: 0,

                memory: memory,

                __memory_base: 1024,

                STACKTOP: 0,

                STACK_MAX: memory.buffer.byteLength,

                abort: (_msg, _file, line, column) => {

                    console.error("abort called at log.as:" + line + ":" + column);

                }

            }

        })

            .then(result => {

                window.myModule = result;

                //window.myModule.exports.__getString(window.myModule.instance.exports.send(window.myModule.exports.__newString("testHello")))

            })

            .catch(console.error)

你们可以试试执行/window.myModule.exports.__getString(window.myModule.instance.exports.send(window.myModule.exports.__newString(“testHello”)))的结果

关于loader,这里有解释
https://www.assemblyscript.org/loader.html#installation


用哪种都可以,我用的是·UMD`那个,因为简单

还有建议图标也换下assemblyscript assemblyscript

这个放在resources/static/icon/assets/assemblyscript.png比较好

@jare
好了,assemblyscript的内容就是这些了,反正做不成插件,就交给你们了,需要我帮助的话那就告诉我吧,期待你们下个cocos版本正式支持assemblyscript

1赞

当然我这个是resources/AssemblyScript下的.as是强制编译的,所以你们可以不弄成强制编译,比如做成选项之类的,这样多文件的as也就可以编译成一个wasm了,这个编译选项在入口的as文件上选择之类的。这个就交给引擎组的大佬们了,谢谢
image

我认为AS3从语法方面来说到现在还够js追10年的

@jare
·
coffeescript全局置换成 assemblyscript的一览文件,最底下那两个是要删除的文件

resources/app/editor-framework/styles/globals/hljs.paraiso.dark.css
resources/app/editor-framework/themes/default/globals/hljs.paraiso.dark.css
resources/app/editor/builtin/assets/core/menu.js
resources/app/editor/builtin/assets/panel/component/node.js
resources/app/editor/builtin/assets/panel/component/search.js
resources/app/editor/builtin/inspector/package.json
resources/app/editor/builtin/inspector/panel/index.js
resources/app/editor/builtin/inspector/share/markdown-preview.paraiso.dark.css
resources/app/editor/builtin/package-asset/parse/depend.js
resources/app/editor/core/init-builtin-assets.js
resources/app/editor/core/quick-compiler.js
resources/app/editor/page/ui/elements/asset.js
resources/app/editor/page/ui/styles/globals/hljs.paraiso.dark.css
resources/app/editor/share/register-builtin-assets.js
resources/app/themes/default/globals/hljs.paraiso.dark.css
resources/engine/cocos2d/core/assets/CCScripts.js
resources/app/editor/builtin/inspector/inspectors/coffeescript.js ←删除
resources/static/icon/assets/coffeescript.png ←删除

1赞

@jare
只不过替换coffeescript的方法,我自己是在2.1.2中进行的,实际可以确认到2.4.5都存在coffeescript相关处理。但3.0就没有了,3.0需要新的办法,这个就靠你们引擎组了。

不会意思,不加 “–exportRuntime”,会出问题,所以刚才修改了

看了一下 AssemblyScript ,非常有意思啊。

1赞

是啊,有人说rust的wasm更好,但我觉得适应性的话,还是assemblyscript更适应typescript的用户

@dualface
可以对引擎组有些请求么?其实typescript只需要在编码规约阶段就 意识到assemblyscript,那么以后只需要把.ts文件扩展名改成.as就可以了,内容不用变,所以既然引擎组在推这个typescirpt,那么建议引擎组尽量把assemblyscript的制约也导入到typescirpt的开发中,让人顺着编码规约写的代码就直接改成.as就可以编译wasm了。
官方的感觉有点繁琐,我这放一个日文版的
https://qiita.com/chikoski/items/d98ed0a98acfa896869f