diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llappviewer.cpp | 43 | ||||
-rw-r--r-- | indra/newview/llappviewer.h | 2 | ||||
-rw-r--r-- | indra/newview/llviewermessage.cpp | 54 | ||||
-rw-r--r-- | indra/newview/llviewermessage.h | 1 |
4 files changed, 58 insertions, 42 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ea6859f0c6..6a808b5daf 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -322,6 +322,41 @@ static std::string gLaunchFileOnQuit; // Used on Win32 for other apps to identify our window (eg, win_setup) const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; +//-- LLDeferredTaskList ------------------------------------------------------ + +/** + * A list of deferred tasks. + * + * We sometimes need to defer execution of some code until the viewer gets idle, + * e.g. removing an inventory item from within notifyObservers() may not work out. + * + * Tasks added to this list will be executed in the next LLAppViewer::idle() iteration. + * All tasks are executed only once. + */ +class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList> +{ + LOG_CLASS(LLDeferredTaskList); + + friend class LLAppViewer; + typedef boost::signals2::signal<void()> signal_t; + + void addTask(const signal_t::slot_type& cb) + { + mSignal.connect(cb); + } + + void run() + { + if (!mSignal.empty()) + { + mSignal(); + mSignal.disconnect_all_slots(); + } + } + + signal_t mSignal; +}; + //---------------------------------------------------------------------------- // List of entries from strings.xml to always replace @@ -3829,6 +3864,11 @@ bool LLAppViewer::initCache() } } +void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb) +{ + LLDeferredTaskList::instance().addTask(cb); +} + void LLAppViewer::purgeCache() { LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; @@ -4422,6 +4462,9 @@ void LLAppViewer::idle() gAudiop->idle(max_audio_decode_time); } } + + // Execute deferred tasks. + LLDeferredTaskList::instance().run(); // Handle shutdown process, for example, // wait for floaters to close, send quit message, diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 61ee6a7cf1..32115e0e7b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -164,6 +164,8 @@ public: login_completed_signal_t mOnLoginCompleted; boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); } + void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle + void purgeCache(); // Clear the local cache. // mute/unmute the system's master audio diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 321d02aaf1..64aeb750c6 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1049,48 +1049,26 @@ void start_new_inventory_observer() class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver { LOG_CLASS(LLDiscardAgentOffer); + public: LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) : LLInventoryFetchItemsObserver(object_id), mFolderID(folder_id), mObjectID(object_id) {} - virtual ~LLDiscardAgentOffer() {} + virtual void done() { LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL; - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - bool notify = false; - if(trash_id.notNull() && mObjectID.notNull()) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(mFolderID, -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - gInventory.moveObject(mObjectID, trash_id); - LLInventoryObject* obj = gInventory.getObject(mObjectID); - if(obj) - { - // no need to restamp since this is already a freshly - // stamped item. - obj->updateParentOnServer(FALSE); - notify = true; - } - } - else - { - LL_WARNS("Messaging") << "DiscardAgentOffer unable to find: " - << (trash_id.isNull() ? "trash " : "") - << (mObjectID.isNull() ? "object" : "") << LL_ENDL; - } + + // We're invoked from LLInventoryModel::notifyObservers(). + // If we now try to remove the inventory item, it will cause a nested + // notifyObservers() call, which won't work. + // So defer moving the item to trash until viewer gets idle (in a moment). + LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeItem, &gInventory, mObjectID)); gInventory.removeObserver(this); - if(notify) - { - gInventory.notifyObservers(); - } delete this; } + protected: LLUUID mFolderID; LLUUID mObjectID; @@ -1495,7 +1473,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& LLChat chat; std::string log_message; S32 button = LLNotificationsUtil::getSelectedOption(notification, response); - + LLInventoryObserver* opener = NULL; LLViewerInventoryCategory* catp = NULL; catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID); @@ -1527,7 +1505,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here: from_string = chatHistory_string = mFromName; - bool busy=FALSE; + bool busy = gAgent.getBusy(); switch(button) { @@ -1586,9 +1564,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } break; - case IOR_BUSY: - //Busy falls through to decline. Says to make busy message. - busy=TRUE; case IOR_MUTE: // MUTE falls through to decline case IOR_DECLINE: @@ -1734,7 +1709,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const from_string = chatHistory_string = mFromName; } - bool busy=FALSE; + bool busy = gAgent.getBusy(); switch(button) { @@ -1780,9 +1755,6 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const } // end switch (mIM) break; - case IOR_BUSY: - //Busy falls through to decline. Says to make busy message. - busy=TRUE; case IOR_MUTE: // MUTE falls through to decline case IOR_DECLINE: @@ -2667,7 +2639,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { // Until throttling is implemented, busy mode should reject inventory instead of silently // accepting it. SEE SL-39554 - info->forceResponse(IOR_BUSY); + info->forceResponse(IOR_DECLINE); } else { diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 9d09d9c01a..d8acd99953 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -57,7 +57,6 @@ enum InventoryOfferResponse IOR_ACCEPT, IOR_DECLINE, IOR_MUTE, - IOR_BUSY, IOR_SHOW }; |