unity客户端框架 消息系统

本文介绍了如何在Unity中构建一个基于C#的消息系统,利用委托和事件驱动,实现不同协议号对应不同委托的功能。通过定义EventID枚举,创建MsgEventManager类管理事件监听和广播,支持不同参数数量的Action类型。

消息系统是客户端的消息驱动的一种方式

整体思路是一个协议号对应一个委托,当收到一个消息协议号是,激活这个委托或者事件

该消息系统使用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")

}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值