消息系统是客户端的消息驱动的一种方式
整体思路是一个协议号对应一个委托,当收到一个消息协议号是,激活这个委托或者事件
该消息系统使用C#自己的委托类型Action不支持返回类型 支持三个参数,支持参数个数也可以自己再扩展
Action
Action<T>
Action<T,X>
Action<T,X,Y>
C#代码:
public enum EventID
{
Login = 0,
OnEnterMainView,
IsPlaying
}
using System;
using System.Collections.Generic;
using UnityEngine;
public class MsgEventManager
{
private static MsgEventManager instance;
public static MsgEventManager Instance
{
get
{
if (instance == null)
{
return instance = new MsgEventManager();
}
return instance;
}
}
private Dictionary<EventID, Delegate> eventPool;
private MsgEventManager()
{
eventPool = new Dictionary<EventID, Delegate>();
}
private void OnListenerAdding(EventID id, Delegate callback)
{
if (!eventPool.ContainsKey(id))
{
eventPool.Add(id, null);
return;
}
Delegate d = eventPool[id];
Debug.Log(string.Format("尝试为事件{0}添加不同类型的委托,当前事件所对应的委托是{1},要添加的委托类型为{2}", id, d.GetType(), callback.GetType()));
if (d != null && d.GetType() != callback.GetType())
{
throw new Exception(string.Format("尝试为事件{0}添加不同类型的委托,当前事件所对应的委托是{1},要添加的委托类型为{2}", id, d.GetType(), callback.GetType()));
}else if(d != null && d.GetType() == callback.GetType())
{
foreach (var item in d.GetInvocationList())
{
if(item==callback)
{
throw new Exception(string.Format("EventID:{0}多次绑定同一个方法委托{1}",id,callback.Method));
}
}
}
}
private void OnListenerRemoveing(EventID id, Delegate callback)
{
Delegate d = null;
if (!eventPool.ContainsKey(id))
{
throw new Exception(string.Format("不包含EventID:{0}的事件", id));
}
else
{
d = eventPool[id];
if (d == null)
{
throw new Exception(string.Format("EventID:{0}}对应的事件是空的", id));
} else if (d.GetType() != callback.GetType())
{
throw new Exception(string.Format("EventID:{0}}对应的事件{1}与要移除的事件callback类型{2}不一致", id, d.GetType(), callback.GetType()));
}
}
}
private void OnRemoveListener(EventID id)
{
if(eventPool.ContainsKey(id))
{
eventPool.Remove(id);
}
}
public void AddListener(EventID id,Action callback)
{
OnListenerAdding(id, callback);
eventPool[id] = (Action)eventPool[id] + callback;
}
public void AddListener<T>(EventID id,Action<T> callback)
{
OnListenerAdding(id, callback);
eventPool[id] = (Action<T>)eventPool[id] + callback;
}
public void AddListener<T,X>(EventID id,Action<T,X> callback)
{
OnListenerAdding(id, callback);
eventPool[id] = (Action<T, X>)eventPool[id] + callback;
}
public void AddListener<T,X,Y>(EventID id,Action<T,X,Y> callback)
{
OnListenerAdding(id, callback);
eventPool[id] = (Action<T, X, Y>)eventPool[id] + callback;
}
public void RemoveListener(EventID id,Action callback)
{
OnListenerRemoveing(id, callback);
eventPool[id] = (Action)eventPool[id] - callback;
OnRemoveListener(id);
}
public void RemoveListener<T>(EventID id,Action<T> callback)
{
OnListenerRemoveing(id, callback);
eventPool[id] = (Action<T>)eventPool[id] - callback;
OnRemoveListener(id);
}
public void RemoveListener<T,X>(EventID id,Action<T,X> callback)
{
OnListenerRemoveing(id, callback);
eventPool[id] = (Action<T,X>)eventPool[id] - callback;
OnRemoveListener(id);
}
public void RemoveListener<T, X,Y>(EventID id, Action<T, X,Y> callback)
{
OnListenerRemoveing(id, callback);
eventPool[id] = (Action<T, X,Y>)eventPool[id] - callback;
OnRemoveListener(id);
}
public void Broadcast(EventID id)
{
Delegate d = null;
if(eventPool.TryGetValue(id, out d))
{
Action callback = d as Action;
if(callback!=null)
{
callback();
}
else
{
throw new Exception(string.Format("EventID:{0}事件广播错误",id));
}
}
}
public void Broadcast<T>(EventID id,T arg1)
{
Delegate d = null;
if (eventPool.TryGetValue(id, out d))
{
Action<T> callback = d as Action<T>;
if (callback != null)
{
callback(arg1);
}
else
{
throw new Exception(string.Format("EventID:{0}事件广播错误", id));
}
}
}
public void Broadcast<T,X>(EventID id,T arg1,X arg2)
{
Delegate d = null;
if (eventPool.TryGetValue(id, out d))
{
Action<T, X> callback = d as Action<T, X>;
if (callback != null)
{
callback(arg1,arg2);
}
else
{
throw new Exception(string.Format("EventID:{0}事件广播错误", id));
}
}
}
public void Broadcast<T, X,Y>(EventID id, T arg1, X arg2,Y arg3)
{
Delegate d = null;
if (eventPool.TryGetValue(id, out d))
{
Action<T, X, Y> callback = d as Action<T, X, Y>;
if (callback != null)
{
callback(arg1, arg2,arg3);
}
else
{
throw new Exception(string.Format("EventID:{0}事件广播错误", id));
}
}
}
public void Clear()
{
eventPool.Clear();
}
}
在unity中使用:
void Start()
{
MsgEventManager.Instance.AddListener(EventID.Login, Print);
MsgEventManager.Instance.AddListener(EventID.Login, Print);
MsgEventManager.Instance.Broadcast(EventID.Login);
}
void Print(){
Debug.Log("Print")
}
本文介绍了如何在Unity中构建一个基于C#的消息系统,利用委托和事件驱动,实现不同协议号对应不同委托的功能。通过定义EventID枚举,创建MsgEventManager类管理事件监听和广播,支持不同参数数量的Action类型。
2183

被折叠的 条评论
为什么被折叠?



