JSBinding + SharpKit / Supporting Coroutine

This document explains in detail how JSBinding supports Unity Coroutine in JavaScript.

First, I suggest you read this page to understand coroutine scheduling:

http://wiki.unity3d.com/index.php/CoroutineScheduler

and also Yield instructions in Mozilla SpiderMonkey engine:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield

OK, let‘s get started. Open this scene:

Assets/JSBinding/Samples/Coroutine/TestCoroutine.unity

Part 1. Usage

This is source code of TestCoroutine.cs:

 1 [JsType(JsMode.Clr,"../../../StreamingAssets/JavaScript/SharpKitGenerated/JSBinding/Samples/Coroutine/TestCoroutine.javascript")]
 2  public class TestCoroutine : MonoBehaviour {
 3
 4      // Use this for initialization
 5      void Start ()
 6      {
 7          StartCoroutine(DoTest());
 8      }
 9
10     // Update is called once per frame
11     void Update ()
12     {
13
14     }
15     void LateUpdate()
16     {
17         jsimp.Coroutine.UpdateMonoBehaviourCoroutine(this);
18     }
19     IEnumerator WaitForCangJingKong()
20     {
21         yield return new WaitForSeconds(2f);
22     }
23     IEnumerator DoTest()
24     {
25         // test null
26         Debug.Log(1);
27         yield return null;
28
29         // test WaitForSeconds
30         Debug.Log(2);
31         yield return new WaitForSeconds(1f);
32
33         // test WWW
34         WWW www = new WWW("file://" + Application.dataPath + "/JSBinding/Samples/Coroutine/CoroutineReadme.txt");
35         yield return www;
36         Debug.Log("Text from WWW: " + www.text);
37
38         // test another coroutine
39         yield return StartCoroutine(WaitForCangJingKong());
40         Debug.Log("Wait for CangJingKong finished!");
41     }
42 }

This is JavaScript code compiled by SharpKit:

 1 if (typeof(JsTypes) == "undefined")
 2     var JsTypes = [];
 3 var TestCoroutine = {
 4     fullname: "TestCoroutine",
 5     baseTypeName: "UnityEngine.MonoBehaviour",
 6     assemblyName: "SharpKitProj",
 7     Kind: "Class",
 8     definition: {
 9         ctor: function (){
10             UnityEngine.MonoBehaviour.ctor.call(this);
11         },
12         Start: function (){
13             this.StartCoroutine$$IEnumerator(this.DoTest());
14         },
15         Update: function (){
16         },
17         LateUpdate: function (){
18             jsimp.Coroutine.UpdateMonoBehaviourCoroutine(this);
19         },
20         WaitForCangJingKong: function (){
21             var $yield = [];
22             $yield.push(new UnityEngine.WaitForSeconds.ctor(2));
23             return $yield;
24         },
25         DoTest: function (){
26             var $yield = [];
27             UnityEngine.Debug.Log$$Object(1);
28             $yield.push(null);
29             UnityEngine.Debug.Log$$Object(2);
30             $yield.push(new UnityEngine.WaitForSeconds.ctor(1));
31             var www = new UnityEngine.WWW.ctor$$String("file://" + UnityEngine.Application.get_dataPath() + "/JSBinding/Samples/Coroutine/CoroutineReadme.txt");
32             $yield.push(www);
33             UnityEngine.Debug.Log$$Object("Text from WWW: " + www.get_text());
34             $yield.push(this.StartCoroutine$$IEnumerator(this.WaitForCangJingKong()));
35             UnityEngine.Debug.Log$$Object("Wait for CangJingKong finished!");
36             return $yield;
37         }
38     }
39 };
40 JsTypes.push(TestCoroutine);

See "DoTest" and "WaitForCangJingKong" method, they are coroutine methods. SharpKit translates C# yield to a $yield array, and every yield instruction is pushed into that array.

BUT, this is not JavaScript yield syntax. So, I made a menu to correct this: JSB | Correct JavaScript Yield code

After excuting this menu, the 2 methods look like:

 1 WaitForCangJingKong: function* (){
 2      yield (new UnityEngine.WaitForSeconds.ctor(2));
 3  },
 4
 5  DoTest: function* () {
 6      UnityEngine.Debug.Log$$Object(1);
 7      yield (null);
 8      UnityEngine.Debug.Log$$Object(2);
 9      yield (new UnityEngine.WaitForSeconds.ctor(1));
10      var www = new UnityEngine.WWW.ctor$$String("file://" + UnityEngine.Application.get_dataPath() + "/JSBinding/Samples/Coroutine/CoroutineReadme.txt");
11      yield (www);
12      UnityEngine.Debug.Log$$Object("Text from WWW: " + www.get_text());
13      yield (this.StartCoroutine$$IEnumerator(this.WaitForCangJingKong()));
14      UnityEngine.Debug.Log$$Object("Wait for CangJingKong finished!");
15  }

Do you notice what has been changed?

  1. Use "function*" instead of "function" to declare a coroutine function
  2. "$yield" array has been deleted
  3. "$yield.push" has been replaced with simple "yield"

Now the code matchs exactly JavaScript yield syntax, and is ready to run.

Part 2. Things inside

A C# coroutine method is compiled by C# comipler, it returns an IEnumerator when you call it.
This IEnumerator is then passed to "StartCoroutine" method. After that, it is Unity coroutine scheduler who manages them and decides when to call "MoveNext".
In the case of JavaScript, it also has compiler to compile coroutine function, but C# coroutine scheduler is not

时间: 2024-10-20 15:37:34

JSBinding + SharpKit / Supporting Coroutine的相关文章

JSBinding + SharpKit / Important Notes

Serialization of List<T> is not supported. public List<int> lst; // NOT supported, use int[] instead About menu: JSB | Add SharpKit JsType Attribute for all Structs and Classes. If you execute this menu more than once, only one JsType will be

JSBinding + SharpKit / Home

Description JSBinding is a great tool enabling you to run actual JavaScript in Unity3D. It contains Mozilla SpiderMonkey JavaScript engine version 33 library. New version is expected to work with SharpKit (sharpkit.net). SharpKit is an open source to

JSBinding+SharpKit / 菜单介绍

[JSB | Generate JS and CS Bindings] 生成绑定,即让 Js 和 Cs 互通.详情请看 JSBinding+SharpKit / 生成 JavaScript 绑定 [JSB | Add SharpKit JsType Attribute for all Structs and Classes] 在所有逻辑代码中,所有类的定义前面加上 [JsType(JsMode.Clr, "~/Assets/StreamingAssets/JavaScript/SharpKitG

JSBinding + SharpKit / 编译 Cs 成 Js

轻轻一点菜单:[JSB | Compile Cs to Js] 主要产出:StreamingAssets/JavaScript/SharpkitGeneratedFiles.javascript,你的所有逻辑代码都在这里 其他产出: Temp/AllInvocations.txt:记录所有逻辑代码对框架代码的调用 (1) Temp/AllInvocationsWithLocation.txt:同上,但同时记录每个调用的文件名和行号 (2) Temp/YieldReturnTypes.txt:记录

JSBinding + SharpKit / 初体验:下载代码及运行Demo

QQ群:189738580 git地址:https://github.com/qcwgithub/qjsbunitynew.git插件源码地址(不包含SpiderMonkey源代码):https://github.com/qcwgithub/qjsbmozillajswrap.git 首先用 Unity 打开代码目录下的 proj 工程 由于使用的插件存在依赖,请将 Assets/Plugins/x86/mozjs-28.dll 拷贝于 Unity 安装目录下.如图所示. 如果没有做这个步骤,运

JSBinding+SharpKit / 更新的原理

首先,其实不是热更新,而是更新. 热更新意思是不重启游戏,但只要你脚本里有存储数据,就不可能.所以只能叫更新. 但大家都这么说,所以... 先举个具体的例子: 如果是C#:在 Prefab 的 GameObject 上绑定 C# 脚本,这个 Prefab 会被打包成 AssetBundle,然后通过 AssetBundle.Load 加载到游戏中. 因为C#本身不可能更新,所以就无法修改. JSB的方案是,将这些 C# 的 MonoBehaviour 都替换成 JSComponent_xxx.这

JSBinding + SharpKit / 常见问题

运行时出现: 1 Return a "System.Xml.XmlIteratorNodeList" to JS failed. Did you forget to export that class? 答:将这个类加入到 JSBindingSettings.classes 数组后运行一下菜单 JSB | Generate JS and CS Bindings. 特殊情况1:如果这个类并不存在,或者是被 DLL 隐藏了,导致无法添加,那么请添加他的基类.比如上面的 System.Xml

JSBinding + SharpKit / To JavaScript-Only users

This plugin is mainly desined to work with SharpKit. You are expected to write C# and get JavaScript code with help of SharpKit. If you don't like C# and would like to write JavaScrtipt only, Yes, you can do this, in version 1.5. But it will be a lit

JSBinding + SharpKit / 原理篇:Delegate

以 NGUI 的 UIEventListener 为例: 有一个类: 1 using SharpKit.JavaScript; 2 using UnityEngine; 3 using System.Collections; 4 5 [JsType(JsMode.Clr,"../StreamingAssets/JavaScript/SharpKitGenerated/z_temp/test0610.javascript")] 6 public class test0610 : Mono