您好,登錄后才能下訂單哦!
這篇文章給大家介紹基于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é)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(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)容。