溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于JSBinding+SharpKit如何分析Delegate

發(fā)布時間:2021-12-03 16:46:36 來源:億速云 閱讀:165 作者:柒染 欄目:大數(shù)據(jù)

這篇文章給大家介紹基于JSBinding+SharpKit如何分析Delegate,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

以 NGUI 的 UIEventListener 為例:

有一個類:

using SharpKit.JavaScript;
 using UnityEngine;
 using System.Collections;
 
 [JsType(JsMode.Clr,"../StreamingAssets/JavaScript/SharpKitGenerated/z_temp/test0610.javascript")]
 public class test0610 : MonoBehaviour {
     public UIButton btn;
 
     void Start () 
    {
        // 在此注冊回調(diào)
        UIEventListener.Get(btn.gameObject).onClick = this.OnClick; // (*)
    }

    void OnClick(GameObject go)
   {
        Debug.Log("onclick ");
    }
}

這個類有一個 public UIButton btn;  變量,可以在 Inspector 里賦值。我們用這個類來響應(yīng) btn 的點擊事件。重點就是第12行。

生成的JS如下:

1 if (typeof(JsTypes) == "undefined")
 2     var JsTypes = [];
 3 var test0610 = {
 4     fullname: "test0610",
 5     baseTypeName: "UnityEngine.MonoBehaviour",
 6     assemblyName: "SharpKitProj",
 7     Kind: "Class",
 8     definition: {
 9         ctor: function (){
10             this.btn = null;
11             UnityEngine.MonoBehaviour.ctor.call(this);
12         },
13         Start: function (){
14             UIEventListener.Get(this.btn.get_gameObject()).onClick = $CreateDelegate(this, this.OnClick); // (*)
15         },
16         Update: function (){
17         },
18         OnClick: function (go){
19             UnityEngine.Debug.Log$$Object("onclick ");
20         }
21     }
22 };
23 JsTypes.push(test0610);

看 JS代碼 第14行,將 onClick 賦值為 $CreateDelegate 的返回值

$CreateDelegate 的作用是返回一個函數(shù),具體可以看 jsclr.javascript 文件里這個函數(shù)的定義。這里不討論這個函數(shù)的實現(xiàn)細節(jié),只要知道他返回一個函數(shù)就可以了。這個函數(shù)傳到 C# 后就變成一個ID。

當(dāng)然,如果要讓這段JS可以正常執(zhí)行,當(dāng)然要將 UIEventListener 配置到 JSBindingSettings.classes 數(shù)組讓他導(dǎo)出,來看一下 onClick 這個字段的C#代碼:

1 public static UIEventListener.VoidDelegate UIEventListener_onClick_GetDelegate_member2_arg0(CSRepresentedObject objFunction)
 2 {
 3     if (objFunction == null || objFunction.jsObjID == 0)
 4     {
 5         return null;
 6     }
 7     UIEventListener.VoidDelegate action = (go) => 
 8     {
 9         JSMgr.vCall.CallJSFunctionValue(0, objFunction.jsObjID, go);
10     };
11     return action;
12 }
13 static void UIEventListener_onClick(JSVCall vc)
14 {
15     if (vc.bGet) {
16         UIEventListener _this = (UIEventListener)vc.csObj;
17         var result = _this.onClick;
18         JSMgr.vCall.datax.setObject((int)JSApi.SetType.Rval, result);
19     }
20     else {
21         UIEventListener _this = (UIEventListener)vc.csObj;
22         _this.onClick = JSDataExchangeMgr.GetJSArg<UIEventListener.VoidDelegate>(()=>{
23     if (JSApi.isFunctionS((int)JSApi.GetType.Arg))
24         return UIEventListener_onClick_GetDelegate_member2_arg0(JSApi.getFunctionS((int)JSApi.GetType.Arg));
25     else
26         return (UIEventListener.VoidDelegate)vc.datax.getObject((int)JSApi.GetType.Arg);
27 })
28 ;
29     }
30 }

第22行在賦值 onClick 字段。因為 onClick 是 Delegate,所以賦值也要給他一個 Delegate,這個 Delegate 是由函數(shù) UIEventListener_onClick_GetDelegate_member2_arg0 返回的(第1行)。

第24行首先調(diào)用 JSApi.getFunctionS(..) 獲取 JS 函數(shù) ID。CSRepresentedObject 只是對 JS 對象的一個封裝而已。UIEventListener_onClick_GetDelegate_member2_arg0 拿到這個函數(shù)ID后,

構(gòu)造了一個 UIEventListener.VoidDelegate 類型的 Delegate ,最終賦值給了 UIEventListener.onClick。

以上是比較簡單的情況:將 JS 函數(shù)存儲在 C#。

再來看一種情況,將 C# 函數(shù)存儲在 JS。

// C#

1 TweenEasingCallback func = TweenEasingFunctions.GetFunction(this.EaseType );
2 
3 transform.TweenPosition()
4 .SetEndValue( transform.position + ( Vector3.right * 9f ) )
5 .SetDelay( 0.5f, false )
6 .SetDuration( 1.33f )
7 .SetEasing( func )
8 .SetLoopType( TweenLoopType.Loop )
9 .Play();

// JS代碼

1 var func = DaikonForge.Tween.TweenEasingFunctions.GetFunction(this.EaseType); // get a delegate from C# (1)
2 TweenTransformExtensions.TweenPosition$$Transform(this.get_transform())
3     .SetEndValue(UnityEngine.Vector3.op_Addition(this.get_transform().get_position(), (UnityEngine.Vector3.op_Multiply$$Vector3$$Single(UnityEngine.Vector3.get_right(), 9))))
4     .SetDelay$$Single$$Boolean(0.5, false)
5     .SetDuration(1.33)
6     .SetEasing(func) // give back to C# (2)
7     .SetLoopType(1)
8     .Play();

這種情況下也是要事先將 TweenEasingFunctions 配置到 JSBindingSettings.classes,讓他導(dǎo)出,JS才可以使用。

// TweenEasingFunctions.GetFunction 的綁定代碼:

1 static bool TweenEasingFunctions_GetFunction__EasingType(JSVCall vc, int argc)
 2 {
 3     int len = argc;
 4     if (len == 1) 
 5     {
 6         DaikonForge.Tween.EasingType arg0 = (DaikonForge.Tween.EasingType)JSApi.getEnum((int)JSApi.GetType.Arg);
 7         JSMgr.vCall.datax.setObject((int)JSApi.SetType.Rval, DaikonForge.Tween.TweenEasingFunctions.GetFunction(arg0));
 8     }
 9 
10     return true;
11 }

可以看到,當(dāng) JS 從 C# 獲得一個 delegate 時,會調(diào)用 JSDataExchange.setObject 函數(shù)。

這里不貼出 setObject 的具體代碼,請查看源代碼。

在 setObject 函數(shù)中,會判斷,如果這個對象是個 delegate,那么就創(chuàng)建一個 JSRepresentedObject 對象返回給 JS,同時保存這2者的對應(yīng)關(guān)系。

JSRepresentedObject 的定義在 StreamingAssets/JavaScript/SharpKit/myclrhandler.javascript 最前面。

那么,JS拿到這個對象后,是無法使用的。因為他是C#這邊的函數(shù)。他只能把這個東西再還給C#。請看上面JS代碼標(biāo)記 (2) 那一句。當(dāng)他返回給C#時,C#可以根據(jù)之前存儲的對應(yīng)關(guān)系找到 Delegate。

關(guān)于基于JSBinding+SharpKit如何分析Delegate就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI