C#Messenger分析和使用方法


C#Messenger是UntiyCommunity里的一個工具類,其效果是可以實現一個消息系統,其實現的具體效果表現為:
兩個腳本之間發送消息可以不需要相互引用,保證解耦,內部是委托,可以實現單播和多播

Messenger下載鏈接:files.cnblogs.com/files/FlyingZiming/Messenger.zip

源碼分析

  • 一個只讀委托表

    • readonly public static Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
      
  • 添加監聽者的內部函數

    • 檢查表里是不是有這個string了,有就然后檢查這個delegate的簽名是不是和表里的一致的,沒有則添加

    •     static public void AddListener(string eventType, Delegate callback)
          {
              MessengerInternal.OnListenerAdding(eventType, callback);
              eventTable[eventType] = Delegate.Combine(eventTable[eventType], callback);
          }
      
    • 要記得RemoveListener

  • 廣播函數

    • 觸發該string對應的一個委托

    • 播送者可以設置回調函數,以Listener的返回值為參數,所以只能有一個參數

    • 根據廣播傳的參數數量不同,有幾種broadcast模板,這里取傳一個參數的broadcast作為例子

    •     static public void Broadcast(string eventType, T arg1, MessengerMode mode)
          {
              MessengerInternal.OnBroadcasting(eventType, mode);
              var invocationList = MessengerInternal.GetInvocationList<Action<T>>(eventType);
      
              foreach (var callback in invocationList)
                  callback.Invoke(arg1);
          }
      

使用方法

沒有返回值沒有傳參的消息寫法

  • 一條公有的Message,可以在一個靜態類里管理

  • 發送方

    • Messenger.Broadcast(Message.TouchCat);
      
  • 接收方

    •     void OnEnable()
      	{
              Messenger.AddListener(Message.TouchCat, CatBeTouched2);
      	}
      	
          void OnDisable()
      	{
      	    Messenger.RemoveListener(Message.TouchCat, CatBeTouched2);
      	}
      
      
          void CatBeTouched()
      	{
      	    Debug.Log("喵喵喵"+gameObject.name);
      	}
      
  • 同一條Message可以對應不同對象上的不同腳本的不同方法,必須都是沒有參數的

    • Action無參數的委托

沒有返回值有參數的消息寫法

  • 公有的Message

  • 發送方

    • Messenger<int,float,int>.Broadcast(Message.TouchCat,100,20f,3);
      
    • Messenger里的泛型要保持和方法的參數一致

  • 接收方(三個參數最多,想要四個參數嘗試擴展模板看看)待確定

    •     void OnEnable()
      	{
      	    Messenger<int,float,int>.AddListener(Message.TouchCat, CatBeTouchedWithForce);
      	}
      	
          void OnDisable()
      	{
      	    Messenger<int,float,int>.RemoveListener(Message.TouchCat, CatBeTouchedWithForce);
      	}
      
          void CatBeTouchedWithForce(int Force,float time,int n)
      	{
      	    Debug.Log("Touch Force:"+Force+",時間:"+time+"s"+n);
      	}
      
  • 一條消息只能對應一種函數類型,返回值參數要相同

    • Action有參數的委托

有返回值的消息寫法

  • 公有的Message

  • 發送方

    •     Messenger.Broadcast<int>(Message.TouchCat,CatTouchedCallBack);
      
          void CatTouchedCallBack(int a)
      	{
      	    Debug.Log("乖!" + a);
      	}
      
    • 回調函數只有一個 泛型名字為TReturn

  • 接收方

    •     void OnEnable()
      	{	
      	    Messenger.AddListener(Message.TouchCat, CatBeTouchedWithReturn);
      	}
      	
          void OnDisable()
      	{
      		Messenger.RemoveListener(Message.TouchCat, CatBeTouchedWithReturn);
      
      	}
      
          int CatBeTouchedWithReturn()
      	{
      	    Debug.Log("cat return");
      	    return 10;
      	}
      
    • 返回值作為回調函數的參數

    • Func的委托

    有參數有返回值的委托

    • 上面兩者的結合

      • Messenger<int, float, int>.Broadcast<int>(Message.TouchCat,1,20f,3, CatTouchedCallBack);
        

轉載請標明出處,作者:FlyingZiming 博客:https://www.cnblogs.com/FlyingZiming/p/12521257.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM