本篇文章主要講述Unity3D中客戶端消息機制的實現。this
·消息通訊在遊戲各個模塊中應該很方便調用,並且須要下降模塊之間的耦合。spa
·代碼精煉.net
·易維護code
如今直接上代碼orm
1 using System; 2 public class Notification 3 { 4 public Enum Type { set; get; } 5 6 public Object[] Params { set; get; } 7 8 public Object Target { set; get; } 9 10 public Notification() 11 { 12 13 } 14 }
1 using System; 2 [AttributeUsage(AttributeTargets.Method)] 3 public class Subscribe : Attribute 4 { 5 protected Object m_Type { set; get; } 6 public Subscribe(Object type) 7 { 8 m_Type = type; 9 } 10 public Enum GetSubscription() 11 { 12 return (Enum)m_Type; 13 } 14 }
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Reflection; 5 6 public class Notifier 7 { 8 Dictionary<Enum, Action<Notification>> m_DictAction = new Dictionary<Enum, Action<Notification>>(); 9 Object m_Target = null; 10 byte m_LifeState = 1; 11 public Notifier() 12 { 13 m_Target = this; 14 Init(); 15 } 16 public Notifier(Object target) 17 { 18 if (target == null) 19 throw new Exception("Target is null,please use New Notifier() instead"); 20 m_Target = target; 21 Init(); 22 } 23 24 void Init() 25 { 26 MethodInfo[] methods = m_Target.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 27 foreach (MethodInfo m in methods) 28 { 29 //.net 2.0 30 //Subscribe[] subs = (Subscribe[])m.GetCustomAttributes(typeof(Subscribe), true); 31 //if(subs != null && subs.Length>0) 32 // Add(subs[0].GetSubscription(), Delegate.CreateDelegate(typeof(Action<Notification>), m_Target,m.Name) as Action<Notification>); 33 34 Subscribe sub = m.GetCustomAttribute<Subscribe>(); 35 if (sub != null) 36 Add(sub.GetSubscription(), m.CreateDelegate(typeof(Action<Notification>), m_Target) as Action<Notification>); 37 } 38 } 39 40 public void Awake() { m_LifeState = 1; } 41 public void Sleep() { m_LifeState = 0; } 42 void _Execute(Enum type,Notification note) 43 { 44 if (m_LifeState == 0) return; 45 if (m_DictAction.ContainsKey(type)) 46 { 47 if (m_DictAction[type] != null) 48 m_DictAction[type](note); 49 } 50 } 51 52 public void Add(Enum type,Action<Notification> receiver) 53 { 54 if (receiver == null) 55 throw new Exception("Receiver is null"); 56 if (m_DictAction.ContainsKey(type)) 57 throw new Exception(string.Format("{0} has added",type.ToString())); 58 m_DictAction[type] = receiver; 59 _Add(type, this); 60 } 61 62 public void Remove(Enum type) 63 { 64 m_DictAction.Remove(type); 65 _Remove(type, this); 66 } 67 public void RemoveAll() 68 { 69 ICollection keys = m_DictAction.Keys; 70 Enum[] arrTemp = new Enum[keys.Count]; 71 keys.CopyTo(arrTemp, 0); 72 foreach (Enum type in arrTemp) 73 Remove(type); 74 } 75 76 public void Send(Enum type , params Object[] datas) 77 { 78 Notification note = new Notification(); 79 note.Type = type; 80 note.Params = datas; 81 note.Target = m_Target; 82 _Send(type, note); 83 } 84 85 86 public void Destory() 87 { 88 RemoveAll(); 89 m_DictAction = null; 90 m_Target = null; 91 } 92 93 #region static functions 94 static readonly Dictionary<Enum, List<Notifier>> s_DictNotifiers = new Dictionary<Enum, List<Notifier>>(); 95 static void _Add(Enum type,Notifier notifier) 96 { 97 if (!s_DictNotifiers.ContainsKey(type)) 98 s_DictNotifiers[type] = new List<Notifier>(); 99 if (!s_DictNotifiers[type].Contains(notifier)) 100 s_DictNotifiers[type].Add(notifier); 101 } 102 103 static void _Remove(Enum type,Notifier notifier) 104 { 105 if (s_DictNotifiers.ContainsKey(type)) 106 { 107 if (s_DictNotifiers[type].Contains(notifier)) 108 s_DictNotifiers[type].Remove(notifier); 109 } 110 } 111 112 static void _Send(Enum type, Notification note) 113 { 114 if (s_DictNotifiers.ContainsKey(type)) 115 { 116 List<Notifier> notifiers = s_DictNotifiers[type]; 117 int count = notifiers.Count; 118 for (int i = count - 1; i > -1; --i) 119 { 120 if (notifiers[i] != null) 121 notifiers[i]._Execute(type,note); 122 } 123 } 124 } 125 #endregion 126 }
主程序:blog
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace NotificationProj 8 { 9 class Program:Notifier 10 { 11 public enum NotifierSendType1 12 { 13 E, 14 } 15 static void Main(string[] args) 16 { 17 new Program().init(); 18 } 19 20 Notifier n1; 21 22 private void init() 23 { 24 n1 = new Notifier(); 25 n1.Send(NotifierSendType1.E); 26 Console.ReadKey(); 27 28 } 29 [Subscribe(NotifierSendType1.E)] 30 void OnReceive1E(Notification note) 31 { 32 Console.WriteLine("RRR");//RRR 33 } 34 } 35 }