summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2014-05-01 17:36:17 -0700
committerMerov Linden <merov@lindenlab.com>2014-05-01 17:36:17 -0700
commit87192990592f9abda8314393bdcac3627c15d5ac (patch)
tree066035a26ea60c8ab6b203559377e060c4b1fd9d
parent7df858622bf379781246f23445f86ead4ad3288a (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-xindra/newview/llfloatermarketplacelistings.cpp4
-rwxr-xr-xindra/newview/llinventoryfunctions.cpp97
-rwxr-xr-xindra/newview/llinventoryfunctions.h4
-rwxr-xr-xindra/newview/llinventorymodel.cpp15
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp66
-rwxr-xr-xindra/newview/llmarketplacefunctions.h7
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;