JSBinding + SharpKit / JavaScript 加载流程

先看下 StreamingAssets/JavaScript/ 文件夹下的目录结构:

  • debug/:跟 JS 调试有关的 JS 代码,只有当开启调试的时候才需要加载。
  • Generated/:是由菜单 JSB | Generate JS and CS Bindings 产生的。用于实现将 C# 函数绑定到 JS 上。比如说要在 JS 中使用 GameObject 就要使用这里面的文件。这一点和 LUA 不一样,LUA 产生绑定时只有产生 C# 代码,我们是2边都有。
  • JSImp/ :用于手写一些 JS 代码。在一些情况下,由 C# 编译成的 JS 并不能直接使用,这时候得手写一下 JS 代码。比如说,使用 MonoBehaviour.StartCoroutine 编译成的 JS 代码并不能直接使用,因为协程函数已经变成 JS 了,不可能使用C#去执行JS的协程。所以我添加了 JSImp/UnityEngine_MonoBehaviour.javascript,里面对 StartCoroutine 函数进行了重写,使他可以支持 JS 的协程。
  • Manual/:也是用于手写 JS 代码,跟 JSImp/ 有一些区别。Manual里最有的代表性的是 Vector2 和 Vector3,这2个对象是手写实现的,在 JS 中跑只会使用 JS 版本的 Vector2 和 Vector3。
  • SharpKit/:从 SharpKit 拿过来的一些 JS 库文件。可以实现类继承等
  • SharpKitGenerated/:由 SharpKit 工程编译而来的 JS 代码都会放在这个文件夹里。
  • includes.javascript:JS 代码总入口
  • GeneratedFiles.javascript:列出了 Generated/ 文件夹下所有文件的列表
  • SharpKitGeneratedFiles.javascript:列出了 SharpKitGenerated/ 文件夹下所有文件的列表

 

目前 JavaScript 加载只有一个入口,StreamingAsset/JavaScript/includes.javascript。

查看 _JSEngine.prefab 上的配置:

 

includes.javascript 里面通过 CS.require 包含了所有的 JavaScript 文件:

(此内容可能不是最新的)

 1 /*

 2 * Author: Qiucw

 3 * DO NOT change order

 4 */

 5 

 6 

 7 // -1)

 8 //--------------------------------------------------

 9 function jsb_ReplaceOrPushJsType(jst) {

10     //if (!JsTypes) { JsTypes = []; }

11     var found = false;

12     for (var i = 0; i < JsTypes.length; i++) {

13         if (JsTypes[i].fullname == jst.fullname) {

14             JsTypes[i] = jst;

15             found = true;

16             break;

17         }

18     }

19     if (!found) {

20         JsTypes.push(jst);

21     }

22 }

23 

24 

25 // 0) SharpKit library

26 //--------------------------------------------------

27 CS.require("SharpKit/jsclr");

28 CS.require("SharpKit/clrlibrary");

29 

30 // 1) Files generated by JSBinding

31 // may overwrite some classes in step 0)

32 //--------------------------------------------------

33 CS.require("GeneratedFiles");

34 

35 

36 // 2) Manually written js

37 // will overwrite some classes in step 1)

38 //--------------------------------------------------

39 CS.require("Manual/UnityEngine_Vector3");

40 CS.require("Manual/UnityEngine_Vector2");

41 CS.require("Manual/UnityEngine_MonoBehaviour");

42 CS.require("Manual/UnityEngine_WaitForSeconds");

43 CS.require("Manual/MissingClasses");

44 //

45 // may be more..

46 //

47 

48 // 3) code generated by SharpKit

49 //--------------------------------------------------

50 CS.require("SharpKitGeneratedFiles");

51 

52 

53 // 4) JavaScript implemented

54 // will overwrite some classes in step 1)

55 //--------------------------------------------------

56 CS.require("JSImp/Reflection");

57 CS.require("JSImp/Coroutine");

58 CS.require("JSImp/Iterator");

59 

60 //

61 // may be more..

62 //

63 

64 // 5) SharpKit handler (Compile)

65 //--------------------------------------------------

66 CS.require("SharpKit/myclrhandler");

67 

68 // 6) Error handler

69 //--------------------------------------------------

70 CS.require("ErrorHandler");

 

JS里的类一开始都是用 JsType 对象来表示,可以打开 StreamingAssets/JavaScript/SharpKitGenerated/ 文件夹中随便一个文件查看一下。这里贴出来 V3Test 这个 MonoBehaviour 的JS代码:

 1 if (typeof(JsTypes) == "undefined")

 2     var JsTypes = [];

 3 var V3Test = {

 4     fullname: "V3Test",

 5     baseTypeName: "UnityEngine.MonoBehaviour",

 6     assemblyName: "SharpKitProj",

 7     Kind: "Class",

 8     definition: {

 9         ctor: function (){

10             this.elapsed = 0;

11             UnityEngine.MonoBehaviour.ctor.call(this);

12         },

13         Start: function (){

14         },

15         Update: function (){

16             this.elapsed += UnityEngine.Time.get_deltaTime();

17             if (this.elapsed > 1){

18                 var sb = new System.Text.StringBuilder.ctor();

19                 this.elapsed = 0;

20                 var v = new UnityEngine.Vector3.ctor$$Single$$Single$$Single(2, 3, 6);

21                 var w = new UnityEngine.Vector3.ctor$$Single$$Single$$Single(7, 23, 1);

22                 var n = v.get_normalized();

23                 var arr = [n.x, n.y, n.z];

24                 UnityEngine.Debug.Log$$Object(sb.AppendFormat$$String$$Object$Array("v.normalized = ({0}, {1}, {2})", arr).toString());

25                 sb.Remove(0, sb.get_Length());

26                 var cross = UnityEngine.Vector3.Cross(v, w);

27                 arr = [cross.x, cross.y, cross.z];

28                 UnityEngine.Debug.Log$$Object(sb.AppendFormat$$String$$Object$Array("Cross(v, w) = ({0}, {1}, {2})", arr).toString());

29                 UnityEngine.Debug.Log$$Object("v.magnitude = " + v.get_magnitude());

30                 UnityEngine.Debug.Log$$Object("w.magnitude = " + w.get_magnitude());

31                 UnityEngine.Debug.Log$$Object("Dot(v, w) = " + UnityEngine.Vector3.Dot(v, w));

32                 UnityEngine.Debug.Log$$Object("Angle(v, w) = " + UnityEngine.Vector3.Angle(v, w));

33                 var proj = UnityEngine.Vector3.Project(v, w);

34                 UnityEngine.Debug.Log$$Object("Project(v,w) = " + proj.toString());

35                 v.Normalize();

36                 w.Normalize();

37                 UnityEngine.Debug.Log$$Object("normalized v = " + v.toString());

38                 UnityEngine.Debug.Log$$Object("normalized w = " + w.toString());

39             }

40         }

41     }

42 };

43 JsTypes.push(V3Test);

 

这个文件是由 SharpKit 工程生成的,并不是手写的。

一个 JsType 用于定义一个类。里面的字段通常有:

  • fullname:表示此类的全名,也包含名字空间。V3Test 没有名字空间,所以就没有
  • baseTypeName:父类的名字。在后续的步骤中,会用于实现继承。
  • Kind:通常是 "Class",表示这是一个类。也可以是 "Struct" 或 "Enum"
  • definition:表示实例函数以及实例的 Property,以及构造函数。ctor表示构造函数。V3Test 只有 Start 和 Update 2个函数,是 MonoBehaviour 典型的2个函数。
  • staticDefinition:表示静态函数。
  • fields:实例字段。
  • staticFields:静态字段。
  • interfaceNames:接口的名字,是一个数组

可以看到,每一个类的文件,都是定义一个 JsType,文件最后把他 push 进 JsTypes 数组。

放到 JsTypes 数组干嘛呢?

includes.javascript 里有 require SharpKit/myclrhandler.javascript。可以打开这个文件看一下。这个文件里最重要的一句代码是:

1 Compile();

Compile 函数的定义是在 SharpKit/jsclr.javascript 中。有兴趣的可以看一下源代码。

Compile 主要做了2件事:

  1. 设置全局对象,使你可以访问这些类。比如说 你可以使用 UnityEngine.GameObject 来访问这个类。
  2. 处理继承关系。比如说,V3Test并没有定义 gameObject 这个属性,但是在 V3Test 中是可以 this.gameObject 访问的。

 

。。。待续

 

返回:Unity代码热更新方案 JSBinding + SharpKit 首页

你可能感兴趣的:(JavaScript)