MAINT-4917 WIP - Attachment deferred bulk COF linking WIP
parent
8169cde890
commit
090d3097d5
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue