MAINT-4917 WIP - Attachment deferred bulk COF linking WIP

meow-7.2.2
Brad Payne (Vir Linden) 2015-03-18 21:41:47 -04:00
parent 8169cde890
commit 090d3097d5
8 changed files with 141 additions and 160 deletions

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llagentwearables.h"
#include "llattachmentsmgr.h"
#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentcamera.h"
@ -1373,55 +1374,16 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
S32 obj_count = obj_item_array.size();
if (obj_count > 0)
{
LL_DEBUGS("Avatar") << "ATT [RezMultipleAttachmentsFromInv] attaching multiple, total obj_count " << obj_count << LL_ENDL;
LL_DEBUGS("Avatar") << "ATT attaching multiple, total obj_count " << obj_count << LL_ENDL;
}
// Limit number of packets to send
const S32 MAX_PACKETS_TO_SEND = 10;
const S32 OBJECTS_PER_PACKET = 4;
const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
if( obj_count > MAX_OBJECTS_TO_SEND )
{
obj_count = MAX_OBJECTS_TO_SEND;
}
// Create an id to keep the parts of the compound message together
LLUUID compound_msg_id;
compound_msg_id.generate();
LLMessageSystem* msg = gMessageSystem;
for(S32 i = 0; i < obj_count; ++i)
{
if( 0 == (i % OBJECTS_PER_PACKET) )
{
// Start a new message chunk
msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_HeaderData);
msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
msg->addBOOLFast(_PREHASH_FirstDetachAll, false );
}
const LLInventoryItem* item = obj_item_array.at(i).get();
LL_DEBUGS("Avatar") << "ATT requesting " << item->getName()
<< " " << item->getLinkedUUID() << LL_ENDL;
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD); // Wear at the previous or default attachment point
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
msg->addStringFast(_PREHASH_Name, item->getName());
msg->addStringFast(_PREHASH_Description, item->getDescription());
if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
{
// End of message chunk
msg->sendReliable( gAgent.getRegion()->getHost() );
}
}
for(LLInventoryModel::item_array_t::const_iterator it = obj_item_array.begin();
it != obj_item_array.end();
++it)
{
const LLInventoryItem* item = *it;
LLAttachmentsMgr::instance().addAttachmentRequest(item->getLinkedUUID(), 0, TRUE);
}
}
// Returns false if the given wearable is already topmost/bottommost

View File

@ -525,7 +525,7 @@ LLUpdateAppearanceAndEditWearableOnDestroy::LLUpdateAppearanceAndEditWearableOnD
{
}
LLRequestAppearanceUpdateOnDestroy::~LLRequestAppearanceUpdateOnDestroy()
LLRequestServerAppearanceUpdateOnDestroy::~LLRequestServerAppearanceUpdateOnDestroy()
{
LL_DEBUGS("Avatar") << "ATT requesting server appearance update" << LL_ENDL;
LLAppearanceMgr::instance().requestServerAppearanceUpdate();
@ -3925,24 +3925,7 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
<< (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL;
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
if (mAttachmentInvLinkEnabled)
{
// we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF.
// it will trigger gAgentWariables.notifyLoadingFinished()
// But it is not acceptable solution. See EXT-7777
if (!isLinkedInCOF(item_id))
{
LL_DEBUGS("Avatar") << "ATT adding COF link for attachment "
<< (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL;
// FIXME replace with just a call to request bake update?
LLPointer<LLInventoryCallback> cb = new LLRequestAppearanceUpdateOnDestroy();
LLAppearanceMgr::addCOFItemLink(item_id, cb); // Add COF link for item.
}
}
else
{
//LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
}
LLAttachmentsMgr::instance().onAttachmentArrived(item_id);
}
void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)

View File

@ -306,11 +306,11 @@ private:
LLUUID mItemID;
};
class LLRequestAppearanceUpdateOnDestroy: public LLInventoryCallback
class LLRequestServerAppearanceUpdateOnDestroy: public LLInventoryCallback
{
public:
LLRequestAppearanceUpdateOnDestroy() {}
~LLRequestAppearanceUpdateOnDestroy();
LLRequestServerAppearanceUpdateOnDestroy() {}
~LLRequestServerAppearanceUpdateOnDestroy();
/* virtual */ void fire(const LLUUID& item_id) {}
};

