Skip to content
Snippets Groups Projects
Commit 353ac396 authored by Rick Pasetto's avatar Rick Pasetto
Browse files

FIX DEV-41991: do not allow media settings panel to come up if media data is in flight

Review #33

This change marks the current selection "not editable" if
any objects in the selection are currently "in flight" (i.e.
their media data has not been fetched yet, or is in the
process of being fetched).  This involved adding API to
LLMediaDataClient to query whether an object is in the
process of being fetched (i.e. in the queue).  I've added
a unit test for this new API.
parent 2420a4b9
Branches
Tags
No related merge requests found
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
#include "llviewermenu.h" #include "llviewermenu.h"
#include "llviewerparcelmgr.h" #include "llviewerparcelmgr.h"
#include "llviewerwindow.h" #include "llviewerwindow.h"
#include "llvovolume.h"
#include "lluictrlfactory.h" #include "lluictrlfactory.h"
// Globals // Globals
...@@ -1080,20 +1081,44 @@ void LLFloaterTools::getMediaState() ...@@ -1080,20 +1081,44 @@ void LLFloaterTools::getMediaState()
bool editable = (first_object->permModify() || selectedMediaEditable()); bool editable = (first_object->permModify() || selectedMediaEditable());
// Check modify permissions and whether any selected objects are in
// the process of being fetched. If they are, then we're not editable
if (editable)
{
LLObjectSelection::iterator iter = selected_objects->begin();
LLObjectSelection::iterator end = selected_objects->end();
for ( ; iter != end; ++iter)
{
LLSelectNode* node = *iter;
LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
if (NULL != object)
{
if (!object->permModify() || object->isMediaDataBeingFetched())
{
editable = false;
break;
}
}
}
}
// Media settings // Media settings
U8 has_media = (U8)0; bool bool_has_media = false;
struct media_functor : public LLSelectedTEGetFunctor<U8> struct media_functor : public LLSelectedTEGetFunctor<bool>
{ {
U8 get(LLViewerObject* object, S32 face) bool get(LLViewerObject* object, S32 face)
{ {
return (object->getTE(face)->getMediaTexGen()); LLTextureEntry *te = object->getTE(face);
if (te)
{
return te->hasMedia();
}
return false;
} }
} func; } func;
// check if all faces have media(or, all dont have media) // check if all faces have media(or, all dont have media)
LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media ); LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
const LLMediaEntry default_media_data; const LLMediaEntry default_media_data;
......
...@@ -324,6 +324,22 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue ...@@ -324,6 +324,22 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue
return s; return s;
} }
// find the given object in the queue.
bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const
{
std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin();
std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end();
while (iter < end)
{
if (obj->getID() == (*iter)->getObject()->getID())
{
return true;
}
iter++;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// //
// LLMediaDataClient::QueueTimer // LLMediaDataClient::QueueTimer
...@@ -491,6 +507,11 @@ bool LLMediaDataClient::isEmpty() const ...@@ -491,6 +507,11 @@ bool LLMediaDataClient::isEmpty() const
return (NULL == pRequestQueue) ? true : pRequestQueue->empty(); return (NULL == pRequestQueue) ? true : pRequestQueue->empty();
} }
bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const
{
return (NULL == pRequestQueue) ? false : pRequestQueue->find(object);
}
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// //
// LLObjectMediaDataClient // LLObjectMediaDataClient
......
...@@ -91,6 +91,9 @@ class LLMediaDataClient : public LLRefCount ...@@ -91,6 +91,9 @@ class LLMediaDataClient : public LLRefCount
// Returns true iff the queue is empty // Returns true iff the queue is empty
bool isEmpty() const; bool isEmpty() const;
// Returns true iff the given object is in the queue
bool isInQueue(const LLMediaDataClientObject::ptr_t &object) const;
protected: protected:
// Destructor // Destructor
virtual ~LLMediaDataClient(); // use unref virtual ~LLMediaDataClient(); // use unref
...@@ -206,6 +209,9 @@ class LLMediaDataClient : public LLRefCount ...@@ -206,6 +209,9 @@ class LLMediaDataClient : public LLRefCount
Comparator > Comparator >
{ {
public: public:
// Return whether the given object is in the queue
bool find(const LLMediaDataClientObject::ptr_t &obj) const;
friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q); friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);
}; };
......
...@@ -109,6 +109,7 @@ class LLMediaDataClientObjectImpl : public LLMediaDataClientObject ...@@ -109,6 +109,7 @@ class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{ {
result = te->getMediaData()->asLLSD(); result = te->getMediaData()->asLLSD();
// XXX HACK: workaround bug in asLLSD() where whitelist is not set properly // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
// See DEV-41949
if (!result.has(LLMediaEntry::WHITELIST_KEY)) if (!result.has(LLMediaEntry::WHITELIST_KEY))
{ {
result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
...@@ -1668,6 +1669,13 @@ void LLVOVolume::requestMediaDataUpdate() ...@@ -1668,6 +1669,13 @@ void LLVOVolume::requestMediaDataUpdate()
sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this)); sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));
} }
bool LLVOVolume::isMediaDataBeingFetched() const
{
// I know what I'm doing by const_casting this away: this is just
// a wrapper class that is only going to do a lookup.
return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this)));
}
void LLVOVolume::cleanUpMediaImpls() void LLVOVolume::cleanUpMediaImpls()
{ {
// Iterate through our TEs and remove any Impls that are no longer used // Iterate through our TEs and remove any Impls that are no longer used
......
...@@ -266,6 +266,9 @@ class LLVOVolume : public LLViewerObject ...@@ -266,6 +266,9 @@ class LLVOVolume : public LLViewerObject
LLVector3 getApproximateFaceNormal(U8 face_id); LLVector3 getApproximateFaceNormal(U8 face_id);
// Returns 'true' iff the media data for this object is in flight
bool isMediaDataBeingFetched() const;
protected: protected:
S32 computeLODDetail(F32 distance, F32 radius); S32 computeLODDetail(F32 distance, F32 radius);
BOOL calcLOD(); BOOL calcLOD();
......
...@@ -497,5 +497,38 @@ namespace tut ...@@ -497,5 +497,38 @@ namespace tut
ensure("REF COUNT", o->getNumRefs(), 1); ensure("REF COUNT", o->getNumRefs(), 1);
} }
template<> template<>
void mediadataclient_object_t::test<7>()
{
// Test LLMediaDataClient::isInQueue()
LOG_TEST(7);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_1,"3.0","1.0"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
_DATA(VALID_OBJECT_ID_2,"1.0","1.0"));
int num_refs_start = o1->getNumRefs();
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
ensure("not in queue yet 1", ! mdc->isInQueue(o1));
ensure("not in queue yet 2", ! mdc->isInQueue(o2));
mdc->fetchMedia(o1);
ensure("is in queue", mdc->isInQueue(o1));
ensure("is not in queue", ! mdc->isInQueue(o2));
::pump_timers();
ensure("not in queue anymore", ! mdc->isInQueue(o1));
ensure("still is not in queue", ! mdc->isInQueue(o2));
ensure("queue empty", mdc->isEmpty());
}
// Make sure everyone's destroyed properly
ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment