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

来源:互联网 发布:二维数组与一维数组 编辑:程序博客网 时间:2024/05/10 13:01
这里接着上一次获取纹理图片线程,继续分析发送纹理图片请求到服务器。代码如下:
#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 深圳