master
Loren Shih 2009-11-11 14:34:06 -05:00
commit 0cc89785d6
8 changed files with 103 additions and 27 deletions

View File

@ -887,9 +887,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
}
// What we do here is get the complete information on the items in
// the inventory, and set up an observer that will wait for that to
// happen.
// Get the complete information on the items in the inventory and set up an observer
// that will trigger when the complete information is fetched.
LLInventoryFetchDescendentsObserver::folder_ref_t folders;
folders.push_back(current_outfit_id);
outfit->fetchDescendents(folders);

View File

@ -176,6 +176,7 @@ LLInventoryModel::LLInventoryModel()
mRootFolderID(),
mLibraryRootFolderID(),
mLibraryOwnerID(),
mIsNotifyObservers(FALSE),
mIsAgentInvUsable(false)
{
}
@ -537,7 +538,10 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
item_array,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
if (cat_array.empty() && item_array.empty())
{
return;
}
for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
cat_iter != cat_array.end();
cat_iter++)
@ -639,6 +643,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
new_item = old_item;
LLUUID old_parent_id = old_item->getParentUUID();
LLUUID new_parent_id = item->getParentUUID();
if(old_parent_id != new_parent_id)
{
// need to update the parent-child tree
@ -1133,6 +1138,16 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void LLInventoryModel::notifyObservers(const std::string service_name)
{
if (mIsNotifyObservers)
{
// Within notifyObservers, something called notifyObservers
// again. This type of recursion is unsafe because it causes items to be
// processed twice, and this can easily lead to infinite loops.
llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl;
return;
}
mIsNotifyObservers = TRUE;
llinfos << "Start process notifyObservers for " << this << llendl;
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
{
@ -1154,12 +1169,21 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
mModifyMask = LLInventoryObserver::NONE;
mChangedItemIDs.clear();
mIsNotifyObservers = FALSE;
}
// store flag for change
// and id of object change applies to
void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
{
if (mIsNotifyObservers)
{
// Something marked an item for change within a call to notifyObservers
// (which is in the process of processing the list of items marked for change).
// This means the change may fail to be processed.
llwarns << "Adding changed mask within notify observers! Change will likely be lost." << llendl;
}
mModifyMask |= mask;
if (referent.notNull())
{
@ -1833,13 +1857,13 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
{
//llinfos << "LLInventoryModel::addItem()" << llendl;
// This can happen if assettype enums change. This can be a backwards compatibility issue
// in some viewer prototypes prior to when the AT_LINK enum changed from 23 to 24.
// This can happen if assettype enums from llassettype.h ever change.
// For example, there is a known backwards compatibility issue in some viewer prototypes prior to when
// the AT_LINK enum changed from 23 to 24.
if ((item->getType() == LLAssetType::AT_NONE)
|| LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
{
llwarns << "Got bad asset type for item ( name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ), ignoring." << llendl;
llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl;
return;
}
if(item)
@ -1848,7 +1872,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
// The item will show up as a broken link.
if (item->getIsBrokenLink())
{
llinfos << "Adding broken link ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
}
mItemMap[item->getUUID()] = item;
}
@ -3307,6 +3331,12 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
for(i = 0; i < count; ++i)
{
titem->unpackMessage(msg, _PREHASH_ItemData, i);
// If the item has already been added (e.g. from link prefetch), then it doesn't need to be re-added.
if (gInventory.getItem(titem->getUUID()))
{
llinfos << "Skipping prefetched item [ Name: " << titem->getName() << " | Type: " << titem->getActualType() << " | ItemUUID: " << titem->getUUID() << " ] " << llendl;
continue;
}
gInventory.updateItem(titem);
}

View File

@ -473,23 +473,12 @@ protected:
cat_array_t* getUnlockedCatArray(const LLUUID& id);
item_array_t* getUnlockedItemArray(const LLUUID& id);
protected:
private:
// Variables used to track what has changed since the last notify.
U32 mModifyMask;
typedef std::set<LLUUID> changed_items_t;
changed_items_t mChangedItemIDs;
// Information for tracking the actual inventory. We index this
// information in a lot of different ways so we can access
// the inventory using several different identifiers.
// mInventory member data is the 'master' list of inventory, and
// mCategoryMap and mItemMap store uuid->object mappings.
typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
//inv_map_t mInventory;
cat_map_t mCategoryMap;
item_map_t mItemMap;
std::map<LLUUID, bool> mCategoryLock;
std::map<LLUUID, bool> mItemLock;
@ -525,6 +514,21 @@ protected:
// This flag is used to handle an invalid inventory state.
bool mIsAgentInvUsable;
private:
// Information for tracking the actual inventory. We index this
// information in a lot of different ways so we can access
// the inventory using several different identifiers.
// mInventory member data is the 'master' list of inventory, and
// mCategoryMap and mItemMap store uuid->object mappings.
typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
//inv_map_t mInventory;
cat_map_t mCategoryMap;
item_map_t mItemMap;
// Flag set when notifyObservers is being called, to look for bugs
// where it's called recursively.
BOOL mIsNotifyObservers;
public:
// *NOTE: DEBUG functionality
void dumpInventory() const;

View File

@ -49,7 +49,7 @@
#include "llviewermenu.h"
#include "llviewertexturelist.h"
static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
static LLDefaultChildRegistry::Register<LLPanelMainInventory> r("panel_main_inventory");
void on_file_loaded_for_save(BOOL success,
LLViewerFetchedTexture *src_vi,
@ -90,8 +90,8 @@ private:
/// LLPanelMainInventory
///----------------------------------------------------------------------------
LLPanelMainInventory::LLPanelMainInventory()
: LLPanel(),
LLPanelMainInventory::LLPanelMainInventory(const LLPanelMainInventory::Params& p)
: LLPanel(p),
mActivePanel(NULL),
mSavedFolderState(NULL),
mFilterText(""),
@ -124,6 +124,24 @@ LLPanelMainInventory::LLPanelMainInventory()
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
if (p.hide_top_menu)
{
LLInventoryPanel *top_panel = getChild<LLInventoryPanel>("top_panel");
if (top_panel)
{
top_panel->setVisible(FALSE);
}
}
if (p.hide_bottom_menu)
{
LLInventoryPanel *bottom_panel = getChild<LLInventoryPanel>("bottom_panel");
if (bottom_panel)
{
bottom_panel->setVisible(FALSE);
}
}
}
BOOL LLPanelMainInventory::postBuild()

View File

@ -58,7 +58,19 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
public:
friend class LLFloaterInventoryFinder;
LLPanelMainInventory();
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<bool> hide_top_menu;
Optional<bool> hide_bottom_menu;
Params() :
hide_top_menu("hide_top_menu", false),
hide_bottom_menu("hide_bottom_menu", false)
{}
};
LLPanelMainInventory(const Params&);
~LLPanelMainInventory();
BOOL postBuild();

View File

@ -36,10 +36,10 @@
filename="panel_main_inventory.xml"
follows="all"
layout="topleft"
hide_top_panel="true"
left="0"
label="Inventory Panel"
name="Inventory Panel"
top="15"
width="467">
</panel>
width="467" />
</floater>

View File

@ -103,6 +103,17 @@
width="18" />
</panel>
<panel
background_visible="true"
bevel_style="none"
bottom="0"
follows="left|right|bottom"
height="30"
layout="bottomleft"
left="0"
visible="true"
name="top_panel"
width="330">
<menu_bar
bg_visible="false"
follows="left|top|right"
@ -464,4 +475,5 @@
</menu_item_check>
</menu>
</menu_bar>
</panel>
</panel>

View File

@ -24,6 +24,7 @@
filename="panel_main_inventory.xml"
follows="all"
layout="topleft"
hide_top_panel="true"
left="0"
name="panel_main_inventory"
top="0"