View File

@ -44,9 +44,9 @@ LLAttachmentsMgr::~LLAttachmentsMgr()
{
}
void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
const U8 attachment_pt,
const BOOL add)
void LLAttachmentsMgr::addAttachmentRequest(const LLUUID& item_id,
const U8 attachment_pt,
const BOOL add)
{
LLViewerInventoryItem *item = gInventory.getItem(item_id);
LL_DEBUGS("Avatar") << "ATT adding attachment to mPendingAttachments "
@ -57,6 +57,8 @@ void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
attachment.mAttachmentPt = attachment_pt;
attachment.mAdd = add;
mPendingAttachments.push_back(attachment);
addAttachmentRequestTime(item_id);
}
// static
@ -73,7 +75,9 @@ void LLAttachmentsMgr::onIdle()
return;
}
linkPendingAttachments();
requestPendingAttachments();
linkRecentlyArrivedAttachments();
}
class LLAttachAfterLinkCallback: public LLInventoryCallback
@ -111,39 +115,58 @@ private:
LLAttachmentsMgr::attachments_vec_t mToLinkAndAttach;
};
//#define COF_LINK_FIRST
void LLAttachmentsMgr::linkPendingAttachments()
void LLAttachmentsMgr::requestPendingAttachments()
{
if (mPendingAttachments.size())
{
#ifdef COF_LINK_FIRST
LLPointer<LLInventoryCallback> cb = new LLAttachAfterLinkCallback(mPendingAttachments);
LLInventoryObject::const_object_list_t inv_items_to_link;
LL_DEBUGS("Avatar") << "ATT requesting COF links for " << mPendingAttachments.size() << " object(s):" << LL_ENDL;
for (attachments_vec_t::const_iterator it = mPendingAttachments.begin();
it != mPendingAttachments.end(); ++it)
{
const AttachmentsInfo& att_info = *it;
LLViewerInventoryItem *item = gInventory.getItem(att_info.mItemID);
if (item)
{
LL_DEBUGS("Avatar") << "ATT - requesting COF link for " << item->getName() << LL_ENDL;
inv_items_to_link.push_back(item);
}
else
{
LL_WARNS() << "ATT unable to link requested attachment " << att_info.mItemID
<< ", item not found in inventory" << LL_ENDL;
}
}
link_inventory_array(LLAppearanceMgr::instance().getCOF(), inv_items_to_link, cb);
#else
requestAttachments(mPendingAttachments);
#endif
mPendingAttachments.clear();
}
}
void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
{
const F32 COF_LINK_BATCH_TIME = 5.0F;
// One or more attachments have arrived but not been processed for COF links
if (mRecentlyArrivedAttachments.size())
{
if (mAttachmentRequests.empty())
{
// Not waiting for more
LL_DEBUGS("Avatar") << "ATT all pending attachments have arrived" << LL_ENDL;
}
else if (mCOFLinkBatchTimer.getElapsedTimeF32() > COF_LINK_BATCH_TIME)
{
LL_DEBUGS("Avatar") << mAttachmentRequests.size()
<< "ATT pending attachments have not arrived but wait time exceeded" << LL_ENDL;
}
else
{
return;
}
LL_DEBUGS("Avatar") << "ATT requesting COF links for " << mRecentlyArrivedAttachments.size() << LL_ENDL;
LLInventoryObject::const_object_list_t inv_items_to_link;
for (std::set<LLUUID>::iterator it = mRecentlyArrivedAttachments.begin();
it != mRecentlyArrivedAttachments.end(); ++it)
{
if (!LLAppearanceMgr::instance().isLinkedInCOF(*it))
{
LLUUID item_id = *it;
LLViewerInventoryItem *item = gInventory.getItem(item_id);
LL_DEBUGS("Avatar") << "ATT adding COF link for attachment "
<< (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL;
inv_items_to_link.push_back(item);
}
}
if (inv_items_to_link.size())
{
LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
link_inventory_array(LLAppearanceMgr::instance().getCOF(), inv_items_to_link, cb);
}
mRecentlyArrivedAttachments.clear();
}
}
// FIXME this is basically the same code as LLAgentWearables::userAttachMultipleAttachments(),
@ -225,3 +248,53 @@ void LLAttachmentsMgr::requestAttachments(const attachments_vec_t& attachment_re
i++;
}
}
void LLAttachmentsMgr::addAttachmentRequestTime(const LLUUID& inv_item_id)
{
LLInventoryItem *item = gInventory.getItem(inv_item_id);
LL_DEBUGS("Avatar") << "ATT add request time " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL;
LLTimer current_time;
mAttachmentRequests[inv_item_id] = current_time;
}
void LLAttachmentsMgr::removeAttachmentRequestTime(const LLUUID& inv_item_id)
{
LLInventoryItem *item = gInventory.getItem(inv_item_id);
LL_DEBUGS("Avatar") << "ATT remove request time " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL;
mAttachmentRequests.erase(inv_item_id);
}
BOOL LLAttachmentsMgr::attachmentWasRequestedRecently(const LLUUID& inv_item_id, F32 seconds) const
{
std::map<LLUUID,LLTimer>::const_iterator it = mAttachmentRequests.find(inv_item_id);
if (it != mAttachmentRequests.end())
{
const LLTimer& request_time = it->second;
F32 request_time_elapsed = request_time.getElapsedTimeF32();
if (request_time_elapsed > seconds)
{
LLInventoryItem *item = gInventory.getItem(inv_item_id);
LL_DEBUGS("Avatar") << "ATT time ignored, exceeded " << seconds
<< " " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL;
return FALSE;
}
else
{
return TRUE;
}
}
else
{
return FALSE;
}
}
void LLAttachmentsMgr::onAttachmentArrived(const LLUUID& inv_item_id)
{
removeAttachmentRequestTime(inv_item_id);
if (mRecentlyArrivedAttachments.empty())
{
mCOFLinkBatchTimer.reset();
}
mRecentlyArrivedAttachments.insert(inv_item_id);
}

View File

@ -60,18 +60,31 @@ public:
LLAttachmentsMgr();
virtual ~LLAttachmentsMgr();
void addAttachment(const LLUUID& item_id,
const U8 attachment_pt,
const BOOL add);
void addAttachmentRequest(const LLUUID& item_id,
const U8 attachment_pt,
const BOOL add);
void requestAttachments(const attachments_vec_t& attachment_requests);
static void onIdle(void *);
protected:
void onIdle();
void linkPendingAttachments();
BOOL attachmentWasRequestedRecently(const LLUUID& inv_item_id, F32 seconds) const;
void addAttachmentRequestTime(const LLUUID& inv_item_id);
void onAttachmentArrived(const LLUUID& inv_item_id);
private:
void removeAttachmentRequestTime(const LLUUID& inv_item_id);
void onIdle();
void requestPendingAttachments();
void linkRecentlyArrivedAttachments();
// Attachments that we are planning to rez but haven't requested from the server yet.
attachments_vec_t mPendingAttachments;
// Attachments that have been requested from server but have not arrived yet.
std::map<LLUUID,LLTimer> mAttachmentRequests;
// Attachments that have arrived but have not been linked in the COF yet.
std::set<LLUUID> mRecentlyArrivedAttachments;
LLTimer mCOFLinkBatchTimer;
};
#endif

View File

