From 40b6cb754122f613c1f3018786f095691ec382ff Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 20 Jan 2010 15:14:38 -0500 Subject: For EXT-4222: Switching outfits sometimes causes me to wear both, and show previous outfit as worn. Postpone appearance change until wearables have resolved. --- indra/newview/llappearancemgr.cpp | 200 ++++++++++++++++++++++---------------- indra/newview/llappearancemgr.h | 38 +++++++- 2 files changed, 153 insertions(+), 85 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 748d8bdfbf..0d4e048dde 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -274,6 +274,7 @@ private: struct LLFoundData { + LLFoundData() {} LLFoundData(const LLUUID& item_id, const LLUUID& asset_id, const std::string& name, @@ -292,20 +293,81 @@ struct LLFoundData }; -struct LLWearableHoldingPattern +class LLWearableHoldingPattern { - LLWearableHoldingPattern() : mResolved(0) {} - ~LLWearableHoldingPattern() - { - for_each(mFoundList.begin(), mFoundList.end(), DeletePointer()); - mFoundList.clear(); - } - typedef std::list found_list_t; +public: + LLWearableHoldingPattern(); + ~LLWearableHoldingPattern(); + + bool pollCompletion(); + bool isDone(); + + typedef std::list found_list_t; found_list_t mFoundList; + LLInventoryModel::item_array_t mObjItems; + LLInventoryModel::item_array_t mGestItems; S32 mResolved; - bool append; + LLTimer mWaitTime; }; +LLWearableHoldingPattern::LLWearableHoldingPattern(): + mResolved(0) +{ + llwarns << "constructor" << llendl; +} + +LLWearableHoldingPattern::~LLWearableHoldingPattern() +{ + llwarns << "destructor" << llendl; +} + +bool LLWearableHoldingPattern::isDone() +{ + return (mResolved >= (S32)mFoundList.size()); +} + +bool LLWearableHoldingPattern::pollCompletion() +{ + bool done = isDone(); + llwarns << "polling, done status: " << done << llendl; + if (done) + { + // Activate all gestures in this folder + if (mGestItems.count() > 0) + { + llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; + + LLGestureManager::instance().activateGestures(mGestItems); + + // Update the inventory item labels to reflect the fact + // they are active. + LLViewerInventoryCategory* catp = + gInventory.getCategory(LLAppearanceManager::instance().getCOF()); + + if (catp) + { + gInventory.updateCategory(catp); + gInventory.notifyObservers(); + } + } + + // Update attachments to match those requested. + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; + LLAgentWearables::userUpdateAttachments(mObjItems); + } + + // Update wearables. + llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LLAppearanceManager::instance().updateAgentWearables(this, false); + + delete this; + } + return done; +} + static void removeDuplicateItems(LLInventoryModel::item_array_t& items) { LLInventoryModel::item_array_t new_items; @@ -336,26 +398,21 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) static void onWearableAssetFetch(LLWearable* wearable, void* data) { LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; - bool append = holder->append; if(wearable) { for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); iter != holder->mFoundList.end(); ++iter) { - LLFoundData* data = *iter; - if(wearable->getAssetID() == data->mAssetID) + LLFoundData& data = *iter; + if(wearable->getAssetID() == data.mAssetID) { - data->mWearable = wearable; + data.mWearable = wearable; break; } } } holder->mResolved += 1; - if(holder->mResolved >= (S32)holder->mFoundList.size()) - { - LLAppearanceManager::instance().updateAgentWearables(holder, append); - } } LLUUID LLAppearanceManager::getCOF() @@ -662,12 +719,12 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); iter != holder->mFoundList.end(); ++iter) { - LLFoundData* data = *iter; - LLWearable* wearable = data->mWearable; + LLFoundData& data = *iter; + LLWearable* wearable = data.mWearable; if( wearable && ((S32)wearable->getType() == i) ) { LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); + item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID); if( item && (item->getAssetUUID() == wearable->getAssetID()) ) { items.put(item); @@ -683,8 +740,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, gAgentWearables.setWearableOutfit(items, wearables, !append); } - delete holder; - // dec_busy_count(); } @@ -706,86 +761,63 @@ void LLAppearanceManager::updateAppearanceFromCOF() LLInventoryModel::item_array_t gest_items; getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links); - if( !wear_items.count() && !obj_items.count() && !gest_items.count()) + if(!wear_items.count()) { LLNotificationsUtil::add("CouldNotPutOnOutfit"); return; } - - // Processes that take time should show the busy cursor - //inc_busy_count(); // BAP this is currently a no-op in llinventorybridge.cpp - do we need it? - - // Activate all gestures in this folder - if (gest_items.count() > 0) - { - llinfos << "Activating " << gest_items.count() << " gestures" << llendl; - LLGestureManager::instance().activateGestures(gest_items); + LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - // Update the inventory item labels to reflect the fact - // they are active. - LLViewerInventoryCategory* catp = gInventory.getCategory(current_outfit_id); - if (catp) + holder->mObjItems = obj_items; + holder->mGestItems = gest_items; + + // Note: can't do normal iteration, because if all the + // wearables can be resolved immediately, then the + // callback will be called (and this object deleted) + // before the final getNextData(). + LLDynamicArray found_container; + for(S32 i = 0; i < wear_items.count(); ++i) + { + LLViewerInventoryItem *item = wear_items.get(i); + LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; + if (item && linked_item) { - gInventory.updateCategory(catp); - gInventory.notifyObservers(); + LLFoundData found(linked_item->getUUID(), + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType()); + holder->mFoundList.push_front(found); + found_container.put(found); } - } - - if(wear_items.count() > 0) - { - // Note: can't do normal iteration, because if all the - // wearables can be resolved immediately, then the - // callback will be called (and this object deleted) - // before the final getNextData(). - LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - LLFoundData* found; - LLDynamicArray found_container; - for(S32 i = 0; i < wear_items.count(); ++i) + else { - LLViewerInventoryItem *item = wear_items.get(i); - LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - if (item && linked_item) + if (!item) { - found = new LLFoundData(linked_item->getUUID(), - linked_item->getAssetUUID(), - linked_item->getName(), - linked_item->getType()); - holder->mFoundList.push_front(found); - found_container.put(found); + llwarns << "attempt to wear a null item " << llendl; } - else + else if (!linked_item) { - if (!item) - { - llwarns << "attempt to wear a null item " << llendl; - } - else if (!linked_item) - { - llwarns << "attempt to wear a broken link " << item->getName() << llendl; - } + llwarns << "attempt to wear a broken link " << item->getName() << llendl; } } - for(S32 i = 0; i < found_container.count(); ++i) - { - holder->append = false; - found = found_container.get(i); - - // Fetch the wearables about to be worn. - LLWearableList::instance().getAsset(found->mAssetID, - found->mName, - found->mAssetType, - onWearableAssetFetch, - (void*)holder); - } } - // Update attachments to match those requested. - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar ) + for(S32 i = 0; i < found_container.count(); ++i) { - LLAgentWearables::userUpdateAttachments(obj_items); + LLFoundData& found = found_container.get(i); + + // Fetch the wearables about to be worn. + LLWearableList::instance().getAsset(found.mAssetID, + found.mName, + found.mAssetType, + onWearableAssetFetch, + (void*)holder); + } + + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); + } void LLAppearanceManager::getDescendentsOfAssetType(const LLUUID& category, diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 20745b70e4..517face777 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -39,7 +39,7 @@ #include "llcallbacklist.h" class LLWearable; -struct LLWearableHoldingPattern; +class LLWearableHoldingPattern; class LLAppearanceManager: public LLSingleton { @@ -168,4 +168,40 @@ void doOnIdle(T callable) gIdleCallbacks.addFunction(&OnIdleCallback::onIdle,cb_functor); } +// Shim class and template function to allow arbitrary boost::bind +// expressions to be run as recurring idle callbacks. +template +class OnIdleCallbackRepeating +{ +public: + OnIdleCallbackRepeating(T callable): + mCallable(callable) + { + } + // Will keep getting called until the callable returns false. + static void onIdle(void *data) + { + OnIdleCallbackRepeating* self = reinterpret_cast*>(data); + bool done = self->call(); + if (done) + { + gIdleCallbacks.deleteFunction(onIdle, data); + delete self; + } + } + bool call() + { + return mCallable(); + } +private: + T mCallable; +}; + +template +void doOnIdleRepeating(T callable) +{ + OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); +} + #endif -- cgit v1.2.3 From a9871e8d258404ff32956b093c80b4cf56c3522c Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 20 Jan 2010 17:59:16 -0500 Subject: For EXT-4222: Switching outfits sometimes causes me to wear both, and show previous outfit as worn. --- indra/newview/llappearancemgr.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 0d4e048dde..ccda737fc6 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -301,6 +301,7 @@ public: bool pollCompletion(); bool isDone(); + bool isTimedOut(); typedef std::list found_list_t; found_list_t mFoundList; @@ -313,12 +314,10 @@ public: LLWearableHoldingPattern::LLWearableHoldingPattern(): mResolved(0) { - llwarns << "constructor" << llendl; } LLWearableHoldingPattern::~LLWearableHoldingPattern() { - llwarns << "destructor" << llendl; } bool LLWearableHoldingPattern::isDone() @@ -326,10 +325,16 @@ bool LLWearableHoldingPattern::isDone() return (mResolved >= (S32)mFoundList.size()); } +bool LLWearableHoldingPattern::isTimedOut() +{ + static F32 max_wait_time = 5.0; // give up if wearable fetches haven't completed in max_wait_time seconds. + return mWaitTime.getElapsedTimeF32() > max_wait_time; +} + bool LLWearableHoldingPattern::pollCompletion() { bool done = isDone(); - llwarns << "polling, done status: " << done << llendl; + llinfos << "polling, done status: " << done << llendl; if (done) { // Activate all gestures in this folder @@ -350,6 +355,10 @@ bool LLWearableHoldingPattern::pollCompletion() gInventory.notifyObservers(); } } + + // Update wearables. + llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LLAppearanceManager::instance().updateAgentWearables(this, false); // Update attachments to match those requested. LLVOAvatar* avatar = gAgent.getAvatarObject(); @@ -359,13 +368,17 @@ bool LLWearableHoldingPattern::pollCompletion() LLAgentWearables::userUpdateAttachments(mObjItems); } - // Update wearables. - llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; - LLAppearanceManager::instance().updateAgentWearables(this, false); - delete this; + return done; + } + else if (isTimedOut()) + { + llwarns << "wearables taking too long to fetch for outfit, retrying updateAppearanceFromCOF()." << llendl; + delete this; + LLAppearanceManager::instance().updateAppearanceFromCOF(); + return true; } - return done; + return false; } static void removeDuplicateItems(LLInventoryModel::item_array_t& items) -- cgit v1.2.3 From 83670fc520cf8f4f78446f853cae584c2970f4fc Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 21 Jan 2010 09:53:18 -0500 Subject: For EXT-4222: Switching outfits sometimes causes me to wear both, and show previous outfit as worn. --- indra/newview/llappearancemgr.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index ccda737fc6..6972d4ec98 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -327,14 +327,14 @@ bool LLWearableHoldingPattern::isDone() bool LLWearableHoldingPattern::isTimedOut() { - static F32 max_wait_time = 5.0; // give up if wearable fetches haven't completed in max_wait_time seconds. + static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds. return mWaitTime.getElapsedTimeF32() > max_wait_time; } bool LLWearableHoldingPattern::pollCompletion() { bool done = isDone(); - llinfos << "polling, done status: " << done << llendl; + llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; if (done) { // Activate all gestures in this folder @@ -829,7 +829,10 @@ void LLAppearanceManager::updateAppearanceFromCOF() } - doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); + if (!holder->pollCompletion()) + { + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); + } } -- cgit v1.2.3 From ccc90257e7622bcf35454e8d4a0780f020ee6c39 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 21 Jan 2010 15:57:06 -0500 Subject: For EXT-4222: Switching outfits sometimes causes me to wear both, and show previous outfit as worn. --- indra/newview/llappearancemgr.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6972d4ec98..61d60fdff9 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -322,7 +322,15 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern() bool LLWearableHoldingPattern::isDone() { - return (mResolved >= (S32)mFoundList.size()); + if (mResolved >= (S32)mFoundList.size()) + return true; // have everything we were waiting for + else if (isTimedOut()) + { + llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl; + return true; + } + return false; + } bool LLWearableHoldingPattern::isTimedOut() @@ -369,16 +377,8 @@ bool LLWearableHoldingPattern::pollCompletion() } delete this; - return done; } - else if (isTimedOut()) - { - llwarns << "wearables taking too long to fetch for outfit, retrying updateAppearanceFromCOF()." << llendl; - delete this; - LLAppearanceManager::instance().updateAppearanceFromCOF(); - return true; - } - return false; + return done; } static void removeDuplicateItems(LLInventoryModel::item_array_t& items) -- cgit v1.2.3 From 6a686700d0f51c02facb645208b7e21aa9b687d9 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 21 Jan 2010 15:23:09 -0800 Subject: Minor cleanup to the logic in LLViewerParcelMedia::play(), to prevent duplication of code. --- indra/newview/llviewerparcelmedia.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index e8b435fc8f..e87dbe5c07 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -212,22 +212,15 @@ void LLViewerParcelMedia::play(LLParcel* parcel) else { // Since the texture id is different, we need to generate a new impl - LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; // Delete the old one first so they don't fight over the texture. sMediaImpl = NULL; - - sMediaImpl = LLViewerMedia::newMediaImpl( - placeholder_texture_id, - media_width, - media_height, - media_auto_scale, - media_loop); - sMediaImpl->setIsParcelMedia(true); - sMediaImpl->navigateTo(media_url, mime_type, true); + + // A new impl will be created below. } } - else + + if(!sMediaImpl) { LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; -- cgit v1.2.3 From 96721b3cccee96574695764871c8ac92ee5bb845 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 21 Jan 2010 15:39:14 -0800 Subject: Partial fix for EXT-4508 (nearby media floater parcel media button breaks rtsp) This is actually two seperate issues: 1) After disabling parcel media from the nearby media floater, it can't be re-enabled 2) When you disable parcel media from the nearby media floater, faces displaying it don't revert to their original texture This change fixes issue (1), by forcing the priority of the inworld media instance to normal in LLViewerMedia::updateMedia() so it will always get reloaded instead of possibly being kept unloaded due to already-loaded prim media. Issue (2) is still under investigation. In addition to the case where you disable parcel media from the nearby media floater, it also doesn't restore the textures when you leave the parcel, and I think I've even seen it when unloading --- indra/newview/llviewermedia.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview') diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 04d67fe750..d712446d83 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -752,6 +752,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg) new_priority = LLPluginClassMedia::PRIORITY_NORMAL; impl_count_interest_normal++; } + else if(pimpl->isParcelMedia()) + { + new_priority = LLPluginClassMedia::PRIORITY_NORMAL; + impl_count_interest_normal++; + } else { // Look at interest and CPU usage for instances that aren't in any of the above states. -- cgit v1.2.3