summaryrefslogtreecommitdiff
path: root/indra/newview/llmaterialmgr.cpp
diff options
context:
space:
mode:
authorKitty Barnett <develop@catznip.com>2012-12-05 19:34:27 +0100
committerKitty Barnett <develop@catznip.com>2012-12-05 19:34:27 +0100
commit4c68faec400e4c6d75a53528d8064a3448707158 (patch)
tree01a30035a359b97b13a48332ba49b74332b44df8 /indra/newview/llmaterialmgr.cpp
parent1e194eb412bb10c1733ed76e270e45578ac15e0b (diff)
Added LLMaterialMgr::getAll() to retrieve all materials for the specified region
Diffstat (limited to 'indra/newview/llmaterialmgr.cpp')
-rw-r--r--indra/newview/llmaterialmgr.cpp145
1 files changed, 142 insertions, 3 deletions
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index a8731a8c4c..d463f9480e 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llagent.h"
#include "llcallbacklist.h"
@@ -34,6 +35,7 @@
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
+#include "llworld.h"
/**
* Materials cap parameters
@@ -49,6 +51,7 @@
#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
+#define MATERIALS_GET_TIMEOUT (60.f * 20)
#define MATERIALS_POST_TIMEOUT (60.f * 5)
/**
@@ -165,6 +168,41 @@ boost::signals2::connection LLMaterialMgr::get(const LLMaterialID& material_id,
return signalp->connect(cb);;
}
+bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id)
+{
+ getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
+ return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT);
+}
+
+void LLMaterialMgr::getAll(const LLUUID& region_id)
+{
+ if (!isGetAllPending(region_id))
+ {
+ mGetAllQueue.insert(region_id);
+ }
+}
+
+boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb)
+{
+ if (!isGetAllPending(region_id))
+ {
+ mGetAllQueue.insert(region_id);
+ }
+
+ getall_callback_t* signalp = NULL;
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (mGetAllCallbacks.end() == itCallback)
+ {
+ signalp = new getall_callback_t();
+ mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_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);
@@ -185,6 +223,19 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial&
}
}
+const LLMaterialPtr LLMaterialMgr::setMaterial(const LLMaterialID& material_id, const LLSD& material_data)
+{
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (mMaterials.end() == itMaterial)
+ {
+ LLMaterialPtr material(new LLMaterial(material_data));
+ mMaterials[material_id] = material;
+ return material;
+ }
+ return itMaterial->second;
+}
+
+
void LLMaterialMgr::onGetResponse(bool success, const LLSD& content)
{
if (!success)
@@ -222,9 +273,7 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content)
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;
+ LLMaterialPtr material = setMaterial(material_id, material_data.get(MATERIALS_CAP_MATERIAL_FIELD));
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback != mGetCallbacks.end())
@@ -238,6 +287,57 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content)
}
}
+void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id)
+{
+ 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;
+ }
+
+ llassert(response_data.isArray());
+ material_map_t materials;
+ 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 = setMaterial(material_id, material_data.get(MATERIALS_CAP_MATERIAL_FIELD));
+
+ materials[material_id] = material;
+ }
+
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (itCallback != mGetAllCallbacks.end())
+ {
+ (*itCallback->second)(region_id, materials);
+
+ delete itCallback->second;
+ mGetAllCallbacks.erase(itCallback);
+ }
+}
+
void LLMaterialMgr::onPutResponse(bool success, const LLSD& content, const LLUUID& object_id)
{
if (!success)
@@ -314,6 +414,11 @@ void LLMaterialMgr::onIdle(void*)
instancep->processGetQueue();
}
+ if (!instancep->mGetAllQueue.empty())
+ {
+ instancep->processGetAllQueue();
+ }
+
if (!instancep->mPutQueue.empty())
{
instancep->processPutQueue();
@@ -370,6 +475,40 @@ void LLMaterialMgr::processGetQueue()
LLHTTPClient::post(capURL, postData, materialsResponder);
}
+void LLMaterialMgr::processGetAllQueue()
+{
+ getall_queue_t::iterator itRegion = mGetAllQueue.begin();
+ while (mGetAllQueue.end() != itRegion)
+ {
+ getall_queue_t::iterator curRegion = itRegion++;
+
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(*curRegion);
+ if (regionp == NULL)
+ {
+ LL_WARNS("debugMaterials") << "Unknown region with id " << (*curRegion).asString() << LL_ENDL;
+ mGetAllQueue.erase(curRegion);
+ continue;
+ }
+ else if (!regionp->capabilitiesReceived())
+ {
+ continue;
+ }
+
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
+ mGetAllQueue.erase(curRegion);
+ continue;
+ }
+
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *curRegion));
+ LLHTTPClient::get(capURL, materialsResponder);
+ mGetAllQueue.erase(curRegion);
+ }
+}
+
void LLMaterialMgr::processPutQueue()
{
put_queue_t::iterator itQueue = mPutQueue.begin();