Example #1
0
LLSD LLMaterialID::asLLSD() const
{
	LLSD::Binary materialIDBinary;

	materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
	memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));

	LLSD materialID = materialIDBinary;
	return materialID;
}
void LLMaterialMgr::processPutQueue()
{
	typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
	regionput_request_map requests;

	put_queue_t::iterator loopQueue = mPutQueue.begin();
	while (mPutQueue.end() != loopQueue)
	{
		put_queue_t::iterator itQueue = loopQueue++;

		const LLUUID& object_id = itQueue->first;
		const LLViewerObject* objectp = gObjectList.findObject(object_id);
		if ( !objectp )
		{
			LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;
			mPutQueue.erase(itQueue);
		}
		else
		{
			LLViewerRegion* regionp = objectp->getRegion();
			if ( !regionp )
		{
				LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
				mPutQueue.erase(itQueue);
		}
			else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
			{
		LLSD& facesData = requests[regionp];

		facematerial_map_t& face_map = itQueue->second;
				U32 max_entries = regionp->getMaxMaterialsPerTransaction();
		facematerial_map_t::iterator itFace = face_map.begin();
				while ( (face_map.end() != itFace) && (facesData.size() < (int)max_entries) )
		{
			LLSD faceData = LLSD::emptyMap();
			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
			faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
			if (!itFace->second.isNull())
			{
				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
			}
			facesData.append(faceData);
			face_map.erase(itFace++);
		}
		if (face_map.empty())
		{
			mPutQueue.erase(itQueue);
		}
	}
		}
	}

	for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
	{
		LLViewerRegion* regionp = itRequest->first;
		std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
		if (capURL.empty())
		{
			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
			continue;
		}

		LLSD materialsData = LLSD::emptyMap();
		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;

		std::string materialString = zip_llsd(materialsData);

		S32 materialSize = materialString.size();

		if (materialSize > 0)
		{
			LLSD::Binary materialBinary;
			materialBinary.resize(materialSize);
			memcpy(materialBinary.data(), materialString.data(), materialSize);

			LLSD putData = LLSD::emptyMap();
			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;

			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
			LLHTTPClient::put(capURL, putData, materialsResponder);
			regionp->resetMaterialsCapThrottle();
		}
		else
		{
			LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
		}
	}
}
void LLMaterialMgr::processGetQueue()
{
	get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
	while (mGetQueue.end() != loopRegionQueue)
	{
		get_queue_t::iterator itRegionQueue = loopRegionQueue++;

		const LLUUID& region_id = itRegionQueue->first;
		if (isGetAllPending(region_id))
		{
			continue;
		}

		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
		if (!regionp)
		{
			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
			mGetQueue.erase(itRegionQueue);
			continue;
		}
		else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
		{
			continue;
		}
		else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
		{
			LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
			getAll(region_id);
			continue;
		}

		const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
		if (capURL.empty())
		{
			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
			mGetQueue.erase(itRegionQueue);
			continue;
		}

		LLSD materialsData = LLSD::emptyArray();

		material_queue_t& materials = itRegionQueue->second;
		U32 max_entries = regionp->getMaxMaterialsPerTransaction();
		material_queue_t::iterator loopMaterial = materials.begin();
		while ( (materials.end() != loopMaterial) && (materialsData.size() < (int)max_entries) )
		{
			material_queue_t::iterator itMaterial = loopMaterial++;
			materialsData.append((*itMaterial).asLLSD());
			materials.erase(itMaterial);
			markGetPending(region_id, *itMaterial);
		}
		if (materials.empty())
		{
			mGetQueue.erase(itRegionQueue);
		}
		
		std::string materialString = zip_llsd(materialsData);

		S32 materialSize = materialString.size();
		if (materialSize <= 0)
		{
			LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
			return;
		}

		LLSD::Binary materialBinary;
		materialBinary.resize(materialSize);
		memcpy(materialBinary.data(), materialString.data(), materialSize);

		LLSD postData = LLSD::emptyMap();
		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;

		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." 
			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
		LLHTTPClient::post(capURL, postData, materialsResponder);
		regionp->resetMaterialsCapThrottle();
	}
}