diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llprimitive/llmaterial.h | 4 | ||||
-rw-r--r-- | indra/llprimitive/llmaterialid.cpp | 5 | ||||
-rw-r--r-- | indra/llprimitive/llmaterialid.h | 1 | ||||
-rw-r--r-- | indra/newview/llfloaterdebugmaterials.cpp | 415 | ||||
-rw-r--r-- | indra/newview/llfloaterdebugmaterials.h | 7 | ||||
-rw-r--r-- | indra/newview/llmaterialmgr.cpp | 157 | ||||
-rw-r--r-- | indra/newview/llmaterialmgr.h | 18 |
7 files changed, 310 insertions, 297 deletions
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index 42e3dd04b9..da364e548c 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -27,6 +27,8 @@ #ifndef LL_LLMATERIAL_H #define LL_LLMATERIAL_H +#include <boost/shared_ptr.hpp> + #include "llmaterialid.h" #include "llsd.h" #include "v4coloru.h" @@ -94,4 +96,6 @@ protected: U8 mAlphaMaskCutoff; }; +typedef boost::shared_ptr<LLMaterial> LLMaterialPtr; + #endif // LL_LLMATERIAL_H diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index 73a61f9c54..bbbbf0ced3 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -77,6 +77,11 @@ LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID) return (*this); } +bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) < 0); +} + bool LLMaterialID::isNull() const { return (compareToOtherMaterialID(LLMaterialID::null) == 0); diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index a474703f79..ffefc9f11c 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -42,6 +42,7 @@ public: bool operator == (const LLMaterialID& pOtherMaterialID) const; bool operator != (const LLMaterialID& pOtherMaterialID) const; LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID); + bool operator < (const LLMaterialID& pOtherMaterialID) const; bool isNull() const; diff --git a/indra/newview/llfloaterdebugmaterials.cpp b/indra/newview/llfloaterdebugmaterials.cpp index f69dd6214c..1ee6bab36b 100644 --- a/indra/newview/llfloaterdebugmaterials.cpp +++ b/indra/newview/llfloaterdebugmaterials.cpp @@ -43,6 +43,7 @@ #include "llcolorswatch.h" #include "llenvmanager.h" #include "llfloater.h" +#include "llfloaterreg.h" #include "llfontgl.h" #include "llhttpclient.h" #include "lllineeditor.h" @@ -380,17 +381,12 @@ LLFloaterDebugMaterials::LLFloaterDebugMaterials(const LLSD& pParams) mSelectionUpdateConnection(), mUnparsedGetData(), mNextUnparsedGetDataIndex(-1), - mNextUnparsedQueryDataIndex(-1), - mMultiMaterialsResponder() + mNextUnparsedQueryDataIndex(-1) { } LLFloaterDebugMaterials::~LLFloaterDebugMaterials() { - if (!mMultiMaterialsResponder) - { - mMultiMaterialsResponder.reset(); - } } void LLFloaterDebugMaterials::onGetClicked() @@ -439,7 +435,25 @@ void LLFloaterDebugMaterials::onQueryVisibleObjectsClicked() void LLFloaterDebugMaterials::onPostClicked() { - requestPostMaterials(); + clearPostResults(); + + std::vector<LLScrollListItem*> selectedItems = mViewableObjectsScrollList->getAllSelected(); + if (!selectedItems.empty()) + { + for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); + selectedItemIter != selectedItems.end(); ++selectedItemIter) + { + const LLScrollListItem* selectedItem = *selectedItemIter; + const LLSD& selectedItemValue = selectedItem->getValue(); + + llassert(selectedItemValue.has(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD)); + llassert(selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD).isBinary()); + const LLMaterialID material_id(selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD).asBinary()); + + LLMaterialMgr::instance().get(material_id, boost::bind(&LLFloaterDebugMaterials::onGetMaterial, _1, _2)); + } + LLMaterialMgr::instance().processGetQueue(); + } } void LLFloaterDebugMaterials::onRegionCross() @@ -579,20 +593,6 @@ void LLFloaterDebugMaterials::onGetResponse(bool pRequestStatus, const LLSD& pCo } } -void LLFloaterDebugMaterials::onPostResponse(bool pRequestStatus, const LLSD& pContent) -{ - if (pRequestStatus) - { - setState(kRequestCompleted); - parsePostResponse(pContent); - } - else - { - setState(kError); - } - mMultiMaterialsResponder.reset(); -} - void LLFloaterDebugMaterials::checkRegionMaterialStatus() { LLViewerRegion *region = gAgent.getRegion(); @@ -747,128 +747,6 @@ void LLFloaterDebugMaterials::requestPutMaterials(const LLUUID& regionId, bool p } } -void LLFloaterDebugMaterials::requestPostMaterials() -{ - llassert(!mMultiMaterialsResponder); - - std::vector<LLScrollListItem*> selectedItems = mViewableObjectsScrollList->getAllSelected(); - std::map<LLUUID, std::string> uniqueRegions; - - if (!selectedItems.empty()) - { - for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); - selectedItemIter != selectedItems.end(); ++selectedItemIter) - { - const LLScrollListItem* selectedItem = *selectedItemIter; - const LLSD& selectedItemValue = selectedItem->getValue(); - llassert(selectedItemValue.isMap()); - - llassert(selectedItemValue.has(VIEWABLE_OBJECTS_REGION_ID_FIELD)); - llassert(selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).isUUID()); - const LLUUID& regionId = selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).asUUID(); - if (uniqueRegions.find(regionId) == uniqueRegions.end()) - { - llassert(selectedItemValue.has(VIEWABLE_OBJECTS_OBJECT_ID_FIELD)); - llassert(selectedItemValue.get(VIEWABLE_OBJECTS_OBJECT_ID_FIELD).isUUID()); - const LLUUID& objectId = selectedItemValue.get(VIEWABLE_OBJECTS_OBJECT_ID_FIELD).asUUID(); - LLViewerObject* viewerObject = gObjectList.findObject(objectId); - if (viewerObject != NULL) - { - LLViewerRegion* region = viewerObject->getRegion(); - if (region != NULL) - { - if (!region->capabilitiesReceived()) - { - LL_WARNS("debugMaterials") << "region '" << region->getName() << "' (id:" - << region->getRegionID().asString() << ") has not received capabilities" - << LL_ENDL; - } - else - { - std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME); - - if (capURL.empty()) - { - LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME - << "' is not defined on the current region '" << region->getName() << "'" << LL_ENDL; - } - else - { - uniqueRegions.insert(std::make_pair<LLUUID, std::string>(regionId, capURL)); - } - } - } - } - } - } - - unsigned int numRegions = static_cast<unsigned int>(uniqueRegions.size()); - - if (numRegions > 0U) - { - setState(kRequestStarted); - mMultiMaterialsResponder = MultiMaterialsResponderPtr(new MultiMaterialsResponder(boost::bind(&LLFloaterDebugMaterials::onPostResponse, this, _1, _2), numRegions)); - - for (std::map<LLUUID, std::string>::const_iterator regionIdIter = uniqueRegions.begin(); - regionIdIter != uniqueRegions.end(); ++regionIdIter) - { - const LLUUID& regionId = regionIdIter->first; - std::string capURL = regionIdIter->second; - - LLSD materialIdsData = LLSD::emptyArray(); - - for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); - selectedItemIter != selectedItems.end(); ++selectedItemIter) - { - const LLScrollListItem* selectedItem = *selectedItemIter; - const LLSD& selectedItemValue = selectedItem->getValue(); - - llassert(selectedItemValue.has(VIEWABLE_OBJECTS_REGION_ID_FIELD)); - llassert(selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).isUUID()); - const LLUUID& selectedItemRegionId = selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).asUUID(); - if (selectedItemRegionId == regionId) - { - llassert(selectedItemValue.has(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD)); - llassert(selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD).isBinary()); - const LLSD& materidIdLLSD = selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD); - - materialIdsData.append(materidIdLLSD); - } - } - - if (materialIdsData.size() <= 0) - { - LL_ERRS("debugMaterials") << "no material IDs to POST to region id " << regionId.asString() - << LL_ENDL; - } - else - { - std::string materialsString = zip_llsd(materialIdsData); - S32 materialsSize = materialsString.size(); - - if (materialsSize <= 0) - { - LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL; - } - else - { - LLSD::Binary materialsBinary; - materialsBinary.resize(materialsSize); - memcpy(materialsBinary.data(), materialsString.data(), materialsSize); - - LLSD postData = LLSD::emptyMap(); - postData[MATERIALS_CAP_ZIP_FIELD] = materialsBinary; - - LLHTTPClient::ResponderPtr materialsResponder = new MaterialsResponder("POST", - capURL, boost::bind(&MultiMaterialsResponder::onMaterialsResponse, mMultiMaterialsResponder.get(), _1, _2)); - LLHTTPClient::post(capURL, postData, materialsResponder); - } - } - } - } - } -} - void LLFloaterDebugMaterials::parseQueryViewableObjects() { llassert(mNextUnparsedQueryDataIndex >= 0); @@ -1100,158 +978,111 @@ void LLFloaterDebugMaterials::parseGetResponse() } } -void LLFloaterDebugMaterials::parsePostResponse(const LLSD& pMultiContent) +void LLFloaterDebugMaterials::onGetMaterial(const LLMaterialID& material_id, const LLMaterialPtr materialp) { - clearPostResults(); - - llassert(pMultiContent.isArray()); - for (LLSD::array_const_iterator contentIter = pMultiContent.beginArray(); - contentIter != pMultiContent.endArray(); ++contentIter) + LLFloaterDebugMaterials* instancep = LLFloaterReg::findTypedInstance<LLFloaterDebugMaterials>("floater_debug_materials"); + if ( (!instancep) || (!materialp.get()) ) { - const LLSD& content = *contentIter; - - llassert(content.isMap()); - llassert(content.has(MULTI_MATERIALS_STATUS_FIELD)); - llassert(content.get(MULTI_MATERIALS_STATUS_FIELD).isBoolean()); - if (content.get(MULTI_MATERIALS_STATUS_FIELD).asBoolean()) - { - llassert(content.has(MULTI_MATERIALS_DATA_FIELD)); - llassert(content.get(MULTI_MATERIALS_DATA_FIELD).isMap()); - const LLSD& postData = content.get(MULTI_MATERIALS_DATA_FIELD); - - llassert(postData.has(MATERIALS_CAP_ZIP_FIELD)); - llassert(postData.get(MATERIALS_CAP_ZIP_FIELD).isBinary()); - - LLSD::Binary postDataBinary = postData.get(MATERIALS_CAP_ZIP_FIELD).asBinary(); - S32 postDataSize = static_cast<S32>(postDataBinary.size()); - std::string postDataString(reinterpret_cast<const char*>(postDataBinary.data()), postDataSize); - - std::istringstream postDataStream(postDataString); - - LLSD unzippedPostData; - if (!unzip_llsd(unzippedPostData, postDataStream, postDataSize)) - { - LL_ERRS("debugMaterials") << "cannot unzip LLSD binary content" << LL_ENDL; - } - - LLScrollListCell::Params cellParams; - LLScrollListItem::Params normalMapRowParams; - LLScrollListItem::Params specularMapRowParams; - LLScrollListItem::Params otherDataRowParams; - - llassert(unzippedPostData.isArray()); - for (LLSD::array_const_iterator materialIter = unzippedPostData.beginArray(); - materialIter != unzippedPostData.endArray(); ++materialIter) - { - const LLSD &material_entry = *materialIter; - llassert(material_entry.isMap()); - llassert(material_entry.has(MATERIALS_CAP_OBJECT_ID_FIELD)); - llassert(material_entry.get(MATERIALS_CAP_OBJECT_ID_FIELD).isBinary()); - const LLSD &materialID = material_entry.get(MATERIALS_CAP_OBJECT_ID_FIELD); - std::string materialIDString = convertToPrintableMaterialID(materialID); - - llassert(material_entry.has(MATERIALS_CAP_MATERIAL_FIELD)); - const LLSD &materialData = material_entry.get(MATERIALS_CAP_MATERIAL_FIELD); - llassert(materialData.isMap()); - - LLMaterial material(materialData); - - F32 x, y; - - cellParams.font = LLFontGL::getFontMonospace(); - - cellParams.column = "id"; - cellParams.value = materialIDString; - normalMapRowParams.columns.add(cellParams); - specularMapRowParams.columns.add(cellParams); - otherDataRowParams.columns.add(cellParams); - - cellParams.column = "normal_map_list_map"; - cellParams.value = material.getNormalID().asString(); - normalMapRowParams.columns.add(cellParams); - - cellParams.font = LLFontGL::getFontSansSerif(); - - material.getNormalOffset(x, y); - cellParams.column = "normal_map_list_offset_x"; - cellParams.value = llformat("%f", x); - normalMapRowParams.columns.add(cellParams); - cellParams.column = "normal_map_list_offset_y"; - cellParams.value = llformat("%f", y); - normalMapRowParams.columns.add(cellParams); - - material.getNormalRepeat(x, y); - cellParams.column = "normal_map_list_repeat_x"; - cellParams.value = llformat("%f", x); - normalMapRowParams.columns.add(cellParams); - cellParams.column = "normal_map_list_repeat_y"; - cellParams.value = llformat("%f", y); - normalMapRowParams.columns.add(cellParams); - - cellParams.column = "normal_map_list_rotation"; - cellParams.value = llformat("%f", material.getNormalRotation()); - normalMapRowParams.columns.add(cellParams); - - cellParams.font = LLFontGL::getFontMonospace(); - - cellParams.column = "specular_map_list_map"; - cellParams.value = material.getSpecularID().asString(); - specularMapRowParams.columns.add(cellParams); - - cellParams.font = LLFontGL::getFontSansSerif(); - - material.getSpecularOffset(x, y); - cellParams.column = "specular_map_list_offset_x"; - cellParams.value = llformat("%f", x); - specularMapRowParams.columns.add(cellParams); - cellParams.column = "specular_map_list_offset_y"; - cellParams.value = llformat("%f", y); - specularMapRowParams.columns.add(cellParams); - - material.getSpecularRepeat(x, y); - cellParams.column = "specular_map_list_repeat_x"; - cellParams.value = llformat("%f", x); - specularMapRowParams.columns.add(cellParams); - cellParams.column = "specular_map_list_repeat_y"; - cellParams.value = llformat("%f", y); - specularMapRowParams.columns.add(cellParams); - - cellParams.column = "specular_map_list_rotation"; - cellParams.value = llformat("%d", material.getSpecularRotation()); - specularMapRowParams.columns.add(cellParams); - - const LLColor4U& specularColor = material.getSpecularLightColor(); - cellParams.column = "specular_color"; - cellParams.value = llformat("(%d, %d, %d, %d)", specularColor.mV[0], - specularColor.mV[1], specularColor.mV[2], specularColor.mV[3]); - otherDataRowParams.columns.add(cellParams); - - cellParams.column = "specular_exponent"; - cellParams.value = llformat("%d", material.getSpecularLightExponent()); - otherDataRowParams.columns.add(cellParams); - - cellParams.column = "env_intensity"; - cellParams.value = llformat("%d", material.getEnvironmentIntensity()); - otherDataRowParams.columns.add(cellParams); - - cellParams.column = "alpha_mask_cutoff"; - cellParams.value = llformat("%d", material.getAlphaMaskCutoff()); - otherDataRowParams.columns.add(cellParams); - - cellParams.column = "diffuse_alpha_mode"; - cellParams.value = llformat("%d", material.getDiffuseAlphaMode()); - otherDataRowParams.columns.add(cellParams); - - normalMapRowParams.value = materialIDString; - specularMapRowParams.value = materialIDString; - otherDataRowParams.value = materialIDString; - - mPostNormalMapScrollList->addRow(normalMapRowParams); - mPostSpecularMapScrollList->addRow(specularMapRowParams); - mPostOtherDataScrollList->addRow(otherDataRowParams); - } - } + return; } + + LLScrollListCell::Params cellParams; + LLScrollListItem::Params normalMapRowParams; + LLScrollListItem::Params specularMapRowParams; + LLScrollListItem::Params otherDataRowParams; + + cellParams.font = LLFontGL::getFontMonospace(); + + cellParams.column = "id"; + cellParams.value = material_id.asString(); + normalMapRowParams.columns.add(cellParams); + specularMapRowParams.columns.add(cellParams); + otherDataRowParams.columns.add(cellParams); + + cellParams.column = "normal_map_list_map"; + cellParams.value = materialp->getNormalID().asString(); + normalMapRowParams.columns.add(cellParams); + + cellParams.font = LLFontGL::getFontSansSerif(); + + F32 x, y; + materialp->getNormalOffset(x, y); + cellParams.column = "normal_map_list_offset_x"; + cellParams.value = llformat("%f", x); + normalMapRowParams.columns.add(cellParams); + cellParams.column = "normal_map_list_offset_y"; + cellParams.value = llformat("%f", y); + normalMapRowParams.columns.add(cellParams); + + materialp->getNormalRepeat(x, y); + cellParams.column = "normal_map_list_repeat_x"; + cellParams.value = llformat("%f", x); + normalMapRowParams.columns.add(cellParams); + cellParams.column = "normal_map_list_repeat_y"; + cellParams.value = llformat("%f", y); + normalMapRowParams.columns.add(cellParams); + + cellParams.column = "normal_map_list_rotation"; + cellParams.value = llformat("%f", materialp->getNormalRotation()); + normalMapRowParams.columns.add(cellParams); + + cellParams.font = LLFontGL::getFontMonospace(); + + cellParams.column = "specular_map_list_map"; + cellParams.value = materialp->getSpecularID().asString(); + specularMapRowParams.columns.add(cellParams); + + cellParams.font = LLFontGL::getFontSansSerif(); + + materialp->getSpecularOffset(x, y); + cellParams.column = "specular_map_list_offset_x"; + cellParams.value = llformat("%f", x); + specularMapRowParams.columns.add(cellParams); + cellParams.column = "specular_map_list_offset_y"; + cellParams.value = llformat("%f", y); + specularMapRowParams.columns.add(cellParams); + + materialp->getSpecularRepeat(x, y); + cellParams.column = "specular_map_list_repeat_x"; + cellParams.value = llformat("%f", x); + specularMapRowParams.columns.add(cellParams); + cellParams.column = "specular_map_list_repeat_y"; + cellParams.value = llformat("%f", y); + specularMapRowParams.columns.add(cellParams); + + cellParams.column = "specular_map_list_rotation"; + cellParams.value = llformat("%d", materialp->getSpecularRotation()); + specularMapRowParams.columns.add(cellParams); + + const LLColor4U& specularColor =materialp->getSpecularLightColor(); + cellParams.column = "specular_color"; + cellParams.value = llformat("(%d, %d, %d, %d)", specularColor.mV[0], + specularColor.mV[1], specularColor.mV[2], specularColor.mV[3]); + otherDataRowParams.columns.add(cellParams); + + cellParams.column = "specular_exponent"; + cellParams.value = llformat("%d", materialp->getSpecularLightExponent()); + otherDataRowParams.columns.add(cellParams); + + cellParams.column = "env_intensity"; + cellParams.value = llformat("%d", materialp->getEnvironmentIntensity()); + otherDataRowParams.columns.add(cellParams); + + cellParams.column = "alpha_mask_cutoff"; + cellParams.value = llformat("%d", materialp->getAlphaMaskCutoff()); + otherDataRowParams.columns.add(cellParams); + + cellParams.column = "diffuse_alpha_mode"; + cellParams.value = llformat("%d", materialp->getDiffuseAlphaMode()); + otherDataRowParams.columns.add(cellParams); + + normalMapRowParams.value = cellParams.value; + specularMapRowParams.value = cellParams.value; + otherDataRowParams.value = cellParams.value; + + instancep->mPostNormalMapScrollList->addRow(normalMapRowParams); + instancep->mPostSpecularMapScrollList->addRow(specularMapRowParams); + instancep->mPostOtherDataScrollList->addRow(otherDataRowParams); } void LLFloaterDebugMaterials::setState(EState pState) diff --git a/indra/newview/llfloaterdebugmaterials.h b/indra/newview/llfloaterdebugmaterials.h index 920bc4ae6d..a40e1d1b5c 100644 --- a/indra/newview/llfloaterdebugmaterials.h +++ b/indra/newview/llfloaterdebugmaterials.h @@ -33,6 +33,7 @@ #include <boost/signals2.hpp> #include "llfloater.h" +#include "llmaterial.h" #include "lluuid.h" #include "v4color.h" @@ -40,7 +41,6 @@ class LLButton; class LLColorSwatchCtrl; class LLColor4U; class LLLineEditor; -class LLMaterial; class LLMaterialID; class LLScrollListCtrl; class LLSD; @@ -96,7 +96,6 @@ private: void onDeferredRequestGetMaterials(LLUUID regionId); void onDeferredRequestPutMaterials(LLUUID regionId, bool pIsDoSet); void onGetResponse(bool pRequestStatus, const LLSD& pContent); - void onPostResponse(bool pRequestStatus, const LLSD& pContent); void checkRegionMaterialStatus(); void checkRegionMaterialStatus(const LLUUID& regionId); @@ -107,11 +106,10 @@ private: void requestPutMaterials(bool pIsDoSet); void requestPutMaterials(const LLUUID& regionId, bool pIsDoSet); - void requestPostMaterials(); + static void onGetMaterial(const LLMaterialID& material_id, const LLMaterialPtr materialp); void parseGetResponse(); void parseQueryViewableObjects(); - void parsePostResponse(const LLSD& pMultiContent); void setState(EState pState); inline EState getState() const; @@ -185,7 +183,6 @@ private: S32 mNextUnparsedGetDataIndex; S32 mNextUnparsedQueryDataIndex; - MultiMaterialsResponderPtr mMultiMaterialsResponder; }; diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 5ba7ad5a05..9ee96dccb9 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -28,6 +28,7 @@ #include "llsdserialize.h" +#include "llagent.h" #include "llmaterialmgr.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -47,6 +48,8 @@ #define MATERIALS_CAP_OBJECT_ID_FIELD "ID" #define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID" +#define MATERIALS_POST_TIMEOUT (60.f * 5) + /** * LLMaterialsResponder helper class */ @@ -108,6 +111,57 @@ LLMaterialMgr::~LLMaterialMgr() { } +bool LLMaterialMgr::isGetPending(const LLMaterialID& material_id) +{ + get_pending_map_t::const_iterator itPending = mGetPending.find(material_id); + return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT); +} + +const LLMaterialPtr LLMaterialMgr::get(const LLMaterialID& material_id) +{ + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (itMaterial != mMaterials.end()) + { + return itMaterial->second; + } + + if (!isGetPending(material_id)) + { + mGetQueue.insert(material_id); + } + return LLMaterialPtr(); +} + +boost::signals2::connection LLMaterialMgr::get(const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb) +{ + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (itMaterial != mMaterials.end()) + { + get_callback_t signal; + signal.connect(cb); + signal(material_id, itMaterial->second); + return boost::signals2::connection(); + } + + if (!isGetPending(material_id)) + { + mGetQueue.insert(material_id); + } + + get_callback_t* signalp = NULL; + get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); + if (itCallback == mGetCallbacks.end()) + { + signalp = new get_callback_t(); + mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, signalp)); + } + else + { + signalp = itCallback->second; + } + return signalp->connect(cb);; +} + void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material) { put_queue_t::iterator itQueue = mPutQueue.find(object_id); @@ -128,6 +182,59 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& } } +void LLMaterialMgr::onGetResponse(bool success, const LLSD& content) +{ + if (!success) + { + // *TODO: is there any kind of error handling we can do here? + return; + } + + llassert(content.isMap()); + llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); + llassert(content.get(MATERIALS_CAP_ZIP_FIELD).isBinary()); + + LLSD::Binary content_binary = content.get(MATERIALS_CAP_ZIP_FIELD).asBinary(); + std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); + std::istringstream content_stream(content_string); + + LLSD response_data; + if (!unzip_llsd(response_data, content_stream, content_binary.size())) + { + LL_ERRS("debugMaterials") << "Cannot unzip LLSD binary content" << LL_ENDL; + return; + } + else + { + llassert(response_data.isArray()); + + for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) + { + const LLSD& material_data = *itMaterial; + llassert(material_data.isMap()); + + llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); + llassert(material_data.get(MATERIALS_CAP_OBJECT_ID_FIELD).isBinary()); + LLMaterialID material_id(material_data.get(MATERIALS_CAP_OBJECT_ID_FIELD).asBinary()); + + llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); + llassert(material_data.get(MATERIALS_CAP_MATERIAL_FIELD).isMap()); + LLMaterialPtr material(new LLMaterial(material_data.get(MATERIALS_CAP_MATERIAL_FIELD))); + + mMaterials[material_id] = material; + + get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); + if (itCallback != mGetCallbacks.end()) + { + (*itCallback->second)(material_id, material); + + delete itCallback->second; + mGetCallbacks.erase(itCallback); + } + } + } +} + void LLMaterialMgr::onPutResponse(bool success, const LLSD& content, const LLUUID& object_id) { if (!success) @@ -191,6 +298,56 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content, const LLUUI } } +void LLMaterialMgr::processGetQueue() +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) + { + LL_WARNS("debugMaterials") << "Agent region is NULL" << LL_ENDL; + return; + } + else if (!regionp->capabilitiesReceived()) + { + return; + } + + const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); + if (capURL.empty()) + { + LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME + << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; + return; + } + + LLSD materialsData = LLSD::emptyArray(); + + for (get_queue_t::const_iterator itQueue = mGetQueue.begin(); itQueue != mGetQueue.end(); ++itQueue) + { + const LLMaterialID& material_id = *itQueue; + materialsData.append(material_id.asLLSD()); + } + mGetQueue.clear(); + + std::string materialString = zip_llsd(materialsData); + + S32 materialSize = materialString.size(); + if (materialSize <= 0) + { + LL_ERRS("debugMaterials") << "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)); + LLHTTPClient::post(capURL, postData, materialsResponder); +} + void LLMaterialMgr::processPutQueue() { put_queue_t::iterator itQueue = mPutQueue.begin(); diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index c4e1c01389..d801d40c36 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -28,6 +28,7 @@ #define LL_LLMATERIALMGR_H #include "llmaterial.h" +#include "llmaterialid.h" #include "llsingleton.h" class LLMaterialMgr : public LLSingleton<LLMaterialMgr> @@ -38,16 +39,33 @@ protected: virtual ~LLMaterialMgr(); public: + typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t; + const LLMaterialPtr get(const LLMaterialID& material_id); + boost::signals2::connection get(const LLMaterialID& material_id, get_callback_t::slot_type cb); void put(const LLUUID& object_id, const U8 te, const LLMaterial& material); + void processGetQueue(); void processPutQueue(); protected: + bool isGetPending(const LLMaterialID& material_id); + + void onGetResponse(bool success, const LLSD& content); void onPutResponse(bool success, const LLSD& content, const LLUUID& object_id); protected: + typedef std::set<LLMaterialID> get_queue_t; + get_queue_t mGetQueue; + typedef std::map<LLMaterialID, F64> get_pending_map_t; + get_pending_map_t mGetPending; + typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t; + get_callback_map_t mGetCallbacks; + typedef std::map<U8, LLMaterial> facematerial_map_t; typedef std::map<LLUUID, facematerial_map_t> put_queue_t; put_queue_t mPutQueue; + + typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t; + material_map_t mMaterials; }; #endif // LL_LLMATERIALMGR_H |