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;  | 