@ -5367,17 +5367,15 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
const LLUUID& item_id = item->getLinkedUUID();
// Check for duplicate request.
const F32 MAX_TIME_SINCE_REQUEST = 5.0F;
if (isAgentAvatarValid() &&
(gAgentAvatarp->attachmentWasRequested(item_id) ||
(LLAttachmentsMgr::instance().attachmentWasRequestedRecently(item_id, MAX_TIME_SINCE_REQUEST) ||
gAgentAvatarp->isWearingAttachment(item_id)))
{
LL_WARNS() << "ATT duplicate attachment request, ignoring" << LL_ENDL;
return;
}
LL_DEBUGS("Avatar") << "ATT add rez request for " << item->getName() << " id " << item_id << LL_ENDL;
gAgentAvatarp->addAttachmentRequest(item_id);
S32 attach_pt = 0;
if (isAgentAvatarValid() && attachment)
{
@ -5432,10 +5430,8 @@ bool confirm_attachment_rez(const LLSD& notification, const LLSD& response)
U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
BOOL is_add = notification["payload"]["is_add"].asBoolean();
LL_DEBUGS("Avatar") << "ATT calling addAttachment " << (itemp ? itemp->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
LLAttachmentsMgr::instance().addAttachment(item_id,
attachment_pt,
is_add);
LL_DEBUGS("Avatar") << "ATT calling addAttachmentRequest " << (itemp ? itemp->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
LLAttachmentsMgr::instance().addAttachmentRequest(item_id, attachment_pt, is_add);
}
}
return false;

View File

@ -38,6 +38,7 @@
#include "pipeline.h"
#include "llagent.h" // Get state values from here
#include "llattachmentsmgr.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llhudeffecttrail.h"
@ -1050,44 +1051,6 @@ BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const
return FALSE;
}
//-----------------------------------------------------------------------------
BOOL LLVOAvatarSelf::attachmentWasRequested(const LLUUID& inv_item_id) const
{
const F32 REQUEST_EXPIRATION_SECONDS = 5.0; // any request older than this is ignored/removed.
std::map<LLUUID,LLTimer>::iterator it = mAttachmentRequests.find(inv_item_id);
if (it != mAttachmentRequests.end())
{
const LLTimer& request_time = it->second;
F32 request_time_elapsed = request_time.getElapsedTimeF32();
if (request_time_elapsed > REQUEST_EXPIRATION_SECONDS)
{
mAttachmentRequests.erase(it);
return FALSE;
}
else
{
return TRUE;
}
}
else
{
return FALSE;
}
}
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::addAttachmentRequest(const LLUUID& inv_item_id)
{
LLTimer current_time;
mAttachmentRequests[inv_item_id] = current_time;
}
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::removeAttachmentRequest(const LLUUID& inv_item_id)
{
mAttachmentRequests.erase(inv_item_id);
}
//-----------------------------------------------------------------------------
// getWornAttachment()
//-----------------------------------------------------------------------------
@ -1154,8 +1117,6 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
{
const LLUUID& attachment_id = viewer_object->getAttachmentItemID();
LLAppearanceMgr::instance().registerAttachment(attachment_id);
// Clear any pending requests once the attachment arrives.
removeAttachmentRequest(attachment_id);
updateLODRiggedAttachments();
}

View File

@ -289,19 +289,12 @@ protected:
public:
void updateAttachmentVisibility(U32 camera_mode);
BOOL isWearingAttachment(const LLUUID& inv_item_id) const;
BOOL attachmentWasRequested(const LLUUID& inv_item_id) const;
void addAttachmentRequest(const LLUUID& inv_item_id);
void removeAttachmentRequest(const LLUUID& inv_item_id);
LLViewerObject* getWornAttachment(const LLUUID& inv_item_id);
bool getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const;
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
private:
// Track attachments that have been requested but have not arrived yet.
mutable std::map<LLUUID,LLTimer> mAttachmentRequests;
//--------------------------------------------------------------------
// HUDs
//--------------------------------------------------------------------