第二人生的源码分析(四十七)发送下载纹理图片请求

这里接着上一次获取纹理图片线程,继续分析发送纹理图片请求到服务器。代码如下:
#001 void LLTextureFetch::sendRequestListToSimulators()
#002 {
#003       const S32 IMAGES_PER_REQUEST = 50;
#004       const F32 LAZY_FLUSH_TIMEOUT = 15.f; // 10.0f // temp
#005       const F32 MIN_REQUEST_TIME = 1.0f;
#006       const F32 MIN_DELTA_PRIORITY = 1000.f;
#007
 
先同步多线程的访问。
#008       LLMutexLock lock(&mQueueMutex);
#009      
#010       // Send requests
#011       typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
#012       typedef std::map< LLHost, request_list_t > work_request_map_t;
#013       work_request_map_t requests;
 
下面循环地分析已经放到请求队列里的下载请求。
#014       for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
#015       {
#016              queue_t::iterator curiter = iter++;
 
下面获取请求的工作对象。
#017              LLTextureFetchWorker* req = getWorker(*curiter);
#018              if (!req)
#019              {
#020                     mNetworkQueue.erase(curiter);
#021                     continue; // paranoia
#022              }
#023              if (req->mID == mDebugID)
#024              {
#025                     mDebugCount++; // for setting breakpoints
#026              }
 
检查是否已经下载所有数据。
#027              if (req->mTotalPackets > 0 && req->mLastPacket >= req->mTotalPackets-1)
#028              {
#029                     // We have all the packets... make sure this is high priority
#030 //                req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
#031                     continue;
#032              }
#033               F32 elapsed = req->mRequestedTimer.getElapsedTimeF32();
#034               F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
 
按优先级和请求到达的时间来分类放到请求下载队列。
#035              if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
#036                     (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
#037                     (elapsed >= LAZY_FLUSH_TIMEOUT))
#038              {
#039                     requests[req->mHost].insert(req);
#040              }
#041       }
#042 
#043       std::string http_url;
#044 #if 0
#045       if (gSavedSettings.getBOOL("ImagePipelineUseHTTP"))
#046       {
#047              LLViewerRegion* region = gAgent.getRegion();
#048              if (region)
#049              {
#050                     http_url = region->getCapability("RequestTextureDownload");
#051              }
#052       }
#053 #endif
#054      
 
下面开始循环地发送纹理图片请求到服务器。
#055       for (work_request_map_t::iterator iter1 = requests.begin();
#056               iter1 != requests.end(); ++iter1)
#057       {
#058              bool use_http = http_url.empty() ? false : true;
#059              LLHost host = iter1->first;
#060              // invalid host = use agent host
#061              if (host == LLHost::invalid)
#062              {
#063                      host = gAgent.getRegionHost();
#064              }
#065              else
#066              {
#067                     use_http = false;
#068              }
#069 
#070              if (use_http)
#071              {
#072              }
#073              else
#074              {
 
通过消息系统向服务器发送请求。
#075                     S32 request_count = 0;
#076                     for (request_list_t::iterator iter2 = iter1->second.begin();
#077                             iter2 != iter1->second.end(); ++iter2)
#078                     {
 
取得请求对象。
#079                            LLTextureFetchWorker* req = *iter2;
#080                            req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
 
创建一个新的消息来发送请求。
#081                            if (0 == request_count)
#082                            {
#083                                   gMessageSystem->newMessageFast(_PREHASH_RequestImage);
#084                                   gMessageSystem->nextBlockFast(_PREHASH_AgentData);
#085                                   gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
#086                                   gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
#087                            }
#088                            S32 packet = req->mLastPacket + 1;
 
下面开始创始消息新块数据。
#089                            gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
 
添加图片ID到消息里。
#090                            gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
#091                            gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mSimRequestedDiscard);
#092                            gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
#093                            gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
#094                            gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
#095 //                       llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
#096 //                                     << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl;
#097 
#098                            req->lockWorkData();
#099                            req->mSimRequestedDiscard = req->mDesiredDiscard;
#100                            req->mRequestedPriority = req->mImagePriority;
#101                            req->mRequestedTimer.reset();
#102                            req->unlockWorkData();
#103                            request_count++;
#104                            if (request_count >= IMAGES_PER_REQUEST)
#105                            {
#106 //                              llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl;
#107                                   gMessageSystem->sendSemiReliable(host, NULL, NULL);
#108                                   request_count = 0;
#109                            }
#110                     }
#111                     if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
#112                     {
#113 //                       llinfos << "REQUESTING " << request_count << " IMAGES FROM HOST: " << host.getIPString() << llendl;
 
通过消息系统发送纹理请求下载到服务器。
#114                            gMessageSystem->sendSemiReliable(host, NULL, NULL);
#115                            request_count = 0;
#116                     }
#117              }
#118       }
#119      
 
发送一些取消下载的纹理图片。
#120       // Send cancelations
#121       if (!mCancelQueue.empty())
#122       {
#123              for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
#124                      iter1 != mCancelQueue.end(); ++iter1)
#125              {
#126                     LLHost host = iter1->first;
#127                     if (host == LLHost::invalid)
#128                     {
#129                            host = gAgent.getRegionHost();
#130                     }
#131                     S32 request_count = 0;
#132                     for (queue_t::iterator iter2 = iter1->second.begin();
#133                             iter2 != iter1->second.end(); ++iter2)
#134                     {
#135                            if (0 == request_count)
#136                            {
#137                                   gMessageSystem->newMessageFast(_PREHASH_RequestImage);
#138                                   gMessageSystem->nextBlockFast(_PREHASH_AgentData);
#139                                   gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
#140                                   gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
#141                            }
#142                            gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
#143                            gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
#144                            gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
#145                            gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
#146                            gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
#147                            gMessageSystem->addU8Fast(_PREHASH_Type, 0);
#148 //                       llinfos << "CANCELING IMAGE REQUEST: " << (*iter2) << llendl;
#149 
#150                            request_count++;
#151                            if (request_count >= IMAGES_PER_REQUEST)
#152                            {
#153                                   gMessageSystem->sendSemiReliable(host, NULL, NULL);
#154                                   request_count = 0;
#155                            }
#156                     }
#157                     if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
#158                     {
#159                            gMessageSystem->sendSemiReliable(host, NULL, NULL);
#160                     }
#161              }
#162              mCancelQueue.clear();
#163       }
#164 }
 

通过上面的代码,就可以清晰地看到怎么样把纹理的图片请求发送到服务器的,它是先把请求分类,主要按请求的时间和优先级来决定的。接着把这些需要下载的请求组成一个消息包,通过网络消息系统向服务器发送出去。在这里还处理了那些需要取消下载的纹理请求,由于下载比较大的纹理图片是非常耗费时间和带宽的,应该添加取消下载的功能,这是一个比较好的设计。

 

//蔡军生 2008/4/27 QQ:9073204 深圳
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值