您的位置:首页 > 其它

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

2008-04-27 22:33 555 查看
这里接着上一次获取纹理图片线程,继续分析发送纹理图片请求到服务器。代码如下:
#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 深圳
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