diff options
author | Merov Linden <merov@lindenlab.com> | 2014-05-01 17:36:17 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2014-05-01 17:36:17 -0700 |
commit | 87192990592f9abda8314393bdcac3627c15d5ac (patch) | |
tree | 066035a26ea60c8ab6b203559377e060c4b1fd9d | |
parent | 7df858622bf379781246f23445f86ead4ad3288a (diff) |
DD-81 : Fixed the stock folder count update using an inventory observer. This observe other changes as well of interest to marketplace and should improve consistency in general
-rwxr-xr-x | indra/newview/llfloatermarketplacelistings.cpp | 4 | ||||
-rwxr-xr-x | indra/newview/llinventoryfunctions.cpp | 97 | ||||
-rwxr-xr-x | indra/newview/llinventoryfunctions.h | 4 | ||||
-rwxr-xr-x | indra/newview/llinventorymodel.cpp | 15 | ||||
-rwxr-xr-x | indra/newview/llmarketplacefunctions.cpp | 66 | ||||
-rwxr-xr-x | indra/newview/llmarketplacefunctions.h | 7 |
6 files changed, 153 insertions, 40 deletions
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index fb6ff211d1..b1b397c77c 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -92,6 +92,10 @@ BOOL LLPanelMarketplaceListings::postBuild() void LLPanelMarketplaceListings::draw() { + if (LLMarketplaceData::instance().checkDirtyCount()) + { + update_all_marketplace_count(); + } LLPanel::draw(); } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 62b626d0c8..413c0d4b4b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -126,7 +126,6 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) // for all observers of the folder to, possibly, change the display label of the folder // so that's the only thing we change on the update mask. gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); - gInventory.notifyObservers(); // Update all descendent folders down LLInventoryModel::cat_array_t* cat_array; @@ -142,55 +141,87 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) return; } -void update_marketplace_category(const LLUUID& cat_id) +void update_marketplace_category(const LLUUID& cur_uuid) { - // When changing the marketplace status of a folder, we usually have to change the status of all + // When changing the marketplace status of an item, we usually have to change the status of all // folders in the same listing. This is because the display of each folder is affected by the // overall status of the whole listing. - // Consequently, the only way to correctly update a folder anywhere in the marketplace is to + // Consequently, the only way to correctly update an item anywhere in the marketplace is to // update the whole listing from its listing root. // This is not as bad as it seems as we only update folders, not items, and the folder nesting depth // is limited to 4. // We also take care of degenerated cases so we don't update all folders in the inventory by mistake. - const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - // No marketplace -> likely called too early... or - // Not a descendent of the marketplace listings root -> likely called in error then... - if (marketplace_listings_uuid.isNull() || !gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid)) + // Grab marketplace listing data for this item + S32 depth = depth_nesting_in_marketplace(cur_uuid); + if (depth > 0) { - // In those cases, just do the regular category update - LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); - gInventory.updateCategory(cat); - gInventory.notifyObservers(); - return; - } + // Retrieve the listing uuid this object is in + LLUUID listing_uuid = nested_parent_id(cur_uuid, depth); - // Grab marketplace listing data for this folder - S32 depth = depth_nesting_in_marketplace(cat_id); - LLUUID listing_uuid = nested_parent_id(cat_id, depth); - - // Verify marketplace data consistency for this listing - if (LLMarketplaceData::instance().isListed(listing_uuid)) - { - LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); - if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + // Verify marketplace data consistency for this listing + if (LLMarketplaceData::instance().isListed(listing_uuid)) { - // *TODO : Confirm with Producer that this is what we want to happen in that case! - llinfos << "Merov : Unlist as the version folder is not under the listing folder anymore!!" << llendl; - LLMarketplaceData::instance().setVersionFolderID(listing_uuid, LLUUID::null); - LLMarketplaceData::instance().setActivation(listing_uuid, false); + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); + if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + { + // *TODO : Confirm with Producer that this is what we want to happen in that case! + llinfos << "Merov : Unlist as the version folder is not under the listing folder anymore!!" << llendl; + LLMarketplaceData::instance().setVersionFolderID(listing_uuid, LLUUID::null); + LLMarketplaceData::instance().setActivation(listing_uuid, false); + } } - if (!gInventory.isObjectDescendentOf(listing_uuid, marketplace_listings_uuid)) + + // Update all descendents starting from the listing root + update_marketplace_folder_hierarchy(listing_uuid); + } + else if (depth < 0) + { + if (LLMarketplaceData::instance().isListed(cur_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! llinfos << "Merov : Disassociate as the listing folder is not under the marketplace folder anymore!!" << llendl; - LLMarketplaceData::instance().deleteListing(listing_uuid); + LLMarketplaceData::instance().deleteListing(cur_uuid); } } + + return; +} + +// Iterate through the marketplace and flag for label change all categories that countain a stock folder (i.e. stock folders and embedding folders up the hierarchy) +void update_all_marketplace_count(const LLUUID& cat_id) +{ + // Get all descendent folders down + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array); - // Update all descendents starting from the listing root - update_marketplace_folder_hierarchy(listing_uuid); + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + if (category->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // Listing containing stock folders needs to be updated but not others + // Note: we take advantage of the fact that stock folder *do not* contain sub folders to avoid a recursive call here + update_marketplace_category(category->getUUID()); + } + else + { + // Explore the contained folders recursively + update_all_marketplace_count(category->getUUID()); + } + } +} +void update_all_marketplace_count() +{ + // Get the marketplace root and launch the recursive exploration + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (!marketplace_listings_uuid.isNull()) + { + update_all_marketplace_count(marketplace_listings_uuid); + } return; } @@ -966,6 +997,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Update the modified folders update_marketplace_category(src_folder); update_marketplace_category(dest_folder); + gInventory.notifyObservers(); } else { @@ -1011,6 +1043,7 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // Update the modified folders update_marketplace_category(src_folder); update_marketplace_category(dest_folder); + gInventory.notifyObservers(); } } @@ -1227,6 +1260,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ items_vector[i].pop_back(); } update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); } } // Clean up @@ -1248,6 +1282,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { // Update the current folder update_marketplace_category(cat->getUUID()); + gInventory.notifyObservers(); } } diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index a31bc9dbdd..aecbe816c4 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -58,8 +58,10 @@ void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id); void show_item_original(const LLUUID& item_uuid); void reset_inventory_filter(); -// Just nudge the category in the global inventory to signal that its marketplace status changed +// Nudge the listing categories in the inventory to signal that their marketplace status changed void update_marketplace_category(const LLUUID& cat_id); +// Nudge all listing categories to signal that their marketplace status changed +void update_all_marketplace_count(); void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c0aedd3881..0fbccb2f3f 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1441,16 +1441,17 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) } mModifyMask |= mask; - if (referent.notNull()) + if (referent.notNull() && (mChangedItemIDs.find(referent) == mChangedItemIDs.end())) { mChangedItemIDs.insert(referent); - } + update_marketplace_category(referent); - // Update all linked items. Starting with just LABEL because I'm - // not sure what else might need to be accounted for this. - if (mModifyMask & LLInventoryObserver::LABEL) - { - addChangedMaskForLinks(referent, LLInventoryObserver::LABEL); + // Update all linked items. Starting with just LABEL because I'm + // not sure what else might need to be accounted for this. + if (mModifyMask & LLInventoryObserver::LABEL) + { + addChangedMaskForLinks(referent, LLInventoryObserver::LABEL); + } } } diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 5804bce819..c9e6623b72 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llhttpclient.h" #include "llinventoryfunctions.h" +#include "llinventoryobserver.h" #include "llsdserialize.h" #include "lltimer.h" #include "lltrans.h" @@ -607,6 +608,54 @@ void LLMarketplaceInventoryImporter::updateImport() // // Direct Delivery : Marketplace tuples and data // +class LLMarketplaceInventoryObserver : public LLInventoryObserver +{ +public: + LLMarketplaceInventoryObserver() {} + virtual ~LLMarketplaceInventoryObserver() {} + virtual void changed(U32 mask); +}; + +void LLMarketplaceInventoryObserver::changed(U32 mask) +{ + // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder: + // * stock counts changing : no copy items coming in and out will change the stock count on folders + // * version and listing folders : moving those might invalidate the marketplace data itself + // Since we should cannot raise inventory change while in the observer is called (the list will be cleared once observers are called) + // we need to raise a flag in the inventory to signal that things have been dirtied. + + // That's the only changes that really do make sense for marketplace to worry about + if ((mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) != 0) + { + const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + + std::set<LLUUID>::const_iterator id_it = changed_items.begin(); + std::set<LLUUID>::const_iterator id_end = changed_items.end(); + for (;id_it != id_end; ++id_it) + { + LLInventoryObject* obj = gInventory.getObject(*id_it); + if (LLAssetType::AT_CATEGORY == obj->getType()) + { + // If it's a folder known to the marketplace, let's check it's in proper shape + if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it)) + { + LLInventoryCategory* cat = (LLInventoryCategory*)(obj); + validate_marketplacelistings(cat); + } + } + else + { + // If it's not a category, it's an item... + LLInventoryItem* item = (LLInventoryItem*)(obj); + // If it's a no copy item, we may need to update the label count of marketplace listings + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + LLMarketplaceData::instance().setDirtyCount(); + } + } + } + } +} // Tuple == Item LLMarketplaceTuple::LLMarketplaceTuple() : @@ -637,9 +686,17 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id, // Data map LLMarketplaceData::LLMarketplaceData() : mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED), - mStatusUpdatedSignal(NULL) + mStatusUpdatedSignal(NULL), + mDirtyCount(false) { mTestCurrentMarketplaceID = 1234567; + mInventoryObserver = new LLMarketplaceInventoryObserver; + gInventory.addObserver(mInventoryObserver); +} + +LLMarketplaceData::~LLMarketplaceData() +{ + gInventory.removeObserver(mInventoryObserver); } S32 LLMarketplaceData::getTestMarketplaceID() @@ -707,6 +764,7 @@ bool LLMarketplaceData::addListing(const LLUUID& folder_id) setListingID(folder_id,listing_id); update_marketplace_category(folder_id); + gInventory.notifyObservers(); return true; } @@ -729,6 +787,7 @@ bool LLMarketplaceData::associateListing(const LLUUID& folder_id, S32 listing_id setListingID(folder_id,listing_id); update_marketplace_category(folder_id); + gInventory.notifyObservers(); return true; } @@ -741,6 +800,7 @@ bool LLMarketplaceData::deleteListing(const LLUUID& folder_id) } mMarketplaceItems.erase(folder_id); update_marketplace_category(folder_id); + gInventory.notifyObservers(); return true; } @@ -842,6 +902,7 @@ bool LLMarketplaceData::setListingID(const LLUUID& folder_id, S32 listing_id) { (it->second).mListingId = listing_id; update_marketplace_category(folder_id); + gInventory.notifyObservers(); return true; } } @@ -861,6 +922,7 @@ bool LLMarketplaceData::setVersionFolderID(const LLUUID& folder_id, const LLUUID (it->second).mVersionFolderId = version_id; update_marketplace_category(old_version_id); update_marketplace_category(version_id); + gInventory.notifyObservers(); } return true; } @@ -874,6 +936,7 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); (it->second).mIsActive = activate; update_marketplace_category((it->second).mListingFolderId); + gInventory.notifyObservers(); return true; } // We need to iterate through the list to check it's not a version folder @@ -884,6 +947,7 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) { (it->second).mIsActive = activate; update_marketplace_category((it->second).mListingFolderId); + gInventory.notifyObservers(); return true; } it++; diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 42d76a1ba9..9e2dc871d6 100755 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -125,6 +125,7 @@ namespace SLMErrorCodes } class LLMarketplaceData; +class LLInventoryObserver; // A Marketplace item is known by its tuple class LLMarketplaceTuple @@ -153,6 +154,7 @@ class LLMarketplaceData { public: LLMarketplaceData(); + virtual ~LLMarketplaceData(); // SLM Public typedef boost::signals2::signal<void ()> status_updated_signal_t; @@ -188,6 +190,9 @@ public: bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id); bool setActivation(const LLUUID& folder_id, bool activate); + bool checkDirtyCount() { if (mDirtyCount) { mDirtyCount = false; return true; } else { return false; } } + void setDirtyCount() { mDirtyCount = true; } + // Merov : Test method while waiting for SLM API S32 getTestMarketplaceID(); @@ -199,6 +204,8 @@ private: U32 mMarketPlaceStatus; status_updated_signal_t * mStatusUpdatedSignal; + LLInventoryObserver* mInventoryObserver; + bool mDirtyCount; // Merov : This is for test only, waiting for SLM API S32 mTestCurrentMarketplaceID; |