ToLua SimpleFramework NGUI/UGUI基础知识[3]

ToLua SimpleFramework NGUI/UGUI基础知识[3]

原文地址:http://doc.ulua.org/default.asp?cateID=4

视频地址:http://pan.baidu.com/s/1gd8fG4N

昨天,痛骂完PMVC多么的操蛋,到了晚上,就遇到一个项目里面的问题,突然觉得接口无关性与PMVC的消息无主性比起来吧,还是PMVC更加科学、合理一些。至少简洁明了,不用拖泥带水的。

 

既然,首次觉得PMVC有好处,那么我们继续讲,关于昨天最后提供给大家一个门面”facade,以及搭载它的顺风车的管理器们,

有一个问题,如果在普通的Unity对象上面,GameObject上面如何获得这些支持咧?其实 很简单,我们往常给一个类集成的时候都用Unity自带的MonoBehaviour,那现在用框架提供的,继承自BehaviourBase类即可,它本来也集成自MonoBehaviour,里面包装了所有管理器的获取、维护等操作。所有的子类都可以直接调用不同管理器,或者收发PMVC的消息。

 

其实这一次的改版,除了PMVC的集成引入外,还有个非常重要的变动,就是引入了另一个管理器线程管理器,引入它的目的在于真正的开发过程中,难免都需要做很多分包操作,你可以参考里面的实现,将一些费时操作交给线程去完成,完成后再通过PMVC通知主线程,完成一次echo,主线程就避免卡顿的用户体验。今天我们主要说下线程管理器跟更新系统的协同操作。

 

说线程类之前,首先说下,怎么传递消息给线程?当GameManager类中OnUpdateResource的时候,里面有个BeginDownload函数,是它启动了ThreadManager.AddEvent(ev, OnThreadCompleted);   //线程下载。

 

线程管理器的代码并不多,短短150行而已,里面演示较多的无非是下载相关的代码,当主线程通过下面函数:

        /// <summary>

        ///添加到事件队列

        /// </summary>

        public void AddEvent(ThreadEvent ev, Action<NotiData> func) {

            lock (m_lockObj) {

                this.func = func;

                events.Enqueue(ev);

            }

        }

将事件传递给线程,记得加锁,我用消息队列保存了所有的事件请求,然后在每一此OnUpdate中,解析每一个消息,根据请求的类型做解包下载操作,将来你可以增添自己的操作类型。我们这里主要就是下载文件OnDownloadFile,解析完里面的下载URL,就开始启动异步下载DownloadFileAsync。因为是异步的,所以每一次的下载更新操作都在ProgressChanged完成,比如更新下载进度等。

 

那在更新函数里面,我拿到一个更新的下载进度,如何传递给主线程,并且让它做出刷新界面操作呢?这里用到了delegate,封装了一个通知数据类实例:NotiData data = new NotiData(NotiConst.Update_PROGRESS, value); 里面是关于更新进度的操作,以及一些数据通过m_SyncEvent回调给主线程,其实当进入m_SyncEvent的时候,CPU已经身处主线程了,那就好说了嘛,

 

既然线程管理器也集成自BehaviourBase,那我直接获取父类的facade的成员变量,并且发送消息出去,关于谁接收?这里不关心。但是我们还是要找到接收的地方,怎么找?看到前面的NotiConst.Update_PROGRESS了嘛,查找它的引用地方在哪儿?发现监听此消息的是AppMediator,这是PMVCV层了,主要处理V层的逻辑的,那通过它:

case NotiConst.Update_PROGRESS:     //更新下载进度

    view.UpdateProgress(body.ToString());

break;

通知View更新界面,也就完成了最后的操作,到达最后终点了。

 

当下载的这个文件完成以后,再次调用m_SyncEvent,这次传递的消息不是更新进度,而是更新完成消息:NotiConst.Update_DOWNLOAD。再通过事先AddEvent传进来的、保存到完成事件回调函数func,回调给GameManager,它接收到知道线程完成当前操作,在回调函数OnThreadCompleted里面,将下载完成的文件名添加到下载队列中,然后更新协同开始接着请求下载下一个文件,直到下载全部完成为止。

 

当所有的操作都完成后,这个线程不会主动退出,而是一直等着主线程交代任务进来,这就是线程与下载的完整流程。

 

借楼层更新-----------------------------------------------------------------------------------------

今天周五,睡觉前再更新一篇帖子,这回咱们聊下在PMVC下的SocketNetworkManager如何交互细节。还记得前面的帖子有个地方记录了:在BootstrapCommands类注册了一个SocketCommand的地方吗?不记得自己翻去。里面添加了一条新消息Facade.RegisterCommand(NotiConst.DISPATCH_MESSAGE, typeof(SocketCommand));为了Socket消息做准备,下面呢,就是注册了一大堆的管理器。

直接打开SocketCommand.cs文件,看看有啥?哦~~这不是原来NetworkManager里面Update函数里面的事件检测函数么?是的,就是从它复制来的,也就是说,当从NetworkManager接收到消息后,它一定会把消息通过facade发送出去,而且没有指定谁来接收,然后这里会接收,并且处理消息派发给Lua的网络管理器:Network组件进行再次分发。为啥?还用问,它不关心接受者,自然也就解耦了,解除了原来的强引用。

为了确定猜想,我们打开NetworkManager.cs文件,果不其然的代码如下:

 

/// <summary>

/// 交给Command,这里不想关心发给谁。

/// </summary>

void Update() {

    if (sEvents.Count > 0) {

        while (sEvents.Count > 0) {

             KeyValuePair<int, ByteBuffer> _event = sEvents.Dequeue();

             facade.SendNotification(NotiConst.DISPATCH_MESSAGE, _event);

         } 

     }

  }

其他的代码都是原来的,没什么可讲的,尽管如此,但是里面有个变量却不得不重点看下,就是下面的

  SocketProxy SocketClient {

       get { 

            if (socket == null) {

                socket = facade.RetrieveProxy(SocketProxy.NAME) as SocketProxy;

            }        

            return socket;          

       }

  }

这个是新的框架才具备,这是虾米东东?其实就是原来框架的SocketClient.cs类,这里是我忘了在哪里看到的,把它当作的Moudule层的代理类。距离网络底层最近的地方,由他来接收网络数据,并且通过添加静态队列AddEvent()将消息传递给NetworkManager,它在通过PMVC的解耦消息发送出去,被SocketCommand类监听截获到之后,再次分发给C#还是LUANetwork组件,以便再次分发给Lua的模块。这就是这一块的思路流程。好不好,自做评判吧。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值