展会信息港展会大全

【Unity】线程安全的消息传输机制,仿照Cocos实现,unitycocos
来源:互联网   发布日期:2015-09-28 13:53:35   浏览:1520次  

导读: 【Unity】线程安全的消息传输机制,仿照Cocos实现,unitycocos 近期用到了网络通信的方法,虽然unity可以用协程来实现异步操作,不过坑爹的队友不会用,他用的是传统的开线程的方...

【Unity】线程安全的消息传输机制,仿照Cocos实现,unitycocos

近期用到了网络通信的方法,虽然unity可以用协程来实现异步操作,不过坑爹的队友不会用,他用的是传统的开线程的方法,这样就会出现线程安全的问题,然后现有的消息通信机制无法满足需求了,就得改了。还好我机智的看过Cocos2dx中消息机制的实现原理,顺手改了一下,下面贴源码:(源码后有解释)

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

/**

* 消息派发类

*/

namespace Assets.TGUI.UIScript

{

public class CDispatcher

{

//单例

public static readonly CDispatcher Instance = new CDispatcher();

//消息委托函数

public delegate void noticeDelegate(object[] data);

/// <summary>

/// 消息Key

/// </summary>

public struct Key

{

public string name;

public object target;

public Key(string _name, object _target)

{

name = _name;

target = _target;

}

}

//存储消息列表

private Dictionary<Key, noticeDelegate> m_noticeDict;

private List<KeyValuePair<Key, object[]>> m_noticeRequest;

private List<KeyValuePair<Key, object[]>> m_tempRequest;

private CDispatcher()

{

m_noticeDict = new Dictionary<Key, noticeDelegate>();

m_noticeRequest = new List<KeyValuePair<Key, object[]>>();

m_tempRequest = new List<KeyValuePair<Key, object[]>>();

}

/// <summary>

/// 循环遍历 执行消息请求

/// </summary>

public IEnumerator Dispatcher()

{

Debug.Log("MSG: Start Dispatcher");

do

{

if (m_tempRequest.Count != 0)

{

lock (m_tempRequest)

{

foreach (var item in m_tempRequest)

{

m_noticeRequest.Add(new KeyValuePair<Key, object[]>(item.Key, item.Value));

}

m_tempRequest.Clear();

}

foreach (var item in m_noticeRequest)

{

if (m_noticeDict.ContainsKey(item.Key))

{

m_noticeDict[item.Key](item.Value);

}

}

m_noticeRequest.Clear();

}

yield return new WaitForFixedUpdate();

} while (true);

}

/**

* 发送消息

* @param notifyName 消息类型

* @param data 携带参数

*/

public void sendNotification(string noticeName, object[] data = null)

{

sendNotification(noticeName, null, data);

}

/// <summary>

/// 发送消息

/// </summary>

/// <param name="noticeName"></param>

/// <param name="target"></param>

/// <param name="data"></param>

public void sendNotification(string noticeName, object target, object[] data)

{

m_tempRequest.Add(new KeyValuePair<Key, object[]>(new Key(noticeName, target), data));

}

/// <summary>

/// 发送消息 附带的数据是发送者本身的对象

/// </summary>

/// <param name="noticeName"></param>

/// <param name="target"></param>

/// <param name="source"></param>

public void sendNotification(string noticeName, object target, object source)

{

sendNotification(noticeName, target, new object[] { source });

}

/// <summary>

/// 获取到源类型变量

/// (与sendNotification(string noticeName,

/// object target, object source)对应)

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="data"></param>

/// <returns></returns>

public T GetSourceObject<T>(object[] data)

{

return (T)data[0];

}

public void addObserver(string noticeName, noticeDelegate notice)

{

addObserver(noticeName, null, notice);

}

public void addObserver(string noticeName, object target, noticeDelegate notice)

{

Key key = new Key(noticeName, target);

if (!m_noticeDict.ContainsKey(key))

{

m_noticeDict.Add(key, notice);

}

}

public void RemoveObserver(string noticeName)

{

RemoveObserver(noticeName, null);

}

public void RemoveObserver(string noticeName, object target)

{

Key key = new Key(noticeName, target);

if (!m_noticeDict.ContainsKey(key))

{

m_noticeDict.Remove(key);

}

}

}

}

方法稍微有点略多,但是值得关注的方法就是下面几个

IEnumerator Dispatcher()

public void sendNotification(...)

public void addObserver(...)

public void RemoveObserver(...)

首先来说第一个,第一个是消息循环遍历的方法,需要在游戏主对象中的start方法中使用协程开启消息循环遍历,写法如下:

//开启消息循环

StartCoroutine(CDispatcher.Instance.Dispatcher());

然后和Cocos2dx一样,添加观察者

CDispatcher.Instance.addObserver("消息名字", [目标对象], 方法);

然后发送消息

CDispatcher.Instance.sendNotification("消息名字",[目标对象],[附加数据]);

下面是一个完整的使用例子:

protected void Start()

{

//开启消息循环

StartCoroutine(CDispatcher.Instance.Dispatcher());

CDispatcher.Instance.addObserver("我要睡觉", x => Debug.Log("睡觉"));

CDispatcher.Instance.sendNotification("我要睡觉");

}

最后当然输出“睡觉”咯

http://www.bkjia.com/Androidjc/941575.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/941575.htmlTechArticle【Unity】线程安全的消息传输机制,仿照Cocos实现,unitycocos 近期用到了网络通信的方法,虽然unity可以用协程来实现异步操作,不过坑爹的...

赞助本站

人工智能实验室

相关热词: android开发 应用开发

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港