meow-7.2.2
Nyx Linden 2013-06-26 17:57:40 -04:00
commit f388b32137
11 changed files with 165 additions and 96 deletions

View File

@ -440,8 +440,9 @@ void AISUpdate::doUpdate()
LLViewerInventoryCategory *cat = gInventory.getCategory(id);
if (cat->getVersion() != version)
{
llwarns << "Possible version mismatch, viewer " << cat->getVersion()
<< " server " << version << llendl;
llwarns << "Possible version mismatch for category " << cat->getName()
<< ", viewer version " << cat->getVersion()
<< " server version " << version << llendl;
}
}

View File

@ -53,6 +53,7 @@
#include "llsdutil.h"
#include "llsdserialize.h"
#include "llhttpretrypolicy.h"
#include "llaisapi.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@ -1449,6 +1450,58 @@ void LLAppearanceMgr::shallowCopyCategory(const LLUUID& src_id, const LLUUID& ds
gInventory.notifyObservers();
}
void LLAppearanceMgr::copyCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
bool include_folder_links, LLPointer<LLInventoryCallback> cb)
{
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
LLSD contents = LLSD::emptyArray();
gInventory.getDirectDescendentsOf(src_id, cats, items);
llinfos << "copying " << items->count() << " items" << llendl;
for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
iter != items->end();
++iter)
{
const LLViewerInventoryItem* item = (*iter);
switch (item->getActualType())
{
case LLAssetType::AT_LINK:
{
LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << llendl;
//getActualDescription() is used for a new description
//to propagate ordering information saved in descriptions of links
LLSD item_contents;
item_contents["name"] = item->getName();
item_contents["desc"] = item->getActualDescription();
item_contents["linked_id"] = item->getLinkedUUID();
item_contents["type"] = LLAssetType::AT_LINK;
contents.append(item_contents);
break;
}
case LLAssetType::AT_LINK_FOLDER:
{
LLViewerInventoryCategory *catp = item->getLinkedCategory();
if (catp && include_folder_links)
{
LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << llendl;
LLSD base_contents;
base_contents["name"] = catp->getName();
base_contents["desc"] = ""; // categories don't have descriptions.
base_contents["linked_id"] = catp->getLinkedUUID();
base_contents["type"] = LLAssetType::AT_LINK_FOLDER;
contents.append(base_contents);
}
break;
}
default:
{
// Linux refuses to compile unless all possible enums are handled. Really, Linux?
break;
}
}
}
slam_inventory_folder(dst_id, contents, cb);
}
// Copy contents of src_id to dst_id.
void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb)
@ -1466,6 +1519,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
{
case LLAssetType::AT_LINK:
{
LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << llendl;
//getActualDescription() is used for a new description
//to propagate ordering information saved in descriptions of links
link_inventory_item(gAgent.getID(),
@ -1482,6 +1536,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
// Skip copying outfit links.
if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT)
{
LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << llendl;
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
dst_id,
@ -1496,7 +1551,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_GESTURE:
{
llinfos << "copying inventory item " << item->getName() << llendl;
LL_DEBUGS("Avatar") << "copying inventory item " << item->getName() << llendl;
copy_inventory_item(gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),
@ -2815,11 +2870,14 @@ bool LLAppearanceMgr::updateBaseOutfit()
llassert(!isOutfitLocked());
return false;
}
setOutfitLocked(true);
gAgentWearables.notifyLoadingStarted();
const LLUUID base_outfit_id = getBaseOutfitUUID();
LL_DEBUGS("Avatar") << "updating base outfit to " << base_outfit_id << llendl;
if (base_outfit_id.isNull()) return false;
updateClothingOrderingInfo();
@ -3334,12 +3392,14 @@ void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
return;
}
LL_DEBUGS("Avatar") << "called" << llendl;
LLSD key;
//EXT-7727. For new accounts inventory callback is created during login process
// and may be processed after login process is finished
if (show_panel)
{
LL_DEBUGS("Avatar") << "showing panel" << llendl;
LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
}
@ -3358,32 +3418,59 @@ void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
// link, since, the COF version has changed. There is a race
// condition in initial outfit setup which can lead to rez
// failures - SH-3860.
LL_DEBUGS("Avatar") << "requesting appearance update after createBaseOutfitLink" << llendl;
LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb);
}
LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
void LLAppearanceMgr::onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel)
{
if (!isAgentAvatarValid()) return LLUUID::null;
LLPointer<LLInventoryCallback> cb =
new LLBoostFuncInventoryCallback(no_op_inventory_func,
boost::bind(&LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered,this,folder_id,show_panel));
updateClothingOrderingInfo(LLUUID::null, false, cb);
}
void LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel)
{
LLPointer<LLInventoryCallback> cb =
new LLBoostFuncInventoryCallback(no_op_inventory_func,
boost::bind(show_created_outfit,folder_id,show_panel));
bool copy_folder_links = false;
copyCategoryLinks(getCOF(), folder_id, copy_folder_links, cb);
}
void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
{
if (!isAgentAvatarValid()) return;
LL_DEBUGS("Avatar") << "creating new outfit" << llendl;
gAgentWearables.notifyLoadingStarted();
// First, make a folder in the My Outfits directory.
const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
LLUUID folder_id = gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name);
updateClothingOrderingInfo();
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,
boost::bind(show_created_outfit,folder_id,show_panel));
shallowCopyCategoryContents(getCOF(),folder_id, cb);
dumpCat(folder_id,"COF, new outfit");
return folder_id;
std::string cap;
if (AISCommand::getCap(cap))
{
// cap-based category creation was buggy until recently. use
// existence of AIS as an indicator the fix is present. Does
// not actually use AIS to create the category.
inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
LLUUID folder_id = gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name,
func);
}
else
{
LLUUID folder_id = gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name);
onOutfitFolderCreated(folder_id, show_panel);
}
}
void LLAppearanceMgr::wearBaseOutfit()

View File

@ -73,6 +73,10 @@ public:
void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb);
S32 getActiveCopyOperations() const;
// Copy all links via the slam command (single inventory operation where supported)
void copyCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
bool include_folder_links, LLPointer<LLInventoryCallback> cb);
// Copy all items and the src category itself.
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
@ -186,7 +190,9 @@ public:
void removeItemFromAvatar(const LLUUID& item_id);
LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
void onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel);
void makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel = true);
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);

View File

@ -162,21 +162,17 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
{
parent_category_id = gInventory.getRootFolderID();
}
LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear);
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLFolderType::FT_NONE,
name,
callbackCreateInventoryCategory,
(void*)cat_data);
func);
//If we get a null category ID, we are using a capability in createNewCategory and we will
//handle the following in the callbackCreateInventoryCategory routine.
if ( category_id.notNull() )
{
delete cat_data;
LLCatAndWear* data = new LLCatAndWear;
data->mCatID = category_id;
data->mWear = wear;
@ -198,20 +194,17 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
}
// static
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear)
{
LLCategoryCreate* cat_data = (LLCategoryCreate*)data;
LLUUID category_id = result["folder_id"].asUUID();
LLCatAndWear* wear_data = new LLCatAndWear;
wear_data->mCatID = category_id;
wear_data->mWear = cat_data->mWear;
wear_data->mWear = wear;
wear_data->mFolderResponded = true;
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE,
BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
callbackMoveInventory,
(void*)wear_data);
if (!success)
@ -221,7 +214,6 @@ void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, vo
LLNotificationsUtil::add("OpenObjectCannotCopy");
}
delete cat_data;
}
// static

View File

@ -45,15 +45,6 @@ public:
void dirty();
class LLCategoryCreate
{
public:
LLCategoryCreate(LLUUID object_id, bool wear) : mObjectID(object_id), mWear(wear) {}
public:
LLUUID mObjectID;
bool mWear;
};
struct LLCatAndWear
{
LLUUID mCatID;
@ -72,7 +63,7 @@ protected:
void onClickMoveToInventory();
void onClickMoveAndWear();
static void callbackCreateInventoryCategory(const LLSD& result, void* data);
static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear);
static void callbackMoveInventory(S32 result, void* data);
private:

View File

@ -472,11 +472,9 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
LOG_CLASS(LLCreateInventoryCategoryResponder);
public:
LLCreateInventoryCategoryResponder(LLInventoryModel* model,
void (*callback)(const LLSD&, void*),
void* user_data) :
mModel(model),
mCallback(callback),
mData(user_data)
boost::optional<inventory_func_type> callback):
mModel(model),
mCallback(callback)
{
}
@ -497,7 +495,7 @@ protected:
}
LLUUID category_id = content["folder_id"].asUUID();
LL_DEBUGS("Avatar") << ll_pretty_print_sd(content) << llendl;
// Add the category to the internal representation
LLPointer<LLViewerInventoryCategory> cat =
new LLViewerInventoryCategory( category_id,
@ -510,17 +508,15 @@ protected:
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
mModel->accountForUpdate(update);
mModel->updateCategory(cat);
if (mCallback && mData)
if (mCallback)
{
mCallback(content, mData);
mCallback.get()(category_id);
}
}
private:
void (*mCallback)(const LLSD&, void*);
void* mData;
boost::optional<inventory_func_type> mCallback;
LLInventoryModel* mModel;
};
@ -531,8 +527,7 @@ private:
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& pname,
void (*callback)(const LLSD&, void*), //Default to NULL
void* user_data) //Default to NULL
boost::optional<inventory_func_type> callback)
{
LLUUID id;
@ -559,33 +554,32 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type));
}
if ( callback && user_data ) //callback required for acked message.
LLViewerRegion* viewer_region = gAgent.getRegion();
std::string url;
if ( viewer_region )
url = viewer_region->getCapability("CreateInventoryCategory");
if (!url.empty() && callback.get_ptr())
{
LLViewerRegion* viewer_region = gAgent.getRegion();
std::string url;
if ( viewer_region )
url = viewer_region->getCapability("CreateInventoryCategory");
//Let's use the new capability.
if (!url.empty())
{
//Let's use the new capability.
LLSD request, body;
body["folder_id"] = id;
body["parent_id"] = parent_id;
body["type"] = (LLSD::Integer) preferred_type;
body["name"] = name;
request["message"] = "CreateInventoryCategory";
request["payload"] = body;
// viewer_region->getCapAPI().post(request);
LLHTTPClient::post(
url,
body,
new LLCreateInventoryCategoryResponder(this, callback, user_data) );
return LLUUID::null;
}
LLSD request, body;
body["folder_id"] = id;
body["parent_id"] = parent_id;
body["type"] = (LLSD::Integer) preferred_type;
body["name"] = name;
request["message"] = "CreateInventoryCategory";
request["payload"] = body;
LL_DEBUGS("Avatar") << "create category request: " << ll_pretty_print_sd(request) << llendl;
// viewer_region->getCapAPI().post(request);
LLHTTPClient::post(
url,
body,
new LLCreateInventoryCategoryResponder(this, callback) );
return LLUUID::null;
}
// Add the category to the internal representation

View File

@ -34,6 +34,7 @@
#include "llhttpclient.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llviewerinventory.h"
#include "llstring.h"
#include "llmd5.h"
#include <map>
@ -45,14 +46,9 @@ class LLInventoryObserver;
class LLInventoryObject;
class LLInventoryItem;
class LLInventoryCategory;
class LLViewerInventoryItem;
class LLViewerInventoryCategory;
class LLViewerInventoryItem;
class LLViewerInventoryCategory;
class LLMessageSystem;
class LLInventoryCollectFunctor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLInventoryModel
//
@ -394,8 +390,7 @@ public:
LLUUID createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& name,
void (*callback)(const LLSD&, void*) = NULL,
void* user_data = NULL );
boost::optional<inventory_func_type> callback = boost::optional<inventory_func_type>());
protected:
// Internal methods that add inventory and make sure that all of
// the internal data structures are consistent. These methods

View File

@ -184,7 +184,7 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD&
LLStringUtil::trim(outfit_name);
if( !outfit_name.empty() )
{
LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
LLSidepanelAppearance* panel_appearance = getAppearanceSP();
if (panel_appearance)

View File

@ -2613,10 +2613,10 @@ void LLStartUp::saveInitialOutfit()
if (sWearablesLoadedCon.connected())
{
lldebugs << "sWearablesLoadedCon is connected, disconnecting" << llendl;
LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << llendl;
sWearablesLoadedCon.disconnect();
}
lldebugs << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
}

View File

@ -69,8 +69,9 @@
#include "llclipboard.h"
#include "llhttpretrypolicy.h"
// Two do-nothing ops for use in callbacks.
// do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
void no_op_llsd_func(const LLSD&) {}
void no_op() {}
///----------------------------------------------------------------------------

View File

@ -263,9 +263,11 @@ private:
};
typedef boost::function<void(const LLUUID&)> inventory_func_type;
void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
typedef boost::function<void(const LLSD&)> llsd_func_type;
typedef boost::function<void()> nullary_func_type;
void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
void no_op_llsd_func(const LLSD&); // likewise for LLSD
void no_op(); // A do-nothing nullary func.
// Shim between inventory callback and boost function/callable