Merge branch 'master' of git://github.com/Shyotl/SingularityViewer

This commit is contained in:
Inusaito Sayori
2015-08-12 14:52:52 -04:00
201 changed files with 10553 additions and 6878 deletions

View File

@@ -109,6 +109,7 @@ set(viewer_SOURCE_FILES
lggdicdownload.cpp
lgghunspell_wrapper.cpp
llaccountingcostmanager.cpp
llaisapi.cpp
llagent.cpp
llagentaccess.cpp
llagentcamera.cpp
@@ -296,6 +297,7 @@ set(viewer_SOURCE_FILES
llgroupnotify.cpp
llhomelocationresponder.cpp
llhoverview.cpp
llhttpretrypolicy.cpp
llhudeffect.cpp
llhudeffectbeam.cpp
llhudeffectlookat.cpp
@@ -521,6 +523,7 @@ set(viewer_SOURCE_FILES
llviewerobject.cpp
llviewerobjectbackup.cpp
llviewerobjectlist.cpp
llvieweroctree.cpp
llviewerparcelmedia.cpp
llviewerparcelmediaautoplay.cpp
llviewerparcelmgr.cpp
@@ -638,6 +641,7 @@ set(viewer_HEADER_FILES
lggdicdownload.h
lgghunspell_wrapper.h
llaccountingcostmanager.h
llaisapi.h
llagent.h
llagentaccess.h
llagentcamera.h
@@ -824,6 +828,7 @@ set(viewer_HEADER_FILES
llgroupactions.h
llgroupmgr.h
llgroupnotify.h
llhttpretrypolicy.h
llhomelocationresponder.h
llhoverview.h
llhudeffect.h
@@ -1055,6 +1060,7 @@ set(viewer_HEADER_FILES
llviewerobject.h
llviewerobjectbackup.h
llviewerobjectlist.h
llvieweroctree.h
llviewerparcelmedia.h
llviewerparcelmediaautoplay.h
llviewerparcelmgr.h

View File

@@ -24,7 +24,6 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llsdserialize.h"
#include "lldarray.h"
#include "llfile.h"
#include "llchat.h"
#include "llfloaterchat.h"

View File

@@ -16,7 +16,6 @@
#define ASCENT_CONTACT_GROUPS
#include "llfloater.h"
#include "lldarray.h"
#include "llsdserialize.h"
class LLScrollListCtrl;

View File

@@ -252,7 +252,7 @@ namespace
asset_id_matches);
// See if any of the inventory items matching this sculpt id are exportable
for (S32 i = 0; i < items.count(); i++)
for (S32 i = 0; i < items.size(); i++)
{
const LLPermissions item_permissions = items[i]->getPermissions();
if (item_permissions.allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()))
@@ -365,9 +365,9 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
LLViewerObject* o = *itero;
if (!o) continue;
LLDynamicArray<LLViewerObject*> prims = LLDynamicArray<LLViewerObject*>();
std::vector<LLViewerObject*> prims;
o->addThisAndAllChildren(prims);
for (LLDynamicArray<LLViewerObject*>::iterator iterc = prims.begin(); iterc != prims.end(); ++iterc)
for (std::vector<LLViewerObject* >::iterator iterc = prims.begin(); iterc != prims.end(); ++iterc)
{
const LLViewerObject* c = *iterc;
if (!c) continue;

View File

@@ -7383,7 +7383,7 @@
<param
id="868"
group="0"
group="3"
wearable="shirt"
edit_group="shirt"
edit_group_order="8"
@@ -8473,7 +8473,7 @@
<param
id="869"
group="0"
group="3"
wearable="pants"
edit_group="pants"
edit_group_order="6"
@@ -9391,7 +9391,7 @@
<param
id="163"
group="0"
group="3"
wearable="skin"
edit_group="skin_facedetail"
edit_group_order="3"
@@ -11449,7 +11449,7 @@
<param
id="877"
group="0"
group="3"
name="Jacket Wrinkles"
label="Jacket Wrinkles"
wearable="jacket"

View File

@@ -1320,7 +1320,7 @@ const LLUUID& LLFloaterAO::getAssetIDByName(const std::string& name)
ObjectNameMatches objectnamematches(name);
gInventory.collectDescendentsIf(LLUUID::null,cats,items,FALSE,objectnamematches);
if (items.count())
if (items.size())
{
return items[0]->getAssetUUID();
}

View File

@@ -369,7 +369,7 @@ std::vector<affected_object> LocalBitmap::getUsingObjects(bool seek_by_type, boo
{
std::vector<affected_object> affected_vector;
for( LLDynamicArrayPtr< LLPointer<LLViewerObject>, 256 >::iterator iter = gObjectList.mObjects.begin();
for (std::vector< LLPointer<LLViewerObject> >::iterator iter = gObjectList.mObjects.begin();
iter != gObjectList.mObjects.end(); iter++ )
{
LLViewerObject* obj = *iter;

View File

@@ -4475,11 +4475,12 @@ void LLAgent::fidget()
void LLAgent::stopFidget()
{
LLDynamicArray<LLUUID> anims;
anims.put(ANIM_AGENT_STAND_1);
anims.put(ANIM_AGENT_STAND_2);
anims.put(ANIM_AGENT_STAND_3);
anims.put(ANIM_AGENT_STAND_4);
std::vector<LLUUID> anims;
anims.reserve(4);
anims.push_back(ANIM_AGENT_STAND_1);
anims.push_back(ANIM_AGENT_STAND_2);
anims.push_back(ANIM_AGENT_STAND_3);
anims.push_back(ANIM_AGENT_STAND_4);
gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
}

View File

@@ -92,7 +92,7 @@ void LLAgentPilot::load(const std::string& filename)
file >> new_action.mTime >> action_type;
file >> new_action.mTarget.mdV[VX] >> new_action.mTarget.mdV[VY] >> new_action.mTarget.mdV[VZ];
new_action.mType = (EActionType)action_type;
mActions.put(new_action);
mActions.push_back(new_action);
}
file.close();
@@ -108,13 +108,14 @@ void LLAgentPilot::save(const std::string& filename)
LL_INFOS() << "Couldn't open " << filename << ", aborting agentpilot save!" << LL_ENDL;
}
file << mActions.count() << '\n';
file << mActions.size() << '\n';
S32 i;
for (i = 0; i < mActions.count(); i++)
for (i = 0; i < mActions.size(); i++)
{
file << mActions[i].mTime << "\t" << mActions[i].mType << "\t";
file << std::setprecision(32) << mActions[i].mTarget.mdV[VX] << "\t" << mActions[i].mTarget.mdV[VY] << "\t" << mActions[i].mTarget.mdV[VZ] << '\n';
file << std::setprecision(32) << mActions[i].mTarget.mdV[VX] << "\t" << mActions[i].mTarget.mdV[VY] << "\t" << mActions[i].mTarget.mdV[VZ];
file << '\n';
}
file.close();
@@ -122,7 +123,7 @@ void LLAgentPilot::save(const std::string& filename)
void LLAgentPilot::startRecord()
{
mActions.reset();
mActions.clear();
mTimer.reset();
addAction(STRAIGHT);
mRecording = TRUE;
@@ -143,7 +144,7 @@ void LLAgentPilot::addAction(enum EActionType action_type)
action.mTarget = gAgent.getPositionGlobal();
action.mTime = mTimer.getElapsedTimeF32();
mLastRecordTime = (F32)action.mTime;
mActions.put(action);
mActions.push_back(action);
}
void LLAgentPilot::startPlayback()
@@ -154,7 +155,7 @@ void LLAgentPilot::startPlayback()
mCurrentAction = 0;
mTimer.reset();
if (mActions.count())
if (mActions.size())
{
LL_INFOS() << "Starting playback, moving to waypoint 0" << LL_ENDL;
gAgent.startAutoPilotGlobal(mActions[0].mTarget);
@@ -183,7 +184,7 @@ void LLAgentPilot::updateTarget()
{
if (mPlaying)
{
if (mCurrentAction < mActions.count())
if (mCurrentAction < mActions.size())
{
if (0 == mCurrentAction)
{
@@ -208,7 +209,7 @@ void LLAgentPilot::updateTarget()
//gAgent.stopAutoPilot();
mCurrentAction++;
if (mCurrentAction < mActions.count())
if (mCurrentAction < mActions.size())
{
gAgent.startAutoPilotGlobal(mActions[mCurrentAction].mTarget);
}

View File

@@ -36,7 +36,6 @@
#include "stdtypes.h"
#include "lltimer.h"
#include "v3dmath.h"
#include "lldarray.h"
// Class that drives the agent around according to a "script".
@@ -92,7 +91,7 @@ private:
F64 mTime;
};
LLDynamicArray<Action> mActions;
std::vector<Action> mActions;
LLTimer mTimer;
};

View File

@@ -38,6 +38,7 @@
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllocaltextureobject.h"
#include "llpanelmaininventory.h"
#include "llmd5.h"
#include "llnotificationsutil.h"
@@ -56,8 +57,7 @@
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
#include "rlvhandler.h"
#include "rlvinventory.h"
#include "llattachmentsmgr.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#include "hippogridmanager.h"
@@ -97,7 +97,7 @@ void wear_and_edit_cb(const LLUUID& inv_item)
gAgentWearables.requestEditingWearable(inv_item);
// Wear it.
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item,true);
}
void wear_cb(const LLUUID& inv_item)
@@ -232,24 +232,15 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
llassert(avatar);
if (avatar)
{
avatar->outputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
if(!gHippoGridManager->getConnectedGrid()->isSecondLife())
{
avatar->outputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
}
setAvatarAppearance(avatar);
}
}
// wearables
LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
{
LL_INFOS() << "destructor - all done?" << LL_ENDL;
gAgentWearables.createStandardWearablesAllDone();
}
LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback()
{
gAgentWearables.sendAgentWearablesUpdate();
}
/**
* @brief Construct a callback for dealing with the wearables.
*
@@ -260,7 +251,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param wearable The wearable data.
* @param todo Bitmask of actions to take on completion.
*/
LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
LLAgentWearables::AddWearableToAgentInventoryCallback::AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :
mType(type),
mIndex(index),
@@ -272,13 +263,8 @@ LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInvento
LL_INFOS() << "constructor" << LL_ENDL;
}
void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
{
if (mTodo & CALL_CREATESTANDARDDONE)
{
LL_INFOS() << "callback fired, inv_item " << inv_item.asString() << LL_ENDL;
}
if (inv_item.isNull())
return;
@@ -290,24 +276,20 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
if (mTodo & CALL_RECOVERDONE)
{
LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
LLAppearanceMgr::instance().addCOFItemLink(inv_item);
gAgentWearables.recoverMissingWearableDone();
}
/*
* Do this for every one in the loop
*/
if (mTodo & CALL_CREATESTANDARDDONE)
{
LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
gAgentWearables.createStandardWearablesDone(mType, mIndex);
}
if (mTodo & CALL_MAKENEWOUTFITDONE)
{
gAgentWearables.makeNewOutfitDone(mType, mIndex);
}
if (mTodo & CALL_WEARITEM)
{
LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);
LLAppearanceMgr::instance().addCOFItemLink(inv_item,
new LLUpdateAppearanceOnDestroy(true, true, boost::bind(&edit_wearable_and_customize_avatar, inv_item)), mDescription);
}
}
@@ -320,7 +302,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
if (item_id.isNull())
return;
LLUUID old_item_id = getWearableItemID(type,index);
if (wearable)
@@ -328,7 +310,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
wearable->setItemID(item_id);
if (old_item_id.notNull())
{
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
setWearable(type,index,wearable);
}
@@ -341,7 +323,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
LLViewerInventoryItem* item = gInventory.getItem(item_id);
if(item && wearable)
if (item && wearable)
{
// We're changing the asset id, so we both need to set it
// locally via setAssetUUID() and via setTransactionID() which
@@ -367,12 +349,12 @@ void LLAgentWearables::sendAgentWearablesUpdate()
if (wearable->getItemID().isNull())
{
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
(LLWearableType::EType)type,
index,
wearable,
addWearableToAgentInventoryCallback::CALL_NONE);
AddWearableToAgentInventoryCallback::CALL_NONE);
addWearableToAgentInventory(cb, wearable);
}
else
@@ -470,23 +452,18 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
item->getFlags(),
item->getCreationDate());
template_item->setTransactionID(new_wearable->getTransactionID());
template_item->updateServer(FALSE);
gInventory.updateItem(template_item);
if (name_changed)
{
gInventory.notifyObservers();
}
update_inventory_item(template_item, gAgentAvatarp->mEndCustomizeCallback);
}
else
{
// Add a new inventory item (shouldn't ever happen here)
U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
U32 todo = AddWearableToAgentInventoryCallback::CALL_NONE;
if (send_update)
{
todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
todo |= AddWearableToAgentInventoryCallback::CALL_UPDATE;
}
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
@@ -539,12 +516,12 @@ LLViewerWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType t
trunc_description);
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
new_wearable,
addWearableToAgentInventoryCallback::CALL_WEARITEM,
AddWearableToAgentInventoryCallback::CALL_WEARITEM,
trunc_description
);
LLUUID category_id;
@@ -826,10 +803,13 @@ void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
// the versions themselves are compatible. This code can be removed before release.
if( wearable->getDefinitionVersion() == 24 )
{
wearable->setDefinitionVersion(22);
U32 index = getWearableIndex(wearable);
saveWearable(wearable->getType(),index,TRUE);
U32 index;
if (getWearableIndex(wearable,index))
{
LL_INFOS() << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << LL_ENDL;
wearable->setDefinitionVersion(22);
saveWearable(wearable->getType(),index,TRUE);
}
}
//Needed as wearable 'save' process is a mess and fires superfluous updateScrollingPanelList calls
@@ -881,11 +861,13 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_
if (mWearableDatas.end() != itWearableType)
{
for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin();
itWearable != itWearableType->second.end(); ++itWearable)
itWearable != itWearableType->second.end(); ++itWearable)
{
LLViewerWearable* wearable = dynamic_cast<LLViewerWearable*>(*itWearable);
if(wearable)
idItems.push_back(wearable->getItemID());
const LLViewerWearable* pWearable = dynamic_cast<LLViewerWearable*>(*itWearable);
if (pWearable)
{
idItems.push_back(pWearable->getItemID());
}
}
}
}
@@ -1033,12 +1015,12 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
// destory content.) JC
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
new_wearable,
addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
AddWearableToAgentInventoryCallback::CALL_RECOVERDONE);
addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE);
}
@@ -1081,17 +1063,17 @@ public:
/* virtual */ void fire(const LLUUID& inv_item)
{
LL_INFOS() << "One item created " << inv_item.asString() << LL_ENDL;
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
mItemsToLink.put(item);
LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item);
mItemsToLink.push_back(item);
updatePendingWearable(inv_item);
}
~OnWearableItemCreatedCB()
{
LL_INFOS() << "All items created" << LL_ENDL;
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
mItemsToLink,
link_waiter);
link_inventory_array(LLAppearanceMgr::instance().getCOF(),
mItemsToLink,
link_waiter);
}
void addPendingWearable(LLViewerWearable *wearable)
{
@@ -1140,7 +1122,7 @@ public:
}
private:
LLInventoryModel::item_array_t mItemsToLink;
LLInventoryObject::const_object_list_t mItemsToLink;
std::vector<LLViewerWearable*> mWearablesAwaitingItems;
};
@@ -1195,6 +1177,39 @@ void LLAgentWearables::createStandardWearables()
}
}
// We no longer need this message in the current viewer, but send
// it for now to maintain compatibility with release viewers. Can
// remove this function once the SH-3455 changesets are universally deployed.
void LLAgentWearables::sendDummyAgentWearablesUpdate()
{
LL_DEBUGS("Avatar") << "sendAgentWearablesUpdate()" << LL_ENDL;
// Send the AgentIsNowWearing
gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
// Send 4 standardized nonsense item ids (same as returned by the modified sim, not that it especially matters).
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(1));
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("db5a4e5f-9da3-44c8-992d-1181c5795498"));
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(2));
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("6969c7cc-f72f-4a76-a19b-c293cce8ce4f"));
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(3));
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("7999702b-b291-48f9-8903-c91dfb828408"));
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(4));
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("566cb59e-ef60-41d7-bfa6-e0f293fbea40"));
gAgent.sendReliableMessage();
}
void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index)
{
LL_INFOS() << "type " << type << " index " << index << LL_ENDL;
@@ -1335,7 +1350,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
//queryWearableCache(); // moved below
if (old_wearable)
{
popWearable(old_wearable);
eraseWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
}
}
@@ -1352,7 +1367,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
if (old_wearable)
{
popWearable(old_wearable);
eraseWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
}
}
@@ -1366,30 +1381,126 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
// Assumes existing wearables are not dirty.
void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
const LLDynamicArray< LLViewerWearable* >& wearables,
BOOL remove)
const std::vector< LLViewerWearable* >& wearables)
{
LL_INFOS() << "setWearableOutfit() start" << LL_ENDL;
// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later
if (remove)
S32 count = wearables.size();
llassert(items.size() == count);
// Check for whether outfit already matches the one requested
S32 matched = 0, mismatched = 0, local_updates = 0;
const S32 arr_size = LLWearableType::WT_COUNT;
S32 type_counts[arr_size];
std::fill(type_counts,type_counts+arr_size,0);
for (S32 i = 0; i < count; i++)
{
// note: shirt is the first non-body part wearable item. Update if wearable order changes.
// This loop should remove all clothing, but not any body parts
for (S32 type = 0; type < (S32)LLWearableType::WT_COUNT; type++)
LLViewerWearable* new_wearable = wearables[i];
LLPointer<LLInventoryItem> new_item = items[i];
const LLWearableType::EType type = new_wearable->getType();
if (type < 0 || type>=LLWearableType::WT_COUNT)
{
if (LLWearableType::getAssetType((LLWearableType::EType)type) == LLAssetType::AT_CLOTHING)
LL_WARNS() << "invalid type " << type << LL_ENDL;
mismatched++;
continue;
}
S32 index = type_counts[type];
type_counts[type]++;
LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type, index));
const LLUUID curr_id = curr_wearable ? curr_wearable->getItemID() : LLUUID::null;
const std::string curr_name = curr_wearable ? curr_wearable->getName() : std::string();
if (curr_id == new_item->getUUID()) //Nothing to do. No change..
{
matched++;
continue;
}
new_wearable->setName(new_item->getName());
new_wearable->setItemID(new_item->getUUID());
bool matching_asset = new_wearable && curr_wearable && new_wearable->getAssetID() == curr_wearable->getAssetID();
if (matching_asset || LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
{
//Simple replacement at index.
setWearable(type, index, new_wearable); //Stomp the old wearable, but don't increment mismatched. setWearable calls wearableUpdate.
if (new_wearable == curr_wearable) //If both new and cur are the same underlying wearable, then the old id got overwritten in the setItemId call above.
//Need to manually call addChangedMasked on the prior id.
{
removeWearable((LLWearableType::EType)type, true, 0);
gInventory.addChangedMask(LLInventoryObserver::LABEL, curr_id);
}
if (matching_asset)
local_updates++;
else
mismatched++; //Need to update visual parameters and such things.
continue;
}
else
{
LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index
<< " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << ","
<< " names " << (new_wearable ? new_wearable->getName() : "NONE") << LL_ENDL;
mismatched++;
continue;
}
// Don't care about this case - ordering of wearables with the same asset id has no effect.
// Causes the two-alphas error case in MAINT-4158.
// We should actually disallow wearing two wearables with the same asset id.
#if 0
if (curr_wearable->getName() != new_item->getName() ||
curr_wearable->getItemID() != new_item->getUUID())
{
LL_DEBUGS("Avatar") << "mismatch on name or inventory id, names "
<< curr_wearable->getName() << " vs " << new_item->getName()
<< " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID()
<< LL_ENDL;
mismatched++;
continue;
}
#endif
// If we got here, everything matches.
matched++;
}
LL_DEBUGS("Avatar") << "matched " << matched << " mismatched " << mismatched << LL_ENDL;
for (S32 j=0; j<LLWearableType::WT_COUNT; j++)
{
LLWearableType::EType type = (LLWearableType::EType) j;
if (getWearableCount(type) != type_counts[j])
{
LL_DEBUGS("Avatar") << "count mismatch for type " << j << " current " << getWearableCount(j) << " requested " << type_counts[j] << LL_ENDL;
mismatched++;
}
}
if (mismatched == 0)
{
LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL;
mCOFChangeInProgress = false;
if (local_updates)
{
LL_DEBUGS("Avatar") << "local_updates " << local_updates << " wearable itemIDs" << LL_ENDL;
gInventory.notifyObservers();
}
return;
}
// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later
// note: shirt is the first non-body part wearable item. Update if wearable order changes.
// This loop should remove all clothing, but not any body parts
for (S32 j = 0; j < (S32)LLWearableType::WT_COUNT; j++)
{
if (LLWearableType::getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING)
{
removeWearable((LLWearableType::EType)j, true, 0);
}
}
S32 count = wearables.count();
llassert(items.count() == count);
S32 i;
for (i = 0; i < count; i++)
for (S32 i = 0; i < count; i++)
{
LLViewerWearable* new_wearable = wearables[i];
LLPointer<LLInventoryItem> new_item = items[i];
@@ -1398,22 +1509,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (new_wearable)
{
const LLWearableType::EType type = new_wearable->getType();
new_wearable->setName(new_item->getName());
new_wearable->setDescription(new_item->getDescription());
new_wearable->setItemID(new_item->getUUID());
if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
if (LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING)
{
// exactly one wearable per body part
setWearable(type,0,new_wearable);
pushWearable(type,new_wearable); //pushWearable calls wearableUpdate.
}
else
{
pushWearable(type,new_wearable);
}
const BOOL removed = FALSE;
wearableUpdated(new_wearable, removed);
}
}
@@ -1422,6 +1522,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (isAgentAvatarValid())
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
gAgentAvatarp->writeWearablesToAvatar();
gAgentAvatarp->updateVisualParams();
// If we have not yet declouded, we may want to use
@@ -1442,7 +1543,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (!mInitialWearablesLoaded)
{
mInitialWearablesLoaded = true;
mInitialWearablesLoadedSignal();
}
// [/SL:KB]
notifyLoadingFinished();
@@ -1511,7 +1611,13 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD&
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
U32 index = gAgentWearables.getWearableIndex(wearable);
U32 index;
if (!gAgentWearables.getWearableIndex(wearable,index))
{
LL_WARNS() << "Wearable not found" << LL_ENDL;
delete wearable;
return false;
}
if( !new_item )
{
delete wearable;
@@ -1550,11 +1656,11 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWeara
if (do_append && getWearableItemID(type,0).notNull())
{
new_wearable->setItemID(new_item->getUUID());
/*mWearableDatas[type].push_back(new_wearable);
checkWearableAgainstInventory(new_wearable);*/
pushWearable(type,new_wearable); //To call LLAgentWearables::wearableUpdated
const bool trigger_updated = false;
pushWearable(type, new_wearable, trigger_updated);
LL_INFOS() << "Added additional wearable for type " << type
<< " size is now " << getWearableCount(type) << LL_ENDL;
checkWearableAgainstInventory(new_wearable);
}
else
{
@@ -1653,33 +1759,12 @@ void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
}
}
// User has picked "remove from avatar" from a menu.
// static
//void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
//{
// if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
// //!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
// {
// gAgentWearables.removeWearable(type,false,index);
// }
//}
//static
//void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &type)
//{
// if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
// //!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
// {
// gAgentWearables.removeWearable(type,true,0);
// }
//}
// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
//void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2)
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool attach_only)
// [/SL:KB]
/// Given a desired set of attachments, find what objects need to be
// removed, and what additional inventory items need to be added.
void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add)
{
// Possible cases:
// already wearing but not in request set -> take off.
@@ -1690,11 +1775,13 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
std::set<LLUUID> requested_item_ids;
std::set<LLUUID> current_item_ids;
for (S32 i=0; i<obj_item_array.count(); i++)
requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID());
for (S32 i=0; i<obj_item_array.size(); i++)
{
const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID();
//LL_INFOS() << "Requested attachment id " << requested_id << LL_ENDL;
requested_item_ids.insert(requested_id);
}
// Build up list of objects to be removed and items currently attached.
llvo_vec_t objects_to_remove;
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end();)
{
@@ -1708,22 +1795,33 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
if (objectp)
{
LLUUID object_item_id = objectp->getAttachmentItemID();
bool remove_attachment = true;
if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
{
// Object currently worn, was requested.
{ // Object currently worn, was requested to keep it
// Flag as currently worn so we won't have to add it again.
current_item_ids.insert(object_item_id);
remove_attachment = false;
}
else if (objectp->isTempAttachment())
{ // Check if we should keep this temp attachment
remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID());
}
if (remove_attachment)
{
// LL_INFOS() << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;
objects_to_remove.push_back(objectp);
}
else
{
// object currently worn, not requested.
objects_to_remove.push_back(objectp);
// LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;
current_item_ids.insert(object_item_id);
objects_to_retain.push_back(objectp);
}
}
}
}
LLInventoryModel::item_array_t items_to_add;
for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();
it != obj_item_array.end();
++it)
@@ -1742,18 +1840,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
// S32 remove_count = objects_to_remove.size();
// S32 add_count = items_to_add.size();
// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
// Remove everything in objects_to_remove
// userRemoveMultipleAttachments(objects_to_remove);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2)
if (!attach_only)
{
userRemoveMultipleAttachments(objects_to_remove);
}
// [/SL:KB]
// Add everything in items_to_add
userAttachMultipleAttachments(items_to_add);
}
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
@@ -1816,20 +1902,14 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
{
// Fall-back code: everything should really already have been pruned before we get this far
for (S32 idxItem = obj_item_array.count() - 1; idxItem >= 0; idxItem--)
{
const LLInventoryItem* pItem = obj_item_array.get(idxItem).get();
if (!gRlvAttachmentLocks.canAttach(pItem))
{
obj_item_array.remove(idxItem);
RLV_ASSERT(false);
}
}
LLInventoryModel::item_array_t::size_type cntAttach = obj_item_array.size();
obj_item_array.erase(std::remove_if(obj_item_array.begin(), obj_item_array.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_item_array.end());
RLV_ASSERT(cntAttach == obj_item_array.size());
}
// [/RLVa:KB]
// Build a compound message to send all the objects that need to be rezzed.
S32 obj_count = obj_item_array.count();
S32 obj_count = obj_item_array.size();
// Limit number of packets to send
const S32 MAX_PACKETS_TO_SEND = 10;
@@ -1860,7 +1940,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->addBOOLFast(_PREHASH_FirstDetachAll, false );
}
const LLInventoryItem* item = obj_item_array.get(i).get();
const LLInventoryItem* item = obj_item_array.at(i).get();
bool replace = !gHippoGridManager->getConnectedGrid()->supportsInvLinks();
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
@@ -1938,7 +2018,7 @@ bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) co
return !(((type == LLWearableType::WT_SHAPE) || (type == LLWearableType::WT_SKIN) || (type == LLWearableType::WT_HAIR) || (type == LLWearableType::WT_EYES))
&& (getWearableCount(type) <= 1) );
}
void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
void LLAgentWearables::animateAllWearableParams(F32 delta, bool upload_bake)
{
for( S32 type = 0; type < LLWearableType::WT_COUNT; ++type )
{
@@ -2012,7 +2092,16 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(wear ? wear_and_edit_cb : wear_cb);
LLPointer<LLInventoryCallback> cb;
if(wear)
{
cb = new LLBoostFuncInventoryCallback(wear_and_edit_cb);
}
else
{
cb = new LLBoostFuncInventoryCallback(wear_cb);
}
LLUUID folder_id;
if (parent_id.notNull())
@@ -2031,8 +2120,7 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
asset_type,
inv_type,
asset_type, inv_type,
wearable->getType(),
LLFloaterPerms::getNextOwnerPerms("Wearables"),
cb);
@@ -2118,13 +2206,6 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_
return mLoadedSignal.connect(cb);
}
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(loaded_callback_t cb)
{
return mInitialWearablesLoadedSignal.connect(cb);
}
// [/SL:KB]
bool LLAgentWearables::changeInProgress() const
{
return mCOFChangeInProgress;
@@ -2133,6 +2214,7 @@ bool LLAgentWearables::changeInProgress() const
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;
mCOFChangeTimer.reset();
mLoadingStartedSignal();
}

View File

@@ -80,6 +80,7 @@ public:
bool areInitalWearablesLoaded() const { return mInitialWearablesLoaded; }
// [/SL:KB]
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
F32 getCOFChangeTime() const { return mCOFChangeTimer.getElapsedTimeF32(); }
void updateWearablesLoaded();
void checkWearablesLoaded() const;
bool canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;
@@ -87,7 +88,7 @@ public:
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
bool canWearableBeRemoved(const LLViewerWearable* wearable) const;
void animateAllWearableParams(F32 delta, BOOL upload_bake);
void animateAllWearableParams(F32 delta, bool upload_bake = false);
//--------------------------------------------------------------------
// Accessors
@@ -114,7 +115,7 @@ private:
/*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed);
public:
// void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const std::vector< LLViewerWearable* >& wearables);
void setWearableName(const LLUUID& item_id, const std::string& new_name);
void nameOrDescriptionChanged(LLUUID const& item_id);
// *TODO: Move this into llappearance/LLWearableData ?
@@ -198,6 +199,11 @@ public:
void saveAllWearables();
void revertWearable(const LLWearableType::EType type, const U32 index);
// We no longer need this message in the current viewer, but send
// it for now to maintain compatibility with release viewers. Can
// remove this function once the SH-3455 changesets are universally deployed.
void sendDummyAgentWearablesUpdate();
//--------------------------------------------------------------------
// Static UI hooks
//--------------------------------------------------------------------
@@ -207,11 +213,10 @@ public:
typedef std::vector<LLViewerObject*> llvo_vec_t;
// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
// Not the best way to go about this but other attempts changed far too much LL code to be a viable solution
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
// [/SL:KB]
static void findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
@@ -229,9 +234,6 @@ public:
typedef boost::function<void()> loaded_callback_t;
typedef boost::signals2::signal<void()> loaded_signal_t;
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
boost::signals2::connection addInitialWearablesLoadedCallback(loaded_callback_t cb);
// [/SL:KB]
bool changeInProgress() const;
void notifyLoadingStarted();
@@ -240,9 +242,6 @@ public:
private:
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
loaded_signal_t mInitialWearablesLoadedSignal; // emitted once when the initial wearables are loaded
// [/SL:KB]
//--------------------------------------------------------------------
// Member variables
@@ -259,23 +258,13 @@ private:
* True if agent's outfit is being changed now.
*/
BOOL mCOFChangeInProgress;
LLTimer mCOFChangeTimer;
//--------------------------------------------------------------------------------
// Support classes
//--------------------------------------------------------------------------------
private:
class createStandardWearablesAllDoneCallback : public LLRefCount
{
protected:
~createStandardWearablesAllDoneCallback();
};
class sendAgentWearablesUpdateCallback : public LLRefCount
{
protected:
~sendAgentWearablesUpdateCallback();
};
class addWearableToAgentInventoryCallback : public LLInventoryCallback
class AddWearableToAgentInventoryCallback : public LLInventoryCallback
{
public:
enum ETodo
@@ -288,7 +277,7 @@ private:
CALL_WEARITEM = 16
};
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
AddWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
LLWearableType::EType type,
U32 index,
LLViewerWearable* wearable,

View File

@@ -177,7 +177,7 @@ void LLInitialWearablesFetch::processContents()
// [/SL:KB]
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
// if (wearable_array.count() > 0)
// if (wearable_array.size() > 0)
// [SL:KB] - Patch: Appearance-MixedViewers | Checked: 2010-04-28 (Catznip-3.0.0a) | Modified: Catznip-2.0.0e
if (fUpdateFromCOF)
// [/SL:KB]
@@ -239,7 +239,7 @@ public:
void doneIdle()
{
// NOTE: the code above makes the assumption that COF is empty which won't be the case the way it's used now
LLInventoryModel::item_array_t initial_items;
LLInventoryObject::const_object_list_t initial_items;
for (uuid_vec_t::iterator itItem = mIDs.begin(); itItem != mIDs.end(); ++itItem)
{
LLViewerInventoryItem* pItem = gInventory.getItem(*itItem);
@@ -408,14 +408,14 @@ void LLLibraryOutfitsFetch::folderDone()
// Early out if we already have items in My Outfits
// except the case when My Outfits contains just initial outfit
if (cat_array.count() > 1)
if (cat_array.size() > 1)
{
mOutfitsPopulated = true;
return;
}
mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
mLibraryClothingID = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_CLOTHING, false);
// If Library->Clothing->Initial Outfits exists, use that.
LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
@@ -424,9 +424,9 @@ void LLLibraryOutfitsFetch::folderDone()
cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH,
matchFolderFunctor);
if (cat_array.count() > 0)
if (cat_array.size() > 0)
{
const LLViewerInventoryCategory *cat = cat_array.get(0);
const LLViewerInventoryCategory *cat = cat_array.at(0);
mLibraryClothingID = cat->getUUID();
}
@@ -456,7 +456,7 @@ void LLLibraryOutfitsFetch::outfitsDone()
gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH);
llassert(cat_array.count() > 0);
llassert(cat_array.size() > 0);
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
iter != cat_array.end();
++iter)
@@ -483,7 +483,7 @@ void LLLibraryOutfitsFetch::outfitsDone()
matchFolderFunctor);
if (cat_array.size() > 0)
{
const LLViewerInventoryCategory *cat = cat_array.get(0);
const LLViewerInventoryCategory *cat = cat_array.at(0);
mImportedClothingID = cat->getUUID();
}
@@ -666,13 +666,9 @@ void LLLibraryOutfitsFetch::contentsDone()
wearable_iter != wearable_array.end();
++wearable_iter)
{
const LLViewerInventoryItem *item = wearable_iter->get();
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
new_outfit_folder_id,
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
LLConstPointer<LLInventoryObject> item = wearable_iter->get();
link_inventory_object(new_outfit_folder_id,
item,
order_myoutfits_on_destroy);
}
}

877
indra/newview/llaisapi.cpp Normal file
View File

@@ -0,0 +1,877 @@
/**
* @file llaisapi.cpp
* @brief classes and functions for interfacing with the v3+ ais inventory service.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#include "llviewerprecompiledheaders.h"
#include "llaisapi.h"
#include "llagent.h"
#include "llcallbacklist.h"
#include "llinventorymodel.h"
#include "llsdutil.h"
#include "llviewerregion.h"
#include "llinventoryobserver.h"
#include "llviewercontrol.h"
///----------------------------------------------------------------------------
/// Classes for AISv3 support.
///----------------------------------------------------------------------------
// AISCommand - base class for retry-able HTTP requests using the AISv3 cap.
AISCommand::AISCommand(LLPointer<LLInventoryCallback> callback):
mCommandFunc(NULL),
mCallback(callback)
{
mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10);
}
bool AISCommand::run_command()
{
if (NULL == mCommandFunc)
{
// This may happen if a command failed to initiate itself.
LL_WARNS("Inventory") << "AIS command attempted with null command function" << LL_ENDL;
return false;
}
else
{
mCommandFunc();
return true;
}
}
void AISCommand::setCommandFunc(command_func_type command_func)
{
mCommandFunc = command_func;
}
// virtual
bool AISCommand::getResponseUUID(const LLSD& content, LLUUID& id)
{
return false;
}
/* virtual */
void AISCommand::httpSuccess()
{
// Command func holds a reference to self, need to release it
// after a success or final failure.
setCommandFunc(no_op);
const LLSD& content = getContent();
if (!content.isMap())
{
failureResult(400, "Malformed response contents", content);
return;
}
mRetryPolicy->onSuccess();
gInventory.onAISUpdateReceived("AISCommand", content);
if (mCallback)
{
LLUUID id; // will default to null if parse fails.
getResponseUUID(content,id);
mCallback->fire(id);
}
}
/*virtual*/
void AISCommand::httpFailure()
{
LL_WARNS("Inventory") << dumpResponse() << LL_ENDL;
S32 status = getStatus();
const AIHTTPReceivedHeaders& headers = getResponseHeaders();
mRetryPolicy->onFailure(status, headers);
F32 seconds_to_wait;
if (mRetryPolicy->shouldRetry(seconds_to_wait))
{
doAfterInterval(boost::bind(&AISCommand::run_command,this),seconds_to_wait);
}
else
{
// Command func holds a reference to self, need to release it
// after a success or final failure.
// *TODO: Notify user? This seems bad.
setCommandFunc(no_op);
}
}
//static
bool AISCommand::isAPIAvailable()
{
if (gAgent.getRegion())
{
return gAgent.getRegion()->isCapabilityAvailable("InventoryAPIv3");
}
return false;
}
//static
bool AISCommand::getInvCap(std::string& cap)
{
if (gAgent.getRegion())
{
cap = gAgent.getRegion()->getCapability("InventoryAPIv3");
}
if (!cap.empty())
{
return true;
}
return false;
}
//static
bool AISCommand::getLibCap(std::string& cap)
{
if (gAgent.getRegion())
{
cap = gAgent.getRegion()->getCapability("LibraryAPIv3");
}
if (!cap.empty())
{
return true;
}
return false;
}
//static
void AISCommand::getCapabilityNames(LLSD& capabilityNames)
{
capabilityNames.append("InventoryAPIv3");
capabilityNames.append("LibraryAPIv3");
}
RemoveItemCommand::RemoveItemCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback):
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
std::string url = cap + std::string("/item/") + item_id.asString();
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off));
setCommandFunc(cmd);
}
RemoveCategoryCommand::RemoveCategoryCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback):
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
std::string url = cap + std::string("/category/") + item_id.asString();
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off));
setCommandFunc(cmd);
}
PurgeDescendentsCommand::PurgeDescendentsCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback):
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
std::string url = cap + std::string("/category/") + item_id.asString() + "/children";
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off));
setCommandFunc(cmd);
}
UpdateItemCommand::UpdateItemCommand(const LLUUID& item_id,
const LLSD& updates,
LLPointer<LLInventoryCallback> callback):
mUpdates(updates),
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
std::string url = cap + std::string("/item/") + item_id.asString();
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LL_DEBUGS("Inventory") << "request: " << ll_pretty_print_sd(mUpdates) << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
AIHTTPHeaders headers;
headers.addHeader("Content-Type", "application/llsd+xml");
command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0);
setCommandFunc(cmd);
}
UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& cat_id,
const LLSD& updates,
LLPointer<LLInventoryCallback> callback):
mUpdates(updates),
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
std::string url = cap + std::string("/category/") + cat_id.asString();
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
AIHTTPHeaders headers;
headers.addHeader("Content-Type", "application/llsd+xml");
command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0);
setCommandFunc(cmd);
}
CreateInventoryCommand::CreateInventoryCommand(const LLUUID& parent_id,
const LLSD& new_inventory,
LLPointer<LLInventoryCallback> callback):
mNewInventory(new_inventory),
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
LLUUID tid;
tid.generate();
std::string url = cap + std::string("/category/") + parent_id.asString() + "?tid=" + tid.asString();
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
AIHTTPHeaders headers;
headers.addHeader("Content-Type", "application/llsd+xml");
command_func_type cmd = boost::bind(&LLHTTPClient::post, url, mNewInventory, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0);
setCommandFunc(cmd);
}
SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback):
mContents(contents),
AISCommand(callback)
{
std::string cap;
if (!getInvCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
LLUUID tid;
tid.generate();
std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString();
LL_INFOS() << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
AIHTTPHeaders headers;
headers.addHeader("Content-Type", "application/llsd+xml");
command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug_off));
setCommandFunc(cmd);
}
CopyLibraryCategoryCommand::CopyLibraryCategoryCommand(const LLUUID& source_id,
const LLUUID& dest_id,
LLPointer<LLInventoryCallback> callback):
AISCommand(callback)
{
std::string cap;
if (!getLibCap(cap))
{
LL_WARNS() << "No cap found" << LL_ENDL;
return;
}
LL_DEBUGS("Inventory") << "Copying library category: " << source_id << " => " << dest_id << LL_ENDL;
LLUUID tid;
tid.generate();
std::string url = cap + std::string("/category/") + source_id.asString() + "?tid=" + tid.asString();
LL_INFOS() << url << LL_ENDL;
LLHTTPClient::ResponderPtr responder = this;
command_func_type cmd = boost::bind(&LLHTTPClient::copy, url, dest_id.asString(), responder);
setCommandFunc(cmd);
}
bool CopyLibraryCategoryCommand::getResponseUUID(const LLSD& content, LLUUID& id)
{
if (content.has("category_id"))
{
id = content["category_id"];
return true;
}
return false;
}
AISUpdate::AISUpdate(const LLSD& update)
{
parseUpdate(update);
}
void AISUpdate::clearParseResults()
{
mCatDescendentDeltas.clear();
mCatDescendentsKnown.clear();
mCatVersionsUpdated.clear();
mItemsCreated.clear();
mItemsUpdated.clear();
mCategoriesCreated.clear();
mCategoriesUpdated.clear();
mObjectsDeletedIds.clear();
mItemIds.clear();
mCategoryIds.clear();
}
void AISUpdate::parseUpdate(const LLSD& update)
{
clearParseResults();
parseMeta(update);
parseContent(update);
}
void AISUpdate::parseMeta(const LLSD& update)
{
// parse _categories_removed -> mObjectsDeletedIds
uuid_list_t cat_ids;
parseUUIDArray(update,"_categories_removed",cat_ids);
for (uuid_list_t::const_iterator it = cat_ids.begin();
it != cat_ids.end(); ++it)
{
LLViewerInventoryCategory *cat = gInventory.getCategory(*it);
if(cat)
{
mCatDescendentDeltas[cat->getParentUUID()]--;
mObjectsDeletedIds.insert(*it);
}
else
{
LL_WARNS("Inventory") << "removed category not found " << *it << LL_ENDL;
}
}
// parse _categories_items_removed -> mObjectsDeletedIds
uuid_list_t item_ids;
parseUUIDArray(update,"_category_items_removed",item_ids);
parseUUIDArray(update,"_removed_items",item_ids);
for (uuid_list_t::const_iterator it = item_ids.begin();
it != item_ids.end(); ++it)
{
LLViewerInventoryItem *item = gInventory.getItem(*it);
if(item)
{
mCatDescendentDeltas[item->getParentUUID()]--;
mObjectsDeletedIds.insert(*it);
}
else
{
LL_WARNS("Inventory") << "removed item not found " << *it << LL_ENDL;
}
}
// parse _broken_links_removed -> mObjectsDeletedIds
uuid_list_t broken_link_ids;
parseUUIDArray(update,"_broken_links_removed",broken_link_ids);
for (uuid_list_t::const_iterator it = broken_link_ids.begin();
it != broken_link_ids.end(); ++it)
{
LLViewerInventoryItem *item = gInventory.getItem(*it);
if(item)
{
mCatDescendentDeltas[item->getParentUUID()]--;
mObjectsDeletedIds.insert(*it);
}
else
{
LL_WARNS("Inventory") << "broken link not found " << *it << LL_ENDL;
}
}
// parse _created_items
parseUUIDArray(update,"_created_items",mItemIds);
// parse _created_categories
parseUUIDArray(update,"_created_categories",mCategoryIds);
// Parse updated category versions.
const std::string& ucv = "_updated_category_versions";
if (update.has(ucv))
{
for(LLSD::map_const_iterator it = update[ucv].beginMap(),
end = update[ucv].endMap();
it != end; ++it)
{
const LLUUID id((*it).first);
S32 version = (*it).second.asInteger();
mCatVersionsUpdated[id] = version;
}
}
}
void AISUpdate::parseContent(const LLSD& update)
{
if (update.has("linked_id"))
{
parseLink(update);
}
else if (update.has("item_id"))
{
parseItem(update);
}
if (update.has("category_id"))
{
parseCategory(update);
}
else
{
if (update.has("_embedded"))
{
parseEmbedded(update["_embedded"]);
}
}
}
void AISUpdate::parseItem(const LLSD& item_map)
{
LLUUID item_id = item_map["item_id"].asUUID();
LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem);
LLViewerInventoryItem *curr_item = gInventory.getItem(item_id);
if (curr_item)
{
// Default to current values where not provided.
new_item->copyViewerItem(curr_item);
}
BOOL rv = new_item->unpackMessage(item_map);
if (rv)
{
if (curr_item)
{
mItemsUpdated[item_id] = new_item;
// This statement is here to cause a new entry with 0
// delta to be created if it does not already exist;
// otherwise has no effect.
mCatDescendentDeltas[new_item->getParentUUID()];
}
else
{
mItemsCreated[item_id] = new_item;
mCatDescendentDeltas[new_item->getParentUUID()]++;
}
}
else
{
// *TODO: Wow, harsh. Should we just complain and get out?
LL_ERRS() << "unpack failed" << LL_ENDL;
}
}
void AISUpdate::parseLink(const LLSD& link_map)
{
LLUUID item_id = link_map["item_id"].asUUID();
LLPointer<LLViewerInventoryItem> new_link(new LLViewerInventoryItem);
LLViewerInventoryItem *curr_link = gInventory.getItem(item_id);
if (curr_link)
{
// Default to current values where not provided.
new_link->copyViewerItem(curr_link);
}
BOOL rv = new_link->unpackMessage(link_map);
if (rv)
{
const LLUUID& parent_id = new_link->getParentUUID();
if (curr_link)
{
mItemsUpdated[item_id] = new_link;
// This statement is here to cause a new entry with 0
// delta to be created if it does not already exist;
// otherwise has no effect.
mCatDescendentDeltas[parent_id];
}
else
{
LLPermissions default_perms;
default_perms.init(gAgent.getID(),gAgent.getID(),LLUUID::null,LLUUID::null);
default_perms.initMasks(PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE);
new_link->setPermissions(default_perms);
LLSaleInfo default_sale_info;
new_link->setSaleInfo(default_sale_info);
//LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << LL_ENDL;
mItemsCreated[item_id] = new_link;
mCatDescendentDeltas[parent_id]++;
}
}
else
{
// *TODO: Wow, harsh. Should we just complain and get out?
LL_ERRS() << "unpack failed" << LL_ENDL;
}
}
void AISUpdate::parseCategory(const LLSD& category_map)
{
LLUUID category_id = category_map["category_id"].asUUID();
// Check descendent count first, as it may be needed
// to populate newly created categories
if (category_map.has("_embedded"))
{
parseDescendentCount(category_id, category_map["_embedded"]);
}
LLPointer<LLViewerInventoryCategory> new_cat(new LLViewerInventoryCategory(category_id));
LLViewerInventoryCategory *curr_cat = gInventory.getCategory(category_id);
if (curr_cat)
{
// Default to current values where not provided.
new_cat->copyViewerCategory(curr_cat);
}
BOOL rv = new_cat->unpackMessage(category_map);
// *NOTE: unpackMessage does not unpack version or descendent count.
//if (category_map.has("version"))
//{
// mCatVersionsUpdated[category_id] = category_map["version"].asInteger();
//}
if (rv)
{
if (curr_cat)
{
mCategoriesUpdated[category_id] = new_cat;
// This statement is here to cause a new entry with 0
// delta to be created if it does not already exist;
// otherwise has no effect.
mCatDescendentDeltas[new_cat->getParentUUID()];
// Capture update for the category itself as well.
mCatDescendentDeltas[category_id];
}
else
{
// Set version/descendents for newly created categories.
if (category_map.has("version"))
{
S32 version = category_map["version"].asInteger();
LL_DEBUGS("Inventory") << "Setting version to " << version
<< " for new category " << category_id << LL_ENDL;
new_cat->setVersion(version);
}
uuid_int_map_t::const_iterator lookup_it = mCatDescendentsKnown.find(category_id);
if (mCatDescendentsKnown.end() != lookup_it)
{
S32 descendent_count = lookup_it->second;
LL_DEBUGS("Inventory") << "Setting descendents count to " << descendent_count
<< " for new category " << category_id << LL_ENDL;
new_cat->setDescendentCount(descendent_count);
}
mCategoriesCreated[category_id] = new_cat;
mCatDescendentDeltas[new_cat->getParentUUID()]++;
}
}
else
{
// *TODO: Wow, harsh. Should we just complain and get out?
LL_ERRS() << "unpack failed" << LL_ENDL;
}
// Check for more embedded content.
if (category_map.has("_embedded"))
{
parseEmbedded(category_map["_embedded"]);
}
}
void AISUpdate::parseDescendentCount(const LLUUID& category_id, const LLSD& embedded)
{
// We can only determine true descendent count if this contains all descendent types.
if (embedded.has("categories") &&
embedded.has("links") &&
embedded.has("items"))
{
mCatDescendentsKnown[category_id] = embedded["categories"].size();
mCatDescendentsKnown[category_id] += embedded["links"].size();
mCatDescendentsKnown[category_id] += embedded["items"].size();
}
}
void AISUpdate::parseEmbedded(const LLSD& embedded)
{
if (embedded.has("links")) // _embedded in a category
{
parseEmbeddedLinks(embedded["links"]);
}
if (embedded.has("items")) // _embedded in a category
{
parseEmbeddedItems(embedded["items"]);
}
if (embedded.has("item")) // _embedded in a link
{
parseEmbeddedItem(embedded["item"]);
}
if (embedded.has("categories")) // _embedded in a category
{
parseEmbeddedCategories(embedded["categories"]);
}
if (embedded.has("category")) // _embedded in a link
{
parseEmbeddedCategory(embedded["category"]);
}
}
void AISUpdate::parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids)
{
if (content.has(name))
{
for(LLSD::array_const_iterator it = content[name].beginArray(),
end = content[name].endArray();
it != end; ++it)
{
ids.insert((*it).asUUID());
}
}
}
void AISUpdate::parseEmbeddedLinks(const LLSD& links)
{
for(LLSD::map_const_iterator linkit = links.beginMap(),
linkend = links.endMap();
linkit != linkend; ++linkit)
{
const LLUUID link_id((*linkit).first);
const LLSD& link_map = (*linkit).second;
if (mItemIds.end() == mItemIds.find(link_id))
{
LL_DEBUGS("Inventory") << "Ignoring link not in items list " << link_id << LL_ENDL;
}
else
{
parseLink(link_map);
}
}
}
void AISUpdate::parseEmbeddedItem(const LLSD& item)
{
// a single item (_embedded in a link)
if (item.has("item_id"))
{
if (mItemIds.end() != mItemIds.find(item["item_id"].asUUID()))
{
parseItem(item);
}
}
}
void AISUpdate::parseEmbeddedItems(const LLSD& items)
{
// a map of items (_embedded in a category)
for(LLSD::map_const_iterator itemit = items.beginMap(),
itemend = items.endMap();
itemit != itemend; ++itemit)
{
const LLUUID item_id((*itemit).first);
const LLSD& item_map = (*itemit).second;
if (mItemIds.end() == mItemIds.find(item_id))
{
LL_DEBUGS("Inventory") << "Ignoring item not in items list " << item_id << LL_ENDL;
}
else
{
parseItem(item_map);
}
}
}
void AISUpdate::parseEmbeddedCategory(const LLSD& category)
{
// a single category (_embedded in a link)
if (category.has("category_id"))
{
if (mCategoryIds.end() != mCategoryIds.find(category["category_id"].asUUID()))
{
parseCategory(category);
}
}
}
void AISUpdate::parseEmbeddedCategories(const LLSD& categories)
{
// a map of categories (_embedded in a category)
for(LLSD::map_const_iterator categoryit = categories.beginMap(),
categoryend = categories.endMap();
categoryit != categoryend; ++categoryit)
{
const LLUUID category_id((*categoryit).first);
const LLSD& category_map = (*categoryit).second;
if (mCategoryIds.end() == mCategoryIds.find(category_id))
{
LL_DEBUGS("Inventory") << "Ignoring category not in categories list " << category_id << LL_ENDL;
}
else
{
parseCategory(category_map);
}
}
}
void AISUpdate::doUpdate()
{
// Do version/descendent accounting.
for (std::map<LLUUID,S32>::const_iterator catit = mCatDescendentDeltas.begin();
catit != mCatDescendentDeltas.end(); ++catit)
{
LL_DEBUGS("Inventory") << "descendent accounting for " << catit->first << LL_ENDL;
const LLUUID cat_id(catit->first);
// Don't account for update if we just created this category.
if (mCategoriesCreated.find(cat_id) != mCategoriesCreated.end())
{
LL_DEBUGS("Inventory") << "Skipping version increment for new category " << cat_id << LL_ENDL;
continue;
}
// Don't account for update unless AIS told us it updated that category.
if (mCatVersionsUpdated.find(cat_id) == mCatVersionsUpdated.end())
{
LL_DEBUGS("Inventory") << "Skipping version increment for non-updated category " << cat_id << LL_ENDL;
continue;
}
// If we have a known descendent count, set that now.
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
S32 descendent_delta = catit->second;
S32 old_count = cat->getDescendentCount();
LL_DEBUGS("Inventory") << "Updating descendent count for "
<< cat->getName() << " " << cat_id
<< " with delta " << descendent_delta << " from "
<< old_count << " to " << (old_count+descendent_delta) << LL_ENDL;
LLInventoryModel::LLCategoryUpdate up(cat_id, descendent_delta);
gInventory.accountForUpdate(up);
}
else
{
LL_DEBUGS("Inventory") << "Skipping version accounting for unknown category " << cat_id << LL_ENDL;
}
}
// CREATE CATEGORIES
for (deferred_category_map_t::const_iterator create_it = mCategoriesCreated.begin();
create_it != mCategoriesCreated.end(); ++create_it)
{
LLUUID category_id(create_it->first);
LLPointer<LLViewerInventoryCategory> new_category = create_it->second;
gInventory.updateCategory(new_category, LLInventoryObserver::CREATE);
LL_DEBUGS("Inventory") << "created category " << category_id << LL_ENDL;
}
// UPDATE CATEGORIES
for (deferred_category_map_t::const_iterator update_it = mCategoriesUpdated.begin();
update_it != mCategoriesUpdated.end(); ++update_it)
{
LLUUID category_id(update_it->first);
LLPointer<LLViewerInventoryCategory> new_category = update_it->second;
// Since this is a copy of the category *before* the accounting update, above,
// we need to transfer back the updated version/descendent count.
LLViewerInventoryCategory* curr_cat = gInventory.getCategory(new_category->getUUID());
if (!curr_cat)
{
LL_WARNS("Inventory") << "Failed to update unknown category " << new_category->getUUID() << LL_ENDL;
}
else
{
new_category->setVersion(curr_cat->getVersion());
new_category->setDescendentCount(curr_cat->getDescendentCount());
gInventory.updateCategory(new_category);
LL_DEBUGS("Inventory") << "updated category " << new_category->getName() << " " << category_id << LL_ENDL;
}
}
// CREATE ITEMS
for (deferred_item_map_t::const_iterator create_it = mItemsCreated.begin();
create_it != mItemsCreated.end(); ++create_it)
{
LLUUID item_id(create_it->first);
LLPointer<LLViewerInventoryItem> new_item = create_it->second;
// FIXME risky function since it calls updateServer() in some
// cases. Maybe break out the update/create cases, in which
// case this is create.
LL_DEBUGS("Inventory") << "created item " << item_id << LL_ENDL;
gInventory.updateItem(new_item, LLInventoryObserver::CREATE);
}
// UPDATE ITEMS
for (deferred_item_map_t::const_iterator update_it = mItemsUpdated.begin();
update_it != mItemsUpdated.end(); ++update_it)
{
LLUUID item_id(update_it->first);
LLPointer<LLViewerInventoryItem> new_item = update_it->second;
// FIXME risky function since it calls updateServer() in some
// cases. Maybe break out the update/create cases, in which
// case this is update.
LL_DEBUGS("Inventory") << "updated item " << item_id << LL_ENDL;
//LL_DEBUGS("Inventory") << ll_pretty_print_sd(new_item->asLLSD()) << LL_ENDL;
gInventory.updateItem(new_item);
}
// DELETE OBJECTS
for (uuid_list_t::const_iterator del_it = mObjectsDeletedIds.begin();
del_it != mObjectsDeletedIds.end(); ++del_it)
{
LL_INFOS("Inventory") << "deleted item " << *del_it << LL_ENDL;
gInventory.onObjectDeletedFromServer(*del_it, false, false, false);
}
// TODO - how can we use this version info? Need to be sure all
// changes are going through AIS first, or at least through
// something with a reliable responder.
for (uuid_int_map_t::iterator ucv_it = mCatVersionsUpdated.begin();
ucv_it != mCatVersionsUpdated.end(); ++ucv_it)
{
const LLUUID id = ucv_it->first;
S32 version = ucv_it->second;
LLViewerInventoryCategory *cat = gInventory.getCategory(id);
LL_DEBUGS("Inventory") << "cat version update " << cat->getName() << " to version " << cat->getVersion() << LL_ENDL;
if (cat->getVersion() != version)
{
LL_WARNS() << "Possible version mismatch for category " << cat->getName()
<< ", viewer version " << cat->getVersion()
<< " server version " << version << LL_ENDL;
}
}
gInventory.notifyObservers();
}

194
indra/newview/llaisapi.h Normal file
View File

@@ -0,0 +1,194 @@
/**
* @file llaisapi.h
* @brief classes and functions for interfacing with the v3+ ais inventory service.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLAISAPI_H
#define LL_LLAISAPI_H
#include "lluuid.h"
#include <map>
#include <set>
#include <string>
#include "llcurl.h"
#include "llhttpclient.h"
#include "llhttpretrypolicy.h"
#include "llviewerinventory.h"
class AISCommand: public LLHTTPClient::ResponderWithResult
{
public:
typedef boost::function<void()> command_func_type;
AISCommand(LLPointer<LLInventoryCallback> callback);
virtual ~AISCommand() {}
bool run_command();
void setCommandFunc(command_func_type command_func);
// Need to do command-specific parsing to get an id here, for
// LLInventoryCallback::fire(). May or may not need to bother,
// since most LLInventoryCallbacks do their work in the
// destructor.
/* virtual */ void httpSuccess();
/* virtual */ void httpFailure();
static bool isAPIAvailable();
static bool getInvCap(std::string& cap);
static bool getLibCap(std::string& cap);
static void getCapabilityNames(LLSD& capabilityNames);
protected:
virtual bool getResponseUUID(const LLSD& content, LLUUID& id);
private:
command_func_type mCommandFunc;
LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
LLPointer<LLInventoryCallback> mCallback;
};
class RemoveItemCommand: public AISCommand
{
public:
RemoveItemCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "RemoveItemCommand"; }
};
class RemoveCategoryCommand: public AISCommand
{
public:
RemoveCategoryCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "RemoveCategoryCommand"; }
};
class PurgeDescendentsCommand: public AISCommand
{
public:
PurgeDescendentsCommand(const LLUUID& item_id,
LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "PurgeDescendentsCommand"; }
};
class UpdateItemCommand: public AISCommand
{
public:
UpdateItemCommand(const LLUUID& item_id,
const LLSD& updates,
LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "UpdateItemCommand"; }
private:
LLSD mUpdates;
};
class UpdateCategoryCommand: public AISCommand
{
public:
UpdateCategoryCommand(const LLUUID& cat_id,
const LLSD& updates,
LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "UpdateCategoryCommand"; }
private:
LLSD mUpdates;
};
class SlamFolderCommand: public AISCommand
{
public:
SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "SlamFolderCommand"; }
private:
LLSD mContents;
};
class CopyLibraryCategoryCommand: public AISCommand
{
public:
CopyLibraryCategoryCommand(const LLUUID& source_id, const LLUUID& dest_id, LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "CopyLibraryCategoryCommand"; }
protected:
/* virtual */ bool getResponseUUID(const LLSD& content, LLUUID& id);
};
class CreateInventoryCommand: public AISCommand
{
public:
CreateInventoryCommand(const LLUUID& parent_id, const LLSD& new_inventory, LLPointer<LLInventoryCallback> callback);
/* virtual */ const char* getName() const { return "CreateInventoryCommand"; }
private:
LLSD mNewInventory;
};
class AISUpdate
{
public:
AISUpdate(const LLSD& update);
void parseUpdate(const LLSD& update);
void parseMeta(const LLSD& update);
void parseContent(const LLSD& update);
void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
void parseLink(const LLSD& link_map);
void parseItem(const LLSD& link_map);
void parseCategory(const LLSD& link_map);
void parseDescendentCount(const LLUUID& category_id, const LLSD& embedded);
void parseEmbedded(const LLSD& embedded);
void parseEmbeddedLinks(const LLSD& links);
void parseEmbeddedItems(const LLSD& items);
void parseEmbeddedCategories(const LLSD& categories);
void parseEmbeddedItem(const LLSD& item);
void parseEmbeddedCategory(const LLSD& category);
void doUpdate();
private:
void clearParseResults();
typedef std::map<LLUUID,S32> uuid_int_map_t;
uuid_int_map_t mCatDescendentDeltas;
uuid_int_map_t mCatDescendentsKnown;
uuid_int_map_t mCatVersionsUpdated;
typedef std::map<LLUUID,LLPointer<LLViewerInventoryItem> > deferred_item_map_t;
deferred_item_map_t mItemsCreated;
deferred_item_map_t mItemsUpdated;
typedef std::map<LLUUID,LLPointer<LLViewerInventoryCategory> > deferred_category_map_t;
deferred_category_map_t mCategoriesCreated;
deferred_category_map_t mCategoriesUpdated;
// These keep track of uuid's mentioned in meta values.
// Useful for filtering out which content we are interested in.
uuid_list_t mObjectsDeletedIds;
uuid_list_t mItemIds;
uuid_list_t mCategoryIds;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,7 @@ class LLWearable;
class LLWearableHoldingPattern;
class LLInventoryCallback;
class LLOutfitUnLockTimer;
class LLCallAfterInventoryLinkMgr;
class RequestAgentUpdateAppearanceResponder;
class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
{
@@ -52,16 +52,18 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
public:
typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
void updateAppearanceFromCOF(bool update_base_outfit_ordering = false);
void updateAppearanceFromCOF(bool enforce_item_restrictions = true,
bool enforce_ordering = true,
nullary_func_t post_update_func = no_op);
// [SL:KB] - Patch: Appearance-MixedViewers | Checked: 2010-04-02 (Catznip-3.0.0a) | Added: Catznip-2.0.0a
void updateAppearanceFromInitialWearables(LLInventoryModel::item_array_t& initial_items);
void updateAppearanceFromInitialWearables(LLInventoryObject::const_object_list_t& initial_items);
// [/SL:KB]
bool needToSaveCOF();
void updateCOF(const LLUUID& category, bool append = false);
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new,
LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new,
bool append = false, const LLUUID& idOutfit = LLUUID::null);
bool append = false, const LLUUID& idOutfit = LLUUID::null, LLPointer<LLInventoryCallback> link_waiter = NULL);
// [/RLVa:KB]
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
@@ -74,18 +76,24 @@ public:
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
LLAssetType::EType type,
S32 max_items,
LLInventoryModel::item_array_t& items_to_kill);
void enforceItemRestrictions();
S32 max_items_per_type,
S32 max_items_total,
LLInventoryObject::object_list_t& items_to_kill);
void findAllExcessOrDuplicateItems(const LLUUID& cat_id,
LLInventoryObject::object_list_t& items_to_kill);
void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb);
S32 getActiveCopyOperations() const;
// Replace category contents with copied links via the slam_inventory_folder
// command (single inventory operation where supported)
void slamCategoryLinks(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,
LLPointer<LLInventoryCallback> cb);
void copyItems(const LLUUID& dst_id, LLInventoryModel::item_array_t* items, LLPointer<LLInventoryCallback> cb);
// Return whether this folder contains minimal contents suitable for making a full outfit.
BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id);
@@ -101,21 +109,20 @@ public:
// Determine whether we can replace current outfit with the given one.
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
// Can we add all referenced items to the avatar?
bool canAddWearables(const uuid_vec_t& item_ids);
// Copy all items in a category.
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb);
void copyItems(const LLUUID& dst_id, LLInventoryModel::item_array_t* items, LLPointer<LLInventoryCallback> cb);
// Find the Current Outfit folder.
const LLUUID getCOF() const;
S32 getCOFVersion() const;
S32 mLastUpdateRequestCOFVersion;
S32 getLastUpdateRequestCOFVersion() const;
// COF version of last appearance message received for self av.
S32 mLastAppearanceUpdateCOFVersion;
S32 getLastAppearanceUpdateCOFVersion() const;
void setLastAppearanceUpdateCOFVersion(S32 new_val);
// Debugging - get truncated LLSD summary of COF contents.
LLSD dumpCOF() const;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@@ -124,17 +131,24 @@ public:
// find the UUID of the currently worn outfit (Base Outfit)
const LLUUID getBaseOutfitUUID();
void wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
bool do_update,
bool replace,
LLPointer<LLInventoryCallback> cb = NULL);
// Wear/attach an item (from a user's inventory) on the agent
bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true, bool replace = false, LLPointer<LLInventoryCallback> cb = NULL);
void wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update, bool replace = false,
LLPointer<LLInventoryCallback> cb = NULL);
// Update the displayed outfit name in UI.
void updatePanelOutfitName(const std::string& name);
void purgeBaseOutfitLink(const LLUUID& category);
void purgeBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> cb = NULL);
void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
void updateAgentWearables(LLWearableHoldingPattern* holder);
S32 countActiveHoldingPatterns();
// For debugging - could be moved elsewhere.
void dumpCat(const LLUUID& cat_id, const std::string& msg);
void dumpItemArray(const LLInventoryModel::item_array_t& items, const std::string& msg);
@@ -144,25 +158,26 @@ public:
void registerAttachment(const LLUUID& item_id);
void setAttachmentInvLinkEnable(bool val);
// utility function for bulk linking.
void linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb);
// Add COF link to individual item.
void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
void addCOFItemLink(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
void addCOFItemLink(const LLInventoryItem *item, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
// Find COF entries referencing the given item.
LLInventoryModel::item_array_t findCOFItemLinks(const LLUUID& item_id);
bool isLinkedInCOF(const LLUUID& item_id);
// Remove COF entries
void removeCOFItemLinks(const LLUUID& item_id);
void removeCOFLinksOfType(LLWearableType::EType type);
// void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL);
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
// [/SL:KB]
void removeCOFLinksOfType(LLWearableType::EType type, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
void removeAllClothesFromAvatar();
void removeAllAttachmentsFromAvatar();
// Special handling of temp attachments, which are not in the COF
bool shouldRemoveTempAttachment(const LLUUID& item_id);
//has the current outfit changed since it was loaded?
bool isOutfitDirty() { return mOutfitIsDirty; }
@@ -173,12 +188,11 @@ public:
// should only be necessary to do on initial login.
void updateIsDirty();
void setOutfitLocked(bool locked);
// Called when self avatar is first fully visible.
void onFirstFullyVisible();
// Create initial outfits from library.
void autopopulateOutfits();
// Copy initial gestures from library.
void copyLibraryGestures();
@@ -189,9 +203,18 @@ public:
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
void removeItemsFromAvatar(const uuid_vec_t& item_ids);
void removeItemFromAvatar(const LLUUID& item_id);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
void removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
// [/SL:KB]
// void removeItemsFromAvatar(const uuid_vec_t& item_ids);
// void removeItemFromAvatar(const LLUUID& item_id);
void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
void onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel);
private:
LLUUID makeNewOutfitCore(const std::string& new_folder_name, bool show_panel/*=true*/, LLInventoryModel::item_array_t* items = NULL);
public:
@@ -206,15 +229,29 @@ public:
//Divvy items into arrays by wearable type
static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
typedef std::map<LLUUID,std::string> desc_map_t;
void getWearableOrderingDescUpdates(LLInventoryModel::item_array_t& wear_items, desc_map_t& desc_map);
//Check ordering information on wearables stored in links' descriptions and update if it is invalid
// COF is processed if cat_id is not specified
void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null, bool update_base_outfit_ordering = false);
bool validateClothingOrderingInfo(LLUUID cat_id = LLUUID::null);
void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null,
LLPointer<LLInventoryCallback> cb = NULL);
bool isOutfitLocked() { return mOutfitLocked; }
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
void requestServerAppearanceUpdate(LLHTTPClient::ResponderPtr responder_ptr = NULL);
void requestServerAppearanceUpdate();
void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
U32 getNumAttachmentsInCOF();
// *HACK Remove this after server side texture baking is deployed on all sims.
void incrementCofVersionLegacy();
void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
std::string getAppearanceServiceURL() const;
@@ -229,48 +266,49 @@ protected:
private:
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type, S32 max_total);
void getDescendentsOfAssetType(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLAssetType::EType type,
bool follow_folder_links);
bool follow_folder_links = false);
void getUserDescendents(const LLUUID& category,
LLInventoryModel::item_array_t& wear_items,
LLInventoryModel::item_array_t& obj_items,
LLInventoryModel::item_array_t& gest_items,
bool follow_folder_links);
bool follow_folder_links = false);
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
static void onOutfitRename(const LLSD& notification, const LLSD& response);
void setOutfitLocked(bool locked);
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
void purgeItems(const LLInventoryModel::item_array_t& items);
void purgeItemsOfType(LLAssetType::EType asset_type);
void syncCOF(const LLInventoryModel::item_array_t& items,
LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove);
// [/SL:KB]
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
boost::intrusive_ptr<RequestAgentUpdateAppearanceResponder> mAppearanceResponder;
/**
* Lock for blocking operations on outfit until server reply or timeout exceed
* to avoid unsynchronized outfit state or performing duplicate operations.
*/
bool mOutfitLocked;
boost::scoped_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-3.0.0a) | Modified: Catznip-2.1.2e
// Set of temp attachment UUIDs that should be removed
typedef std::set<LLUUID> doomed_temp_attachments_t;
doomed_temp_attachments_t mDoomedTempAttachmentIDs;
void addDoomedTempAttachment(const LLUUID& id_to_remove);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-2.1)
public:
void linkPendingAttachments();
void onRegisterAttachmentComplete(const LLUUID& idItem);
void clearPendingAttachment(const LLUUID& idItem);
void onRegisterAttachmentComplete(const LLUUID& idAttachItem);
private:
uuid_vec_t mPendingAttachLinks;
// [/SL:KB]
@@ -292,27 +330,36 @@ public:
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
{
public:
LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering = false);
LLUpdateAppearanceOnDestroy(bool enforce_item_restrictions = true,
bool enforce_ordering = true,
nullary_func_t post_update_func = no_op);
virtual ~LLUpdateAppearanceOnDestroy();
/* virtual */ void fire(const LLUUID& inv_item);
static U32 sActiveCallbacks;
private:
U32 mFireCount;
bool mUpdateBaseOrder;
bool mEnforceItemRestrictions;
bool mEnforceOrdering;
nullary_func_t mPostUpdateFunc;
};
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-3.0.0a) | Added: Catznip-2.1.2a
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-2.1)
class LLRegisterAttachmentCallback : public LLInventoryCallback
{
public:
/*virtual*/ void fire(const LLUUID& idItem)
LLRegisterAttachmentCallback(const LLUUID& idAttachItem) : m_idAttachItem(idAttachItem) {}
/*virtual*/ void fire(const LLUUID&)
{
LLAppearanceMgr::instance().onRegisterAttachmentComplete(idItem);
// NOTE: AISCommand::getResponseUUID() currently returns false so the passed UUID is NULL and hence useless
LLAppearanceMgr::instance().onRegisterAttachmentComplete(m_idAttachItem);
}
protected:
LLUUID m_idAttachItem;
};
// [/SL:KB]
void edit_wearable_and_customize_avatar(LLUUID item_id);
#define SUPPORT_ENSEMBLES 0
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);

View File

@@ -1641,6 +1641,8 @@ bool LLAppViewer::cleanup()
LLAvatarAppearance::cleanupClass();
LLAvatarAppearance::cleanupClass();
LLPostProcess::cleanupClass();
LLTracker::cleanupInstance();
@@ -1878,6 +1880,8 @@ bool LLAppViewer::cleanup()
ll_close_fail_log();
LLError::LLCallStacks::cleanup();
MEM_TRACK_RELEASE
LL_INFOS() << "Goodbye!" << LL_ENDL;

View File

@@ -47,7 +47,7 @@ public:
LLAssetUploadChainResponder(const LLSD& post_data,
const std::string& file_name,
const LLUUID& queue_id,
char* data,
U8* data,
U32 data_size,
std::string script_name,
LLAssetUploadQueueSupplier *supplier) :
@@ -129,7 +129,9 @@ public:
for(LLSD::array_const_iterator line = compile_errors.beginArray();
line < compile_errors.endArray(); line++)
{
mSupplier->log(line->asString());
std::string str = line->asString();
str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
mSupplier->log(str);
LL_INFOS() << content["errors"] << LL_ENDL;
}
}
@@ -139,7 +141,7 @@ public:
/*virtual*/ char const* getName(void) const { return "LLAssetUploadChainResponder"; }
LLAssetUploadQueueSupplier *mSupplier;
char* mData;
U8* mData;
U32 mDataSize;
std::string mScriptName;
};
@@ -190,7 +192,7 @@ void LLAssetUploadQueue::queue(const std::string& filename,
BOOL is_running,
BOOL is_target_mono,
const LLUUID& queue_id,
char* script_data,
U8* script_data,
U32 data_size,
std::string script_name)
{

View File

@@ -54,7 +54,7 @@ public:
BOOL is_running,
BOOL is_target_mono,
const LLUUID& queue_id,
char* data,
U8* data,
U32 data_size,
std::string script_name);
@@ -72,7 +72,7 @@ private:
BOOL mIsRunning;
BOOL mIsTargetMono;
LLUUID mQueueId;
char* mData;
U8* mData;
U32 mDataSize;
std::string mScriptName;
};

View File

@@ -33,7 +33,7 @@
#include "llviewerinventory.h"
#include "llviewerregion.h"
#include "message.h"
// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
@@ -49,7 +49,7 @@ LLAttachmentsMgr::~LLAttachmentsMgr()
void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
const U8 attachment_pt,
// const BOOL add)
// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1c) | Added: RLVa-1.2.1c
// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1)
const BOOL add, const BOOL fRlvForce /*=FALSE*/)
// [/RLVa:KB]
{
@@ -58,7 +58,7 @@ void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
attachment.mAttachmentPt = attachment_pt;
attachment.mAdd = add;
// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1d) | Modified: RLVa-1.2.1d
// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1)
if ( (rlv_handler_t::isEnabled()) && (!fRlvForce) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
{
const LLInventoryItem* pItem = gInventory.getItem(item_id);

View File

@@ -162,7 +162,7 @@ void LLAvatarActions::offerTeleport(const LLUUID& invitee)
if (invitee.isNull())
return;
LLDynamicArray<LLUUID> ids;
std::vector<LLUUID> ids;
ids.push_back(invitee);
offerTeleport(ids);
}
@@ -258,8 +258,6 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
return;
}
// convert vector into LLDynamicArray for addSession
LLDynamicArray<LLUUID> id_array;
for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0)
@@ -270,7 +268,6 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF);
return;
}
id_array.push_back(idAgent);
// [/RLVa:KB]
// id_array.push_back(*it);
}
@@ -278,7 +275,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
// create the new ad hoc voice session
const std::string title = LLTrans::getString("conference-title");
LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
ids[0], id_array);
ids[0], ids);
if (session_id.isNull())
{
return;

View File

@@ -73,7 +73,6 @@
#include "v4math.h"
#include "v4color.h"
#include "llmemory.h"
#include "lldarray.h"
#include "llframetimer.h"

View File

@@ -183,7 +183,7 @@ void LLFloaterScriptQueue::onCloseBtn(void* user_data)
void LLFloaterScriptQueue::addObject(const LLUUID& id)
{
mObjectIDs.put(id);
mObjectIDs.push_back(id);
}
BOOL LLFloaterScriptQueue::start()
@@ -193,7 +193,7 @@ BOOL LLFloaterScriptQueue::start()
LLStringUtil::format_map_t args;
args["[START]"] = mStartString;
args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
args["[COUNT]"] = llformat ("%d", mObjectIDs.size());
buffer = getString ("Starting", args);
getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
@@ -416,8 +416,8 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
{
// Read script source in to buffer.
U32 script_size = file.getSize();
char* script_data = new char[script_size];
file.read((U8*)script_data, script_size);
U8* script_data = new U8[script_size];
file.read(script_data, script_size);
queue->mUploadQueue->queue(filename, data->mTaskId,
data->mItemId, is_running, queue->mMono, queue->getID(),
@@ -648,7 +648,7 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
{
// find all of the lsl, leaving off duplicates. We'll remove
// all matching asset uuids on compilation success.
LLDynamicArray<const char*> names;
std::vector<const char*> names;
LLInventoryObject::object_list_t::const_iterator it = inv->begin();
LLInventoryObject::object_list_t::const_iterator end = inv->end();
@@ -709,7 +709,7 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
{
// find all of the lsl, leaving off duplicates. We'll remove
// all matching asset uuids on compilation success.
LLDynamicArray<const char*> names;
std::vector<const char*> names;
LLInventoryObject::object_list_t::const_iterator it = inv->begin();
LLInventoryObject::object_list_t::const_iterator end = inv->end();
@@ -793,7 +793,7 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,
{
// find all of the lsl, leaving off duplicates. We'll remove
// all matching asset uuids on compilation success.
LLDynamicArray<const char*> names;
std::vector<const char*> names;
LLInventoryObject::object_list_t::const_iterator it = inv->begin();
LLInventoryObject::object_list_t::const_iterator end = inv->end();

View File

@@ -33,7 +33,6 @@
#ifndef LL_LLCOMPILEQUEUE_H
#define LL_LLCOMPILEQUEUE_H
#include "lldarray.h"
#include "llinventory.h"
#include "llviewerobject.h"
#include "llvoinventorylistener.h"
@@ -103,7 +102,7 @@ protected:
LLButton* mCloseBtn;
// Object Queue
LLDynamicArray<LLUUID> mObjectIDs;
std::vector<LLUUID> mObjectIDs;
LLUUID mCurrentObjectID;
bool mDone;

View File

@@ -34,7 +34,6 @@
#ifndef LL_LLDEBUGMESSAGEBOX_H
#define LL_LLDEBUGMESSAGEBOX_H
#include "lldarray.h"
#include "llfloater.h"
#include "v3math.h"
#include "lltextbox.h"

View File

@@ -75,19 +75,25 @@ extern bool gShiftFrame;
//
// static
U32 LLDrawable::sCurVisible = 0;
U32 LLDrawable::sNumZombieDrawables = 0;
F32 LLDrawable::sCurPixelAngle = 0;
LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
std::vector<LLPointer<LLDrawable> > LLDrawable::sDeadList;
#define FORCE_INVISIBLE_AREA 16.f
// static
void LLDrawable::incrementVisible()
{
sCurVisible++;
LLViewerOctreeEntryData::incrementVisible();
sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
}
LLDrawable::LLDrawable(LLViewerObject *vobj)
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
mVObjp(vobj)
{
init();
}
void LLDrawable::init()
{
// mXform
@@ -95,21 +101,16 @@ void LLDrawable::init()
mRenderType = 0;
mCurrentScale = LLVector3(1,1,1);
mDistanceWRTCamera = 0.0f;
mPositionGroup.clear();
mExtents[0].clear();
mExtents[1].clear();
mState = 0;
mVObjp = NULL;
// mFaces
mSpatialGroupp = NULL;
mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
mRadius = 0.f;
mGeneration = -1;
mBinRadius = 1.f;
mBinIndex = -1;
mSpatialBridge = NULL;
LLViewerOctreeEntry* entry = NULL;
setOctreeEntry(entry);
initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
// static
@@ -142,6 +143,7 @@ void LLDrawable::destroy()
{
LL_INFOS() << "- Zombie drawables: " << sNumZombieDrawables << LL_ENDL;
}*/
}
void LLDrawable::markDead()
@@ -151,6 +153,7 @@ void LLDrawable::markDead()
LL_WARNS() << "Warning! Marking dead multiple times!" << LL_ENDL;
return;
}
setState(DEAD);
if (mSpatialBridge)
{
@@ -161,9 +164,8 @@ void LLDrawable::markDead()
sNumZombieDrawables++;
// We're dead. Free up all of our references to other objects
setState(DEAD);
cleanupReferences();
// sDeadList.put(this);
// sDeadList.push_back(this);
}
LLVOVolume* LLDrawable::getVOVolume() const
@@ -215,6 +217,8 @@ void LLDrawable::cleanupReferences()
gPipeline.unlinkDrawable(this);
removeFromOctree();
{
LLFastTimer t(FTM_DEREF_DRAWABLE);
// Cleanup references to other objects
@@ -223,6 +227,17 @@ void LLDrawable::cleanupReferences()
}
}
void LLDrawable::removeFromOctree()
{
if(!mEntry)
{
return;
}
mEntry->removeData(this);
mEntry = NULL;
}
void LLDrawable::cleanupDeadDrawables()
{
/*
@@ -236,7 +251,7 @@ void LLDrawable::cleanupDeadDrawables()
}
}
*/
sDeadList.reset();
sDeadList.clear();
}
S32 LLDrawable::findReferences(LLDrawable *drawablep)
@@ -481,6 +496,12 @@ void LLDrawable::makeActive()
}
updatePartition();
}
else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does...
{
mParent->makeActive();
//NOTE: linked set will now NEVER become static
mParent->setState(LLDrawable::ACTIVE_CHILD);
}
llassert(isAvatar() || isRoot() || mParent->isActive());
}
@@ -775,7 +796,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVOVolume* volume = getVOVolume();
if (volume)
{
if (getSpatialGroup())
if (getGroup())
{
pos.set(getPositionGroup().getF32ptr());
}
@@ -893,9 +914,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
}
mExtents[0].add(shift_vector);
mExtents[1].add(shift_vector);
mPositionGroup.add(shift_vector);
shift(shift_vector);
}
else if (mSpatialBridge)
{
@@ -903,9 +922,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
else if (isAvatar())
{
mExtents[0].add(shift_vector);
mExtents[1].add(shift_vector);
mPositionGroup.add(shift_vector);
shift(shift_vector);
}
mVObjp->onShift(shift_vector);
@@ -917,40 +934,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
return mXform.getPositionW();
}
const LLVector4a* LLDrawable::getSpatialExtents() const
{
return mExtents;
}
void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max)
{
mExtents[0].load3(min.mV);
mExtents[1].load3(max.mV);
}
void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
{
mExtents[0] = min;
mExtents[1] = max;
}
void LLDrawable::setPositionGroup(const LLVector4a& pos)
{
mPositionGroup = pos;
}
void LLDrawable::updateSpatialExtents()
{
if (mVObjp)
{
mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]);
const LLVector4a* exts = getSpatialExtents();
LLVector4a extents[2];
extents[0] = exts[0];
extents[1] = exts[1];
mVObjp->updateSpatialExtents(extents[0], extents[1]);
setSpatialExtents(extents[0], extents[1]);
}
updateBinRadius();
if (mSpatialBridge.notNull())
{
mPositionGroup.splat(0.f);
getGroupPosition().splat(0.f);
}
}
@@ -959,11 +960,11 @@ void LLDrawable::updateBinRadius()
{
if (mVObjp.notNull())
{
mBinRadius = llmin(mVObjp->getBinRadius(), 256.f);
setBinRadius(llmin(mVObjp->getBinRadius(), 256.f));
}
else
{
mBinRadius = llmin(getRadius()*4.f, 256.f);
setBinRadius(llmin(getRadius()*4.f, 256.f));
}
}
@@ -997,26 +998,56 @@ void LLDrawable::updateUVMinMax()
{
}
LLSpatialGroup* LLDrawable::getSpatialGroup() const
//virtual
bool LLDrawable::isVisible() const
{
if (LLViewerOctreeEntryData::isVisible())
{
llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
return mSpatialGroupp;
return true;
}
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
//precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
LLViewerOctreeGroup* group = mEntry->getGroup();
if (group && group->isVisible())
{
LLViewerOctreeEntryData::setVisible();
return true;
}
}
return false;
}
//virtual
bool LLDrawable::isRecentlyVisible() const
{
//currently visible or visible in the previous frame.
bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
if(!vis)
{
const U32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
vis = (sCurVisible - getVisible() < MIN_VIS_FRAME_RANGE);
}
return vis ;
}
void LLDrawable::setGroup(LLViewerOctreeGroup *groupp)
{
LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup();
//precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this
//llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this));
//precondition: groupp MUST be null or groupp MUST contain this
llassert(!groupp || groupp->hasElement(this));
llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
{
mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
}*/
if (mSpatialGroupp != groupp && getVOVolume())
if (cur_groupp != groupp && getVOVolume())
{ //NULL out vertex buffer references for volumes on spatial group change to maintain
//requirement that every face vertex buffer is either NULL or points to a vertex buffer
//contained by its drawable's spatial group
@@ -1032,10 +1063,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
//postcondition: if next group is NOT NULL, binIndex must not be -1
llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
getBinIndex() != -1);
//llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
// getBinIndex() != -1);
mSpatialGroupp = groupp;
LLViewerOctreeEntryData::setGroup(groupp);
}
LLSpatialPartition* LLDrawable::getSpatialPartition()
@@ -1081,89 +1112,18 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
//static
S32 LLDrawable::getMinVisFrameRange()
{
return MIN_VIS_FRAME_RANGE ;
}
BOOL LLDrawable::isRecentlyVisible() const
{
//currently visible or visible in the previous frame.
BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
if(!vis)
{
LLSpatialGroup* group = getSpatialGroup();
if (group && group->isRecentlyVisible())
{
mVisible = sCurVisible;
vis = TRUE ;
}
}
return vis ;
}
BOOL LLDrawable::isVisible() const
{
if (mVisible == sCurVisible)
{
return TRUE;
}
#if 0
//disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result.
//should be safe to just always ask the spatial group for visibility.
if (isActive())
{
if (isRoot())
{
LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() :
getSpatialGroup();
if (group && group->isVisible())
{
mVisible = sCurVisible;
return TRUE;
}
}
else
{
if (getParent()->isVisible())
{
mVisible = sCurVisible;
return TRUE;
}
}
}
else
#endif
{
LLSpatialGroup* group = getSpatialGroup();
if (group && group->isVisible())
{
mVisible = sCurVisible;
return TRUE;
}
}
return FALSE;
}
//=======================================
// Spatial Partition Bridging Drawable
//=======================================
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) :
LLDrawable(root->getVObj()),
LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
{
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
mBinIndex = -1;
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1184,10 +1144,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLSpatialBridge::~LLSpatialBridge()
{
if(mEntry)
{
LLSpatialGroup* group = getSpatialGroup();
if (group)
{
group->mSpatialPartition->remove(this, group);
group->getSpatialPartition()->remove(this, group);
}
}
//delete octree here so listeners will still be able to access bridge specific state
@@ -1209,10 +1172,10 @@ void LLSpatialBridge::updateSpatialExtents()
root->rebound();
}
const LLVector4a* root_bounds = root->getBounds();
LLVector4a offset;
LLVector4a size = root->mBounds[1];
LLVector4a size = root_bounds[1];
//VECTORIZE THIS
const LLMatrix4a& mat = mDrawable->getXform()->getWorldMatrix();
LLVector4a t;
@@ -1221,7 +1184,7 @@ void LLSpatialBridge::updateSpatialExtents()
LLVector4a center;
mat.affineTransform(t, center);
mat.rotate(root->mBounds[0], offset);
mat.rotate(root_bounds[0], offset);
center.add(offset);
LLVector4a v[4];
@@ -1243,8 +1206,8 @@ void LLSpatialBridge::updateSpatialExtents()
scale.mul(size);
mat.rotate(scale, v[3]);
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
LLVector4a newMin;
LLVector4a newMax;
newMin = newMax = center;
for (U32 i = 0; i < 4; i++)
{
@@ -1258,19 +1221,21 @@ void LLSpatialBridge::updateSpatialExtents()
newMin.setMin(newMin, min);
newMax.setMax(newMax, max);
}
setSpatialExtents(newMin, newMax);
LLVector4a diagonal;
diagonal.setSub(newMax, newMin);
mRadius = diagonal.getLength3().getF32() * 0.5f;
mPositionGroup.setAdd(newMin,newMax);
mPositionGroup.mul(0.5f);
LLVector4a& pos = getGroupPosition();
pos.setAdd(newMin,newMax);
pos.mul(0.5f);
updateBinRadius();
}
void LLSpatialBridge::updateBinRadius()
{
mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f);
setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));
}
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
@@ -1312,7 +1277,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
{
mVisible = sCurVisible;
LLViewerOctreeEntryData::setVisible();
#if 0 && !LL_RELEASE_FOR_DOWNLOAD
//crazy paranoid rules checking
@@ -1347,21 +1312,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,
#endif
}
class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable>
class LLOctreeMarkNotCulled: public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { }
virtual void traverse(const LLOctreeNode<LLDrawable>* node)
virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
group->setVisible();
LLOctreeTraveler<LLDrawable>::traverse(node);
OctreeTraveler::traverse(node);
}
void visit(const LLOctreeNode<LLDrawable>* branch)
void visit(const OctreeNode* branch)
{
gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera);
}
@@ -1405,7 +1370,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
if (!group ||
LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
impostor ||
!loaded)
{
@@ -1556,9 +1521,7 @@ BOOL LLSpatialBridge::updateMove()
void LLSpatialBridge::shiftPos(const LLVector4a& vec)
{
mExtents[0].add(vec);
mExtents[1].add(vec);
mPositionGroup.add(vec);
LLDrawable::shift(vec);
}
void LLSpatialBridge::cleanupReferences()

View File

@@ -44,10 +44,10 @@
#include "llvector4a.h"
#include "llquaternion.h"
#include "xform.h"
#include "lldarray.h"
#include "llviewerobject.h"
#include "llrect.h"
#include "llappviewer.h" // for gFrameTimeSeconds
#include "llvieweroctree.h"
class LLCamera;
class LLDrawPool;
@@ -65,10 +65,12 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
LL_ALIGN_PREFIX(16)
class LLDrawable : public LLRefCount
class LLDrawable
: public LLViewerOctreeEntryData
{
public:
LLDrawable(const LLDrawable& rhs)
: LLViewerOctreeEntryData(rhs)
{
*this = rhs;
}
@@ -91,7 +93,7 @@ public:
ll_aligned_free_16(ptr);
}
LLDrawable() { init(); }
LLDrawable(LLViewerObject *vobj);
void markDead(); // Mark this drawable as dead
BOOL isDead() const { return isState(DEAD); }
@@ -99,11 +101,9 @@ public:
BOOL isLight() const;
BOOL isVisible() const;
BOOL isRecentlyVisible() const;
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();}
LLViewerRegion* getRegion() const { return mVObjp->getRegion(); }
const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }
LLPointer<LLViewerObject>& getVObj() { return mVObjp; }
@@ -116,16 +116,12 @@ public:
const LLVector3& getPosition() const { return mXform.getPosition(); }
const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
const LLVector3 getPositionAgent() const;
const LLVector4a& getPositionGroup() const { return mPositionGroup; }
const LLVector3& getScale() const { return mCurrentScale; }
void setScale(const LLVector3& scale) { mCurrentScale = scale; }
const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); }
const LLQuaternion& getRotation() const { return mXform.getRotation(); }
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
F32 getBinRadius() const { return mBinRadius; }
S32 getBinIndex() const { return mBinIndex; }
void setBinIndex(S32 index) const { mBinIndex = index; }
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
LLXformMatrix* getXform() { return &mXform; }
@@ -189,8 +185,12 @@ public:
BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; }
void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); }
bool isVisible() const;
bool isRecentlyVisible() const;
virtual void cleanupReferences();
void setGroup(LLViewerOctreeGroup* group);
void setRadius(const F32 radius);
F32 getRadius() const { return mRadius; }
F32 getVisibilityRadius() const;
@@ -200,11 +200,6 @@ public:
const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
virtual void updateSpatialExtents();
virtual void updateBinRadius();
const LLVector4a* getSpatialExtents() const;
void setSpatialExtents(const LLVector3& min, const LLVector3& max);
void setSpatialExtents(const LLVector4a& min, const LLVector4a& max);
void setPositionGroup(const LLVector4a& pos);
void setRenderType(S32 type) { mRenderType = type; }
BOOL isRenderType(S32 type) { return mRenderType == type; }
@@ -213,10 +208,13 @@ public:
// Debugging methods
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
void setSpatialGroup(LLSpatialGroup *groupp);
LLSpatialGroup *getSpatialGroup() const;
LLSpatialPartition* getSpatialPartition();
void removeFromOctree();
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
// Statics
static void incrementVisible();
static void cleanupDeadDrawables();
@@ -299,10 +297,6 @@ public:
ANIMATED_CHILD = 0x20000000,
ACTIVE_CHILD = 0x40000000,
} EDrawableFlags;
private: //aligned members
LL_ALIGN_16(LLVector4a mExtents[2]);
LL_ALIGN_16(LLVector4a mPositionGroup);
public:
LL_ALIGN_16(LLXformMatrix mXform);
@@ -312,12 +306,6 @@ public:
F32 mDistanceWRTCamera;
static S32 getCurrentFrame() { return sCurVisible; }
static S32 getMinVisFrameRange();
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
static F32 sCurPixelAngle; //current pixels per radian
private:
@@ -327,21 +315,15 @@ private:
S32 mRenderType;
LLPointer<LLViewerObject> mVObjp;
face_list_t mFaces;
LLSpatialGroup* mSpatialGroupp;
LLPointer<LLDrawable> mSpatialBridge;
mutable U32 mVisible;
F32 mRadius;
F32 mBinRadius;
mutable S32 mBinIndex;
S32 mGeneration;
LLVector3 mCurrentScale;
static U32 sCurVisible; // Counter for what value of mVisible means currently visible
static U32 sNumZombieDrawables;
static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
static std::vector<LLPointer<LLDrawable> > sDeadList;
} LL_ALIGN_POSTFIX(16);

View File

@@ -303,7 +303,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (group->mSpatialPartition->mRenderByGroup &&
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -343,14 +343,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
LLSpatialGroup* group = *i;
llassert(group);
llassert(group->mSpatialPartition);
llassert(group->getSpatialPartition());
if (group->mSpatialPartition->mRenderByGroup &&
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
bool is_particle_or_hud_particle = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CLOUD
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_CLOUD
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
bool draw_glow_for_this_partition = !depth_only && mVertexShaderLevel > 0; // no shaders = no glow.

View File

@@ -2512,7 +2512,7 @@ void LLFace::renderSetColor() const
}
}
S32 LLFace::pushVertices(const U16* index_array) const
S32 LLFace::pushVertices() const
{
if (mIndicesCount)
{
@@ -2533,19 +2533,19 @@ const LLMatrix4a& LLFace::getRenderMatrix() const
return mDrawablep->getRenderMatrix();
}
S32 LLFace::renderElements(const U16 *index_array) const
S32 LLFace::renderElements() const
{
S32 ret = 0;
if (isState(GLOBAL))
{
ret = pushVertices(index_array);
ret = pushVertices();
}
else
{
gGL.pushMatrix();
gGL.multMatrix(getRenderMatrix());
ret = pushVertices(index_array);
ret = pushVertices();
gGL.popMatrix();
}
@@ -2570,8 +2570,7 @@ S32 LLFace::renderIndexed(U32 mask)
}
mVertexBuffer->setBuffer(mask);
U16* index_array = (U16*) mVertexBuffer->getIndicesPointer();
return renderElements(index_array);
return renderElements();
}
//============================================================================

View File

@@ -37,7 +37,6 @@
#include "v4coloru.h"
#include "llquaternion.h"
#include "xform.h"
#include "lldarrayptr.h"
#include "llvertexbuffer.h"
#include "llviewertexture.h"
#include "llstat.h"
@@ -137,10 +136,10 @@ public:
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
void renderSetColor() const;
S32 renderElements(const U16 *index_array) const;
S32 renderElements() const;
S32 renderIndexed ();
S32 renderIndexed (U32 mask);
S32 pushVertices(const U16* index_array) const;
S32 pushVertices() const;
void setWorldMatrix(const LLMatrix4& mat);
const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); }

View File

@@ -1235,9 +1235,9 @@ void LLFloaterAvatarList::sendKeys() const
std::ostringstream ids;
U32 num_ids = 0;
for (S32 i = 0; i < regionp->mMapAvatarIDs.count(); ++i)
for (S32 i = 0; i < regionp->mMapAvatarIDs.size(); ++i)
{
ids << "," << regionp->mMapAvatarIDs.get(i);
ids << "," << regionp->mMapAvatarIDs.at(i);
++num_ids;
if (ids.tellp() > 200)
{

View File

@@ -79,17 +79,17 @@ void LLFloaterBulkPermission::doApply()
class ModifiableGatherer : public LLSelectedNodeFunctor
{
public:
ModifiableGatherer(LLDynamicArray<LLUUID>& q) : mQueue(q) {}
ModifiableGatherer(std::vector<LLUUID>& q) : mQueue(q) {}
virtual bool apply(LLSelectNode* node)
{
if( node->allowOperationOnNode(PERM_MODIFY, GP_OBJECT_MANIPULATE) )
{
mQueue.put(node->getObject()->getID());
mQueue.push_back(node->getObject()->getID());
}
return true;
}
private:
LLDynamicArray<LLUUID>& mQueue;
std::vector<LLUUID>& mQueue;
};
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
list->deleteAllItems();
@@ -190,7 +190,7 @@ BOOL LLFloaterBulkPermission::nextObject()
BOOL successful_start = FALSE;
do
{
count = mObjectIDs.count();
count = mObjectIDs.size();
//LL_INFOS() << "Objects left to process = " << count << LL_ENDL;
mCurrentObjectID.setNull();
if(count > 0)
@@ -198,7 +198,7 @@ BOOL LLFloaterBulkPermission::nextObject()
successful_start = popNext();
//LL_INFOS() << (successful_start ? "successful" : "unsuccessful") << LL_ENDL;
}
} while((mObjectIDs.count() > 0) && !successful_start);
} while((mObjectIDs.size() > 0) && !successful_start);
if(isDone() && !mDone)
{
@@ -214,12 +214,12 @@ BOOL LLFloaterBulkPermission::popNext()
{
// get the head element from the container, and attempt to get its inventory.
BOOL rv = FALSE;
S32 count = mObjectIDs.count();
S32 count = mObjectIDs.size();
if(mCurrentObjectID.isNull() && (count > 0))
{
mCurrentObjectID = mObjectIDs.get(0);
mCurrentObjectID = mObjectIDs.at(0);
//LL_INFOS() << "mCurrentID: " << mCurrentObjectID << LL_ENDL;
mObjectIDs.remove(0);
mObjectIDs.erase(mObjectIDs.begin());
LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
if(obj)
{

View File

@@ -34,7 +34,6 @@
#ifndef LL_LLBULKPERMISSION_H
#define LL_LLBULKPERMISSION_H
#include "lldarray.h"
#include "llinventory.h"
#include "llviewerobject.h"
#include "llvoinventorylistener.h"
@@ -82,7 +81,7 @@ private:
void onUncheckAll() { doCheckUncheckAll(FALSE); }
// returns true if this is done
BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); }
BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.size() == 0)); }
//Read the settings and Apply the permissions
void doApply();
@@ -90,7 +89,7 @@ private:
private:
// Object Queue
LLDynamicArray<LLUUID> mObjectIDs;
std::vector<LLUUID> mObjectIDs;
LLUUID mCurrentObjectID;
BOOL mDone;

View File

@@ -741,7 +741,7 @@ void LLFloaterCustomize::saveCurrentWearables()
LLAppearanceMgr::instance().findCOFItemLinks(wearable->getItemID());
if (links.size()>0)
{
link_item = links.get(0).get();
link_item = links.at(0).get();
if (link_item && link_item->getIsLinkType())
{
description = link_item->getActualDescription();
@@ -753,15 +753,11 @@ void LLFloaterCustomize::saveCurrentWearables()
if (link_item)
{
// Create new link
link_inventory_item( gAgent.getID(),
link_item->getLinkedUUID(),
link_inventory_object(
LLAppearanceMgr::instance().getCOF(),
link_item->getName(),
description,
LLAssetType::AT_LINK,
NULL);
link_item, NULL);
// Remove old link
gInventory.purgeObject(link_item->getUUID());
remove_inventory_object(link_item->getUUID(), NULL);
}
}
gAgentWearables.saveWearable( cur, i );

View File

@@ -39,8 +39,6 @@
#include "llfloater.h"
#include "lldarray.h"
class LLScrollContainer;
class LLView;
class LLButton;

View File

@@ -244,10 +244,10 @@ const LLUUID& LLFloaterLandmark::findItemID(const LLUUID& asset_id, BOOL copyabl
LLInventoryModel::INCLUDE_TRASH,
asset_id_matches);
if (items.count())
if (items.size())
{
// search for copyable version first
for (S32 i = 0; i < items.count(); i++)
for (S32 i = 0; i < items.size(); i++)
{
LLInventoryItem* itemp = items[i];
LLPermissions item_permissions = itemp->getPermissions();
@@ -352,15 +352,6 @@ void LLFloaterLandmark::onBtnDelete()
gInventory.notifyObservers();
}
}
// Delete the item entirely
/*
item->removeFromServer();
gInventory.deleteObject(item->getUUID());
gInventory.notifyObservers();
*/
}
void LLFloaterLandmark::onBtnRename()

View File

@@ -129,7 +129,7 @@ void LLFloaterOpenObject::dirty()
void LLFloaterOpenObject::moveToInventory(bool wear)
void LLFloaterOpenObject::moveToInventory(bool wear, bool replace)
{
if (mObjectSelection->getRootObjectCount() != 1)
{
@@ -157,40 +157,34 @@ 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,replace);
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLFolderType::FT_NONE,
name,
callbackCreateInventoryCategory,
(void*)cat_data);
LLFolderType::FT_NONE,
name,
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() )
{
LLSD result;
result["folder_id"] = category_id;
//Reduce redundant code by just calling the callback. Dur.
callbackCreateInventoryCategory(result,cat_data);
callbackCreateInventoryCategory(category_id, object_id, wear);
}
}
// static
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace)
{
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;
wear_data->mReplace = replace;
// 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)
@@ -200,7 +194,6 @@ void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, vo
LLNotificationsUtil::add("OpenObjectCannotCopy");
}
delete cat_data;
}
// static

View File

@@ -64,6 +64,7 @@ public:
LLUUID mCatID;
bool mWear;
bool mFolderResponded;
bool mReplace;
};
protected:
@@ -73,11 +74,11 @@ protected:
void refresh();
void draw();
void moveToInventory(bool wear);
void moveToInventory(bool wear, bool replace = false);
static void onClickMoveToInventory(void* data);
static void onClickMoveAndWear(void* data);
static void callbackCreateInventoryCategory(const LLSD& result, void* data);
static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false);
static void callbackMoveInventory(S32 result, void* data);
static void* createPanelInventory(void* data);

View File

@@ -328,7 +328,7 @@ void LLFloaterOutbox::updateFolderCount()
LLInventoryModel::item_array_t * items;
gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
item_count = cats->count() + items->count();
item_count = cats->size() + items->size();
}
mOutboxItemCount = item_count;

View File

@@ -618,9 +618,9 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
buildLandmarkIDLists();
BOOL found = FALSE;
S32 idx;
for (idx = 0; idx < mLandmarkItemIDList.count(); idx++)
for (idx = 0; idx < mLandmarkItemIDList.size(); idx++)
{
if ( mLandmarkItemIDList.get(idx) == landmark_item_id)
if ( mLandmarkItemIDList.at(idx) == landmark_item_id)
{
found = TRUE;
break;
@@ -629,13 +629,13 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
if (found && iface->setCurrentByID( landmark_item_id ) )
{
LLUUID asset_id = mLandmarkAssetIDList.get( idx );
LLUUID asset_id = mLandmarkAssetIDList.at( idx );
std::string name;
LLComboBox* combo = getChild<LLComboBox>( "landmark combo");
if (combo) name = combo->getSimple();
mTrackedStatus = LLTracker::TRACKING_LANDMARK;
LLTracker::trackLandmark(mLandmarkAssetIDList.get( idx ), // assetID
mLandmarkItemIDList.get( idx ), // itemID
LLTracker::trackLandmark(mLandmarkAssetIDList.at( idx ), // assetID
mLandmarkItemIDList.at( idx ), // itemID
name); // name
if( asset_id != sHomeID )
@@ -1026,15 +1026,15 @@ void LLFloaterWorldMap::buildLandmarkIDLists()
list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
}
mLandmarkItemIDList.reset();
mLandmarkAssetIDList.reset();
mLandmarkItemIDList.clear();
mLandmarkAssetIDList.clear();
// Get all of the current landmarks
mLandmarkAssetIDList.put( LLUUID::null );
mLandmarkItemIDList.put( LLUUID::null );
mLandmarkAssetIDList.push_back(LLUUID::null);
mLandmarkItemIDList.push_back(LLUUID::null);
mLandmarkAssetIDList.put( sHomeID );
mLandmarkItemIDList.put( sHomeID );
mLandmarkAssetIDList.push_back(sHomeID);
mLandmarkItemIDList.push_back(sHomeID);
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
@@ -1047,15 +1047,15 @@ void LLFloaterWorldMap::buildLandmarkIDLists()
std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
S32 count = items.count();
S32 count = items.size();
for(S32 i = 0; i < count; ++i)
{
LLInventoryItem* item = items.get(i);
LLInventoryItem* item = items.at(i);
list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());
mLandmarkAssetIDList.put( item->getAssetUUID() );
mLandmarkItemIDList.put( item->getUUID() );
mLandmarkAssetIDList.push_back(item->getAssetUUID());
mLandmarkItemIDList.push_back(item->getUUID());
}
list->sortByColumn(std::string("landmark name"), TRUE);

View File

@@ -37,7 +37,6 @@
#ifndef LL_LLFLOATERWORLDMAP_H
#define LL_LLFLOATERWORLDMAP_H
#include "lldarray.h"
#include "llfloater.h"
#include "llhudtext.h"
#include "llmapimagetype.h"
@@ -170,8 +169,8 @@ private:
// enable/disable teleport destination coordinates
void enableTeleportCoordsDisplay( bool enabled );
LLDynamicArray<LLUUID> mLandmarkAssetIDList;
LLDynamicArray<LLUUID> mLandmarkItemIDList;
std::vector<LLUUID> mLandmarkAssetIDList;
std::vector<LLUUID> mLandmarkItemIDList;
static const LLUUID sHomeID;

View File

@@ -176,7 +176,7 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
// Default constructor
LLFolderView::LLFolderView( const std::string& name,
const LLRect& rect, const LLUUID& source_id, LLPanel* parent_panel, LLFolderViewEventListener* listener ) :
const LLRect& rect, const LLUUID& source_id, LLPanel* parent_panel, LLFolderViewEventListener* listener, LLFolderViewGroupedItemModel* group_model ) :
#if LL_WINDOWS
#pragma warning( push )
#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
@@ -211,7 +211,8 @@ LLFolderView::LLFolderView( const std::string& name,
mUseEllipses(FALSE),
mDraggingOverItem(NULL),
mStatusTextBox(NULL),
mSearchType(1)
mSearchType(1),
mGroupedItemModel(group_model)
{
LLPanel* panel = parent_panel;
mParentPanel = panel->getHandle();
@@ -1053,9 +1054,9 @@ void LLFolderView::removeCutItems()
return;
// Get the list of clipboard item uuids and iterate through them
LLDynamicArray<LLUUID> objects;
std::vector<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
for (std::vector<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
{
@@ -1123,7 +1124,7 @@ void LLFolderView::removeSelectedItems( void )
}
else if (count > 1)
{
LLDynamicArray<LLFolderViewEventListener*> listeners;
std::vector<LLFolderViewEventListener*> listeners;
LLFolderViewEventListener* listener;
LLFolderViewItem* last_item = items[count - 1];
LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
@@ -1151,12 +1152,12 @@ void LLFolderView::removeSelectedItems( void )
for(S32 i = 0; i < count; ++i)
{
listener = items[i]->getListener();
if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
if(listener && (std::find(listeners.begin(), listeners.end(), listener) == listeners.end()))
{
listeners.put(listener);
listeners.push_back(listener);
}
}
listener = listeners.get(0);
listener = listeners.at(0);
if(listener)
{
listener->removeBatch(listeners);
@@ -2362,6 +2363,14 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
flags = 0x0;
}
// This adds a check for restrictions based on the entire
// selection set - for example, any one wearable may not push you
// over the limit, but all wearables together still might.
if (getFolderViewGroupedItemModel())
{
getFolderViewGroupedItemModel()->groupFilterContextMenu(mSelectedItems, *menu);
}
addNoOptions(menu);
}

View File

@@ -45,7 +45,6 @@
#include "lluictrl.h"
#include "v4color.h"
#include "lldarray.h"
#include "stdenums.h"
#include "lldepthstack.h"
#include "lleditmenuhandler.h"
@@ -54,6 +53,7 @@
#include "llviewertexture.h"
class LLFolderViewEventListener;
class LLFolderViewGroupedItemModel;
class LLFolderViewFolder;
class LLFolderViewItem;
class LLInventoryModel;
@@ -78,13 +78,19 @@ public:
LLFolderView( const std::string& name, const LLRect& rect,
const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener );
const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener, LLFolderViewGroupedItemModel* group_model = NULL );
typedef folder_view_item_deque selected_items_t;
virtual ~LLFolderView( void );
virtual BOOL canFocusChildren() const;
virtual LLFolderView* getRoot() { return this; }
LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() { return mGroupedItemModel; }
const LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() const { return mGroupedItemModel; }
// FolderViews default to sort by name. This will change that,
// and resort the items if necessary.
void setSortOrder(U32 order);
@@ -276,7 +282,6 @@ protected:
protected:
LLHandle<LLView> mPopupMenuHandle;
typedef std::deque<LLFolderViewItem*> selected_items_t;
selected_items_t mSelectedItems;
BOOL mKeyboardSelection;
BOOL mAllowMultiSelect;
@@ -322,6 +327,8 @@ protected:
LLHandle<LLPanel> mParentPanel;
LLFolderViewGroupedItemModel* mGroupedItemModel;
/**
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
* NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.

View File

@@ -25,7 +25,6 @@
#ifndef LLFOLDERVIEWEVENTLISTENER_H
#define LLFOLDERVIEWEVENTLISTENER_H
#include "lldarray.h" // *TODO: convert to std::vector
#include "llfoldertype.h"
#include "llfontgl.h" // just for StyleFlags enum
#include "llinventorytype.h"
@@ -72,7 +71,7 @@ public:
virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
virtual BOOL removeItem() = 0;
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
virtual void removeBatch(std::vector<LLFolderViewEventListener*>& batch) = 0;
virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
virtual BOOL isItemCopyable() const = 0;
virtual BOOL copyToClipboard() const = 0;

View File

@@ -27,7 +27,6 @@
#define LLFOLDERVIEWITEM_H
#include "llview.h"
#include "lldarray.h" // *TODO: Eliminate, forward declare
#include "lluiimage.h"
#include "lluictrl.h"
@@ -356,7 +355,7 @@ protected:
LLUIImagePtr icon_open,
LLUIImagePtr icon_link,
LLFolderView* root,
LLFolderViewEventListener* listener );
LLFolderViewEventListener* listener);
friend class LLBuildNewViewsScheduler;
friend class LLPanelObjectInventory;
@@ -573,4 +572,12 @@ public:
virtual void operator()(LLFolderViewEventListener* listener) = 0;
};
typedef std::deque<LLFolderViewItem*> folder_view_item_deque;
class LLFolderViewGroupedItemModel : public LLRefCount
{
public:
virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu) = 0;
};
#endif // LLFOLDERVIEWITEM_H

View File

@@ -96,7 +96,7 @@ LLFrameStats::LLFrameStats()
LLFrameStats::~LLFrameStats()
{
mFrameData.reset();
mFrameData.clear();
}
void LLFrameStats::start(const EStat stat)
@@ -149,7 +149,7 @@ void LLFrameStats::addFrameData()
gTerseObjectUpdates = 0;
mFrameData.put(frame_data);
mFrameData.push_back(frame_data);
if (mUseTimer)
{
if (mTimer.getElapsedTimeF32() > mStopTime)
@@ -162,11 +162,11 @@ void LLFrameStats::addFrameData()
void LLFrameStats::dump()
{
if (mFrameData.count())
if (mFrameData.size())
{
F32 total_time = 0;
S64 total_triangles = 0;
S32 total_frames = mFrameData.count();
S32 total_frames = mFrameData.size();
S32 total_num_objects = 0;
time_t cur_time;
@@ -191,7 +191,7 @@ void LLFrameStats::dump()
LL_INFOS() << "Couldn't open file for dumping frame stats!" << LL_ENDL;
return;
}
LL_INFOS() << "Dumping frame statistics for " << mFrameData.count() << " frames" << LL_ENDL;
LL_INFOS() << "Dumping frame statistics for " << mFrameData.size() << " frames" << LL_ENDL;
fprintf(fp, "Time\tNumTriangles\t");
@@ -203,7 +203,7 @@ void LLFrameStats::dump()
fprintf(fp, "Full Updates\tTerse Updates\tTotal Vorbis\tLong Vorbis\tNum Vorbis Decodes\t");
fprintf(fp, "\n");
for (i = 0; i < mFrameData.count(); i++)
for (i = 0; i < mFrameData.size(); i++)
{
total_time += mFrameData[i].mTotalDuration;
total_triangles += mFrameData[i].mNumTriangles;
@@ -247,7 +247,7 @@ void LLFrameStats::dump()
fprintf(fp, "\n");
fclose(fp);
}
mFrameData.reset();
mFrameData.clear();
}
void LLFrameStats::setTrackStats(const BOOL track_stats)
@@ -267,7 +267,7 @@ void LLFrameStats::setTrackStats(const BOOL track_stats)
if (track_stats)
{
// Reset the frame data
mFrameData.reset();
mFrameData.clear();
}
mTrackStats = track_stats;
}

View File

@@ -36,7 +36,6 @@
#include "stdtypes.h"
#include "llstat.h"
#include "llstring.h"
#include "lldarray.h"
#include "v4color.h"
#include "lltimer.h"
@@ -119,7 +118,7 @@ private:
LLStat mStats[NUM_STATS];
static std::string sStatLabels[NUM_STATS];
static LLColor4 sStatColors[NUM_STATS];
LLDynamicArray<FrameData> mFrameData;
std::vector<FrameData> mFrameData;
void stop();
};

View File

@@ -259,11 +259,11 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
items,
LLInventoryModel::EXCLUDE_TRASH,
giveable);
S32 count = cats.count();
S32 count = cats.size();
bool complete = true;
for(S32 i = 0; i < count; ++i)
{
if(!gInventory.isCategoryComplete(cats.get(i)->getUUID()))
if(!gInventory.isCategoryComplete(cats.at(i)->getUUID()))
{
complete = false;
break;
@@ -274,7 +274,7 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
LLNotificationsUtil::add("IncompleteInventory");
give_successful = false;
}
count = items.count() + cats.count();
count = items.size() + cats.size();
if(count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
@@ -475,10 +475,10 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
items,
LLInventoryModel::EXCLUDE_TRASH,
remove);
S32 count = items.count();
S32 count = items.size();
for(S32 i = 0; i < count; ++i)
{
gInventory.deleteObject(items.get(i)->getUUID());
gInventory.deleteObject(items.at(i)->getUUID());
}
gInventory.notifyObservers();
@@ -529,7 +529,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
// 66. I've cut it down a bit from there to give some pad.
S32 count = items.count() + cats.count();
S32 count = items.size() + cats.size();
if(count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
@@ -555,21 +555,21 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
memcpy(pos, &(cat->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
S32 i;
count = cats.count();
count = cats.size();
for(i = 0; i < count; ++i)
{
memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */
pos += sizeof(U8);
memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
memcpy(pos, &(cats.at(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
}
count = items.count();
count = items.size();
for(i = 0; i < count; ++i)
{
type = (U8)items.get(i)->getType();
type = (U8)items.at(i)->getType();
memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */
pos += sizeof(U8);
memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
memcpy(pos, &(items.at(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
}
pack_instant_message(

View File

@@ -225,7 +225,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
part->cull(*LLViewerCamera::getInstance(), &potentials);
}
}
}

View File

@@ -222,7 +222,7 @@ void LLGroupActions::startCall(const LLUUID& group_id)
}
// [/RLVa:KB]
LLUUID session_id = gIMMgr->addSession(gdata.mName, IM_SESSION_GROUP_START, group_id, true);
LLUUID session_id = gIMMgr->addSession(gdata.mName, IM_SESSION_GROUP_START, group_id);
if (session_id.isNull())
{
LL_WARNS() << "Error adding session" << LL_ENDL;

View File

@@ -35,7 +35,6 @@
#include "llfontgl.h"
#include "llpanel.h"
#include "lldarray.h"
#include "lltimer.h"
#include "llviewermessage.h"
#include "llnotifications.h"

View File

@@ -41,7 +41,6 @@
#include "llcoord.h"
#include "v3dmath.h"
#include "lldarray.h"
#include "llviewerwindow.h"
#include "llviewerobject.h"

View File

@@ -0,0 +1,155 @@
/**
* @file llhttpretrypolicy.h
* @brief Header for a retry policy class intended for use with http responders.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llhttpretrypolicy.h"
#include "llhttpstatuscodes.h"
#include "aihttpheaders.h"
// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
#include <curl/curl.h>
// Parses 'Retry-After' header contents and returns seconds until retry should occur.
bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait)
{
// *TODO: This needs testing! Not in use yet.
// Examples of Retry-After headers:
// Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
// Retry-After: 120
// Check for number of seconds version, first:
char* end = 0;
// Parse as double
double seconds = std::strtod(retry_after.c_str(), &end);
if (end != 0 && *end == 0)
{
// Successful parse
seconds_to_wait = (F32)seconds;
return true;
}
// Parse rfc1123 date.
time_t date = curl_getdate(retry_after.c_str(), NULL);
if (-1 == date) return false;
seconds_to_wait = (F64)date - LLTimer::getTotalSeconds();
return true;
}
LLAdaptiveRetryPolicy::LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries, bool retry_on_4xx):
mMinDelay(min_delay),
mMaxDelay(max_delay),
mBackoffFactor(backoff_factor),
mMaxRetries(max_retries),
mRetryOn4xx(retry_on_4xx)
{
init();
}
void LLAdaptiveRetryPolicy::init()
{
mDelay = mMinDelay;
mRetryCount = 0;
mShouldRetry = true;
}
void LLAdaptiveRetryPolicy::reset()
{
init();
}
bool LLAdaptiveRetryPolicy::getRetryAfter(const AIHTTPReceivedHeaders& headers, F32& retry_header_time)
{
AIHTTPReceivedHeaders::range_type results;
return headers.getValues("retry-after", results) && getSecondsUntilRetryAfter(results.first->second, retry_header_time);
}
void LLAdaptiveRetryPolicy::onSuccess()
{
init();
}
void LLAdaptiveRetryPolicy::onFailure(S32 status, const AIHTTPReceivedHeaders& headers)
{
F32 retry_header_time;
bool has_retry_header_time = getRetryAfter(headers,retry_header_time);
onFailureCommon(status, has_retry_header_time, retry_header_time);
}
void LLAdaptiveRetryPolicy::onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time)
{
if (!mShouldRetry)
{
LL_INFOS() << "keep on failing" << LL_ENDL;
return;
}
if (mRetryCount > 0)
{
mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
}
// Honor server Retry-After header.
// Status 503 may ask us to wait for a certain amount of time before retrying.
F32 wait_time = mDelay;
if (has_retry_header_time)
{
wait_time = retry_header_time;
}
if (mRetryCount>=mMaxRetries)
{
LL_INFOS() << "Too many retries " << mRetryCount << ", will not retry" << LL_ENDL;
mShouldRetry = false;
}
if (!mRetryOn4xx && !(status == HTTP_INTERNAL_ERROR_OTHER || ((500 <= status) && (status < 600))))
{
LL_INFOS() << "Non-server error " << status << ", will not retry" << LL_ENDL;
mShouldRetry = false;
}
if (mShouldRetry)
{
LL_INFOS() << "Retry count " << mRetryCount << " should retry after " << wait_time << LL_ENDL;
mRetryTimer.reset();
mRetryTimer.setTimerExpirySec(wait_time);
}
mRetryCount++;
}
bool LLAdaptiveRetryPolicy::shouldRetry(F32& seconds_to_wait) const
{
if (mRetryCount == 0)
{
// Called shouldRetry before any failure.
seconds_to_wait = F32_MAX;
return false;
}
seconds_to_wait = mShouldRetry ? (F32) mRetryTimer.getRemainingTimeF32() : F32_MAX;
return mShouldRetry;
}

View File

@@ -0,0 +1,88 @@
/**
* @file file llhttpretrypolicy.h
* @brief declarations for http retry policy class.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_RETRYPOLICY_H
#define LL_RETRYPOLICY_H
#include "lltimer.h"
#include "llthread.h"
class AIHTTPReceivedHeaders;
// This is intended for use with HTTP Clients/Responders, but is not
// specifically coupled with those classes.
class LLHTTPRetryPolicy: public LLThreadSafeRefCount
{
public:
LLHTTPRetryPolicy() {}
virtual ~LLHTTPRetryPolicy() {}
// Call after a sucess to reset retry state.
virtual void onSuccess() = 0;
// Call once after an HTTP failure to update state.
virtual void onFailure(S32 status, const AIHTTPReceivedHeaders& headers) = 0;
virtual bool shouldRetry(F32& seconds_to_wait) const = 0;
virtual void reset() = 0;
};
// Very general policy with geometric back-off after failures,
// up to a maximum delay, and maximum number of retries.
class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
{
public:
LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries, bool retry_on_4xx = false);
// virtual
void onSuccess();
void reset();
// virtual
void onFailure(S32 status, const AIHTTPReceivedHeaders& headers);
// virtual
bool shouldRetry(F32& seconds_to_wait) const;
protected:
void init();
bool getRetryAfter(const AIHTTPReceivedHeaders& headers, F32& retry_header_time);
void onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time);
private:
F32 mMinDelay; // delay never less than this value
F32 mMaxDelay; // delay never exceeds this value
F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay.
U32 mMaxRetries; // maximum number of times shouldRetry will return true.
F32 mDelay; // current delay.
U32 mRetryCount; // number of times shouldRetry has been called.
LLTimer mRetryTimer; // time until next retry.
bool mShouldRetry; // Becomes false after too many retries, or the wrong sort of status received, etc.
bool mRetryOn4xx; // Normally only retry on 5xx server errors.
};
#endif

View File

@@ -34,7 +34,6 @@
#define LL_LLHUDICON_H
#include "llpointer.h"
#include "lldarrayptr.h"
#include "llhudobject.h"
#include "v4color.h"
@@ -45,7 +44,6 @@
#include "llfontgl.h"
#include <set>
#include <vector>
#include "lldarray.h"
// Renders a 2D icon billboard floating at the location specified.
class LLDrawable;

View File

@@ -67,7 +67,7 @@ void LLHUDManager::updateEffects()
{
LLFastTimer ftm(FTM_HUD_EFFECTS);
S32 i;
for (i = 0; i < mHUDEffects.count(); i++)
for (i = 0; i < mHUDEffects.size(); i++)
{
LLHUDEffect *hep = mHUDEffects[i];
if (hep->isDead())
@@ -85,7 +85,7 @@ void LLHUDManager::sendEffects()
static LLCachedControl<bool> broadcast_viewer_effects(gSavedSettings, "BroadcastViewerEffects", true);
S32 i;
for (i = 0; i < mHUDEffects.count(); i++)
for (i = 0; i < mHUDEffects.size(); i++)
{
LLHUDEffect *hep = mHUDEffects[i];
if (hep->mType == LLHUDObject::LL_HUD_EFFECT_LOOKAT)
@@ -136,18 +136,18 @@ void LLHUDManager::sendEffects()
//static
void LLHUDManager::shutdownClass()
{
getInstance()->mHUDEffects.reset();
getInstance()->mHUDEffects.clear();
}
void LLHUDManager::cleanupEffects()
{
S32 i = 0;
while (i < mHUDEffects.count())
while (i < mHUDEffects.size())
{
if (mHUDEffects[i]->isDead())
{
mHUDEffects.remove(i);
mHUDEffects.erase(mHUDEffects.begin() + i);
}
else
{
@@ -171,7 +171,7 @@ LLHUDEffect *LLHUDManager::createViewerEffect(const U8 type, BOOL send_to_sim, B
hep->setNeedsSendToSim(send_to_sim);
hep->setOriginatedHere(originated_here);
mHUDEffects.put(hep);
mHUDEffects.push_back(hep);
return hep;
}
@@ -195,20 +195,20 @@ void LLHUDManager::processViewerEffect(LLMessageSystem *mesgsys, void **user_dat
effectp = NULL;
LLHUDEffect::getIDType(mesgsys, k, effect_id, effect_type);
S32 i;
for (i = 0; i < LLHUDManager::getInstance()->mHUDEffects.count(); i++)
for (i = 0; i < LLHUDManager::getInstance()->mHUDEffects.size(); i++)
{
LLHUDEffect *cur_effectp = LLHUDManager::getInstance()->mHUDEffects[i];
if (!cur_effectp)
{
LL_WARNS() << "Null effect in effect manager, skipping" << LL_ENDL;
LLHUDManager::getInstance()->mHUDEffects.remove(i);
LLHUDManager::getInstance()->mHUDEffects.erase(LLHUDManager::getInstance()->mHUDEffects.begin() + i);
i--;
continue;
}
if (cur_effectp->isDead())
{
// LL_WARNS() << "Dead effect in effect manager, removing" << LL_ENDL;
LLHUDManager::getInstance()->mHUDEffects.remove(i);
LLHUDManager::getInstance()->mHUDEffects.erase(LLHUDManager::getInstance()->mHUDEffects.begin() + i);
i--;
continue;
}

View File

@@ -36,7 +36,6 @@
// Responsible for managing all HUD elements.
#include "llhudobject.h"
#include "lldarray.h"
class LLViewerObject;
class LLHUDEffect;
@@ -65,7 +64,7 @@ public:
static LLColor4 sChildColor;
protected:
LLDynamicArrayPtr<LLPointer<LLHUDEffect> > mHUDEffects;
std::vector<LLPointer<LLHUDEffect> > mHUDEffects;
};
#endif // LL_LLHUDMANAGER_H

View File

@@ -207,7 +207,7 @@ private:
bool send_start_session_messages(
const LLUUID& temp_session_id,
const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids,
const std::vector<LLUUID>& ids,
EInstantMessage dialog)
{
if ( dialog == IM_SESSION_GROUP_START )
@@ -231,7 +231,7 @@ bool send_start_session_messages(
LLSD agents;
for (int i = 0; i < (S32) ids.size(); i++)
{
agents.append(ids.get(i));
agents.append(ids.at(i));
}
//we have a new way of starting conference calls now
@@ -276,7 +276,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
const LLUUID& session_id,
const LLUUID& other_participant_id,
const EInstantMessage& dialog,
const LLDynamicArray<LLUUID>& ids) :
const std::vector<LLUUID>& ids) :
LLFloater(log_label, LLRect(), log_label),
mStartCallOnInitialize(false),
mInputEditor(NULL),
@@ -682,7 +682,7 @@ private:
LLUUID mSessionID;
};
bool LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
bool LLFloaterIMPanel::inviteToSession(const std::vector<LLUUID>& ids)
{
LLViewerRegion* region = gAgent.getRegion();
if (!region)
@@ -690,7 +690,7 @@ bool LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
return FALSE;
}
S32 count = ids.count();
S32 count = ids.size();
if( isInviteAllowed() && (count > 0) )
{
@@ -703,7 +703,7 @@ bool LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
data["params"] = LLSD::emptyArray();
for (int i = 0; i < count; i++)
{
data["params"].append(ids.get(i));
data["params"].append(ids.at(i));
}
data["method"] = "invite";
@@ -930,8 +930,8 @@ BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop)
{
if (drop)
{
LLDynamicArray<LLUUID> ids;
ids.put(item->getCreatorUUID());
std::vector<LLUUID> ids;
ids.push_back(item->getCreatorUUID());
inviteToSession(ids);
}
return true;
@@ -952,17 +952,17 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
items,
LLInventoryModel::EXCLUDE_TRASH,
buddies);
S32 count = items.count();
S32 count = items.size();
if(count == 0)
{
return false;
}
else if(drop)
{
LLDynamicArray<LLUUID> ids;
std::vector<LLUUID> ids;
for(S32 i = 0; i < count; ++i)
{
ids.put(items.get(i)->getCreatorUUID());
ids.push_back(items.at(i)->getCreatorUUID());
}
inviteToSession(ids);
}

View File

@@ -60,7 +60,7 @@ public:
const LLUUID& session_id,
const LLUUID& target_id,
const EInstantMessage& dialog,
const LLDynamicArray<LLUUID>& ids = LLDynamicArray<LLUUID>());
const std::vector<LLUUID>& ids = std::vector<LLUUID>());
virtual ~LLFloaterIMPanel();
void onAvatarNameLookup(const LLAvatarName& avatar_name);
@@ -77,7 +77,7 @@ public:
// add target ids to the session.
// Return TRUE if successful, otherwise FALSE.
bool inviteToSession(const LLDynamicArray<LLUUID>& agent_ids);
bool inviteToSession(const std::vector<LLUUID>& agent_ids);
void addHistoryLine(const std::string &utf8msg,
LLColor4 incolor = LLColor4::white,

View File

@@ -615,8 +615,8 @@ LLUUID LLIMMgr::addSession(
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
{
LLDynamicArray<LLUUID> ids;
ids.put(other_participant_id);
std::vector<LLUUID> ids;
ids.push_back(other_participant_id);
floater = createFloater(session_id, other_participant_id, name, dialog, ids, true);
@@ -659,9 +659,9 @@ LLUUID LLIMMgr::addSession(
const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids)
const std::vector<LLUUID>& ids)
{
if (0 == ids.getLength())
if (0 == ids.size())
{
return LLUUID::null;
}
@@ -1050,7 +1050,7 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
const LLUUID& other_participant_id,
const std::string& session_label,
const EInstantMessage& dialog,
const LLDynamicArray<LLUUID>& ids,
const std::vector<LLUUID>& ids,
bool user_initiated)
{
if (session_id.isNull())
@@ -1098,9 +1098,9 @@ bool LLIMMgr::isNonFriendSessionNotified(const LLUUID& session_id)
void LLIMMgr::noteOfflineUsers(
LLFloaterIMPanel* floater,
const LLDynamicArray<LLUUID>& ids)
const std::vector<LLUUID>& ids)
{
S32 count = ids.count();
S32 count = ids.size();
if(count == 0)
{
const std::string& only_user = LLTrans::getString("only_user_message");
@@ -1112,11 +1112,11 @@ void LLIMMgr::noteOfflineUsers(
LLAvatarTracker& at = LLAvatarTracker::instance();
for(S32 i = 0; i < count; ++i)
{
info = at.getBuddyInfo(ids.get(i));
info = at.getBuddyInfo(ids.at(i));
std::string full_name;
if (info
&& !info->isOnline()
&& LLAvatarNameCache::getNSName(ids.get(i), full_name))
&& LLAvatarNameCache::getNSName(ids.at(i), full_name))
{
LLUIString offline = LLTrans::getString("offline_message");
offline.setArg("[NAME]", full_name);
@@ -1127,7 +1127,7 @@ void LLIMMgr::noteOfflineUsers(
}
void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater,
const LLDynamicArray<LLUUID>& ids)
const std::vector<LLUUID>& ids)
{
// Don't do this if we don't have a mute list.
LLMuteList *ml = LLMuteList::getInstance();
@@ -1136,12 +1136,12 @@ void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater,
return;
}
S32 count = ids.count();
S32 count = ids.size();
if(count > 0)
{
for(S32 i = 0; i < count; ++i)
{
if( ml->isMuted(ids.get(i)) )
if( ml->isMuted(ids.at(i)) )
{
LLUIString muted = LLTrans::getString("muted_message");

View File

@@ -92,7 +92,7 @@ public:
LLUUID addSession(const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids);
const std::vector<LLUUID>& ids);
// Creates a P2P session with the requisite handle for responding to voice calls
LLUUID addP2PSession(const std::string& name,
@@ -197,15 +197,15 @@ private:
const LLUUID& target_id,
const std::string& name,
const EInstantMessage& dialog,
const LLDynamicArray<LLUUID>& ids = LLDynamicArray<LLUUID>(),
const std::vector<LLUUID>& ids = std::vector<LLUUID>(),
bool user_initiated = false);
// This simple method just iterates through all of the ids, and
// prints a simple message if they are not online. Used to help
// reduce 'hello' messages to the linden employees unlucky enough
// to have their calling card in the default inventory.
void noteOfflineUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids);
void noteMutedUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids);
void noteOfflineUsers(LLFloaterIMPanel* panel, const std::vector<LLUUID>& ids);
void noteMutedUsers(LLFloaterIMPanel* panel, const std::vector<LLUUID>& ids);
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);

View File

@@ -71,6 +71,8 @@ typedef LLMemberListener<LLInventoryPanel> inventory_panel_listener_t;
bool LLInventoryAction::doToSelected(LLFolderView* folder, std::string action)
{
if (!folder)
return true;
LLInventoryModel* model = &gInventory;
if ("rename" == action)
{
@@ -133,43 +135,7 @@ bool LLInventoryAction::doToSelected(LLFolderView* folder, std::string action)
return true;
}
class LLDoToSelectedPanel : public object_inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLPanelObjectInventory *panel = mPtr;
LLFolderView* folder = panel->getRootFolder();
if(!folder) return true;
return LLInventoryAction::doToSelected(folder, userdata.asString());
}
};
class LLDoToSelectedFloater : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryPanel *panel = mPtr->getPanel();
LLFolderView* folder = panel->getRootFolder();
if(!folder) return true;
return LLInventoryAction::doToSelected(folder, userdata.asString());
}
};
class LLDoToSelected : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryPanel *panel = mPtr;
LLFolderView* folder = panel->getRootFolder();
if(!folder) return true;
return LLInventoryAction::doToSelected(folder, userdata.asString());
}
};
class LLNewWindow : public inventory_listener_t
struct LLNewWindow : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
@@ -190,105 +156,10 @@ class LLNewWindow : public inventory_listener_t
}
};
class LLShowFilters : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
mPtr->toggleFindOptions();
return true;
}
};
class LLResetFilter : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
mPtr->resetFilters();
return true;
}
};
class LLCloseAllFolders : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
mPtr->closeAllFolders();
return true;
}
};
class LLCloseAllFoldersFloater : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
mPtr->getPanel()->closeAllFolders();
return true;
}
};
class LLEmptyTrash : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getModel();
if(!model) return false;
LLNotificationsUtil::add("ConfirmEmptyTrash", LLSD(), LLSD(), boost::bind(&LLEmptyTrash::callback_empty_trash, this, _1, _2));
return true;
}
bool callback_empty_trash(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) // YES
{
LLInventoryModel* model = mPtr->getModel();
LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
model->purgeDescendentsOf(trash_id);
model->notifyObservers();
}
return false;
}
};
class LLEmptyLostAndFound : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getModel();
if(!model) return false;
LLNotificationsUtil::add("ConfirmEmptyLostAndFound", LLSD(), LLSD(), boost::bind(&LLEmptyLostAndFound::callback_empty_lost_and_found, this, _1, _2));
return true;
}
bool callback_empty_lost_and_found(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) // YES
{
LLInventoryModel* model = mPtr->getModel();
LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
model->purgeDescendentsOf(lost_and_found_id);
model->notifyObservers();
}
return false;
}
};
class LLEmptyTrashFloater : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getPanel()->getModel();
if(!model) return false;
LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
model->purgeDescendentsOf(trash_id);
model->notifyObservers();
return true;
}
};
void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, LLFolderBridge *self = NULL)
void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, const LLSD& sdtype, LLFolderBridge *self = NULL)
{
const std::string& type = sdtype.asString();
LL_INFOS() << "self=0x" << std::hex << self << std::dec << LL_ENDL;
if ("category" == type)
{
LLUUID category;
@@ -343,31 +214,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type,
ptr->getRootFolder()->setNeedsAutoRename(TRUE);
}
class LLDoCreate : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getModel();
if(!model) return false;
std::string type = userdata.asString();
do_create(model, mPtr, type, LLFolderBridge::sSelf.get());
return true;
}
};
class LLDoCreateFloater : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getPanel()->getModel();
if(!model) return false;
std::string type = userdata.asString();
do_create(model, mPtr->getPanel(), type);
return true;
}
};
class LLSetSortBy : public inventory_listener_t
struct LLSetSortBy : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
@@ -426,20 +273,7 @@ class LLSetSortBy : public inventory_listener_t
return true;
}
};
class LLRefreshInvModel : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLInventoryModel* model = mPtr->getPanel()->getModel();
if(!model) return false;
model->empty();
LLInventoryModelBackgroundFetch::instance().start();
return true;
}
};
class LLSetSearchType : public inventory_listener_t
struct LLSetSearchType : public inventory_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
@@ -451,7 +285,7 @@ class LLSetSearchType : public inventory_listener_t
}
};
class LLBeginIMSession : public inventory_panel_listener_t
struct LLBeginIMSession : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
@@ -463,7 +297,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
std::string name;
static int session_num = 1;
LLDynamicArray<LLUUID> members;
std::vector<LLUUID> members;
EInstantMessage type = IM_SESSION_CONFERENCE_START;
// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9)
@@ -495,7 +329,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_buddy);
S32 count = item_array.count();
S32 count = item_array.size();
if(count > 0)
{
// create the session
@@ -505,13 +339,13 @@ class LLBeginIMSession : public inventory_panel_listener_t
LLUUID id;
for(S32 i = 0; i < count; ++i)
{
id = item_array.get(i)->getCreatorUUID();
id = item_array.at(i)->getCreatorUUID();
if(at.isBuddyOnline(id))
{
// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9)
fRlvCanStartIM &= RlvActions::canStartIM(id);
// [RLVa:KB]
members.put(id);
members.push_back(id);
}
}
}
@@ -536,7 +370,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9)
fRlvCanStartIM &= RlvActions::canStartIM(id);
// [RLVa:KB]
members.put(id);
members.push_back(id);
}
}
} //if IT_CALLINGCARD
@@ -572,7 +406,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
}
};
class LLAttachObject : public inventory_panel_listener_t
struct LLAttachObject : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
@@ -584,10 +418,9 @@ class LLAttachObject : public inventory_panel_listener_t
LLUUID id = *selected_items.begin();
std::string joint_name = userdata.asString();
LLVOAvatar *avatarp = gAgentAvatarp;
LLViewerJointAttachment* attachmentp = NULL;
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end(); )
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end(); )
{
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
LLViewerJointAttachment* attachment = curiter->second;
@@ -601,7 +434,7 @@ class LLAttachObject : public inventory_panel_listener_t
{
return true;
}
if (LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id))
if (LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id))
{
if(gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
{
@@ -610,7 +443,10 @@ class LLAttachObject : public inventory_panel_listener_t
else if(item->isFinished())
{
// must be in library. copy it to our inventory and put it on.
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false));
// LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, attachmentp));
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4)
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, attachmentp, false));
// [/SL;KB]
copy_inventory_item(
gAgentID,
item->getPermissions().getOwner(),
@@ -628,42 +464,30 @@ class LLAttachObject : public inventory_panel_listener_t
void init_object_inventory_panel_actions(LLPanelObjectInventory *panel)
{
(new LLDoToSelectedPanel())->registerListener(panel, "Inventory.DoToSelected");
(new LLBindMemberListener(panel, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLPanelObjectInventory::getRootFolder, panel), _2)));
}
void init_inventory_actions(LLInventoryView *floater)
{
(new LLDoToSelectedFloater())->registerListener(floater, "Inventory.DoToSelected");
(new LLDoToSelectedFloater())->registerListener(floater, "Inventory.DoToSelected");
(new LLCloseAllFoldersFloater())->registerListener(floater, "Inventory.CloseAllFolders");
(new LLEmptyTrashFloater())->registerListener(floater, "Inventory.EmptyTrash");
(new LLDoCreateFloater())->registerListener(floater, "Inventory.DoCreate");
(new LLBindMemberListener(floater, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLInventoryView::getRootFolder, floater), _2)));
(new LLBindMemberListener(floater, "Inventory.CloseAllFolders", boost::bind(&LLInventoryPanel::closeAllFolders, boost::bind(&LLInventoryView::getPanel, floater))));
(new LLBindMemberListener(floater, "Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "", LLFolderType::FT_TRASH)));
(new LLBindMemberListener(floater, "Inventory.DoCreate", boost::bind(&do_create, &gInventory, boost::bind(&LLInventoryView::getPanel, floater), _2, (LLFolderBridge*)0)));
(new LLNewWindow())->registerListener(floater, "Inventory.NewWindow");
(new LLShowFilters())->registerListener(floater, "Inventory.ShowFilters");
(new LLResetFilter())->registerListener(floater, "Inventory.ResetFilter");
(new LLBindMemberListener(floater, "Inventory.ShowFilters", boost::bind(&LLInventoryView::toggleFindOptions, floater)));
(new LLBindMemberListener(floater, "Inventory.ResetFilter", boost::bind(&LLInventoryView::resetFilters, floater)));
(new LLSetSortBy())->registerListener(floater, "Inventory.SetSortBy");
(new LLSetSearchType())->registerListener(floater, "Inventory.SetSearchType");
}
class LLShare : public inventory_panel_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLAvatarActions::shareWithAvatars(mPtr);
return true;
}
};
void init_inventory_panel_actions(LLInventoryPanel *panel)
{
(new LLDoToSelected())->registerListener(panel, "Inventory.DoToSelected");
(new LLBindMemberListener(panel, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLInventoryPanel::getRootFolder, panel), _2)));
(new LLAttachObject())->registerListener(panel, "Inventory.AttachObject");
(new LLCloseAllFolders())->registerListener(panel, "Inventory.CloseAllFolders");
(new LLEmptyTrash())->registerListener(panel, "Inventory.EmptyTrash");
(new LLEmptyLostAndFound())->registerListener(panel, "Inventory.EmptyLostAndFound");
(new LLDoCreate())->registerListener(panel, "Inventory.DoCreate");
(new LLBindMemberListener(panel, "Inventory.CloseAllFolders", boost::bind(&LLInventoryPanel::closeAllFolders, panel)));
(new LLBindMemberListener(panel, "Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)));
(new LLBindMemberListener(panel, "Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)));
(new LLBindMemberListener(panel, "Inventory.DoCreate", boost::bind(&do_create, &gInventory, panel, _2, boost::bind(&LLHandle<LLFolderBridge>::get, boost::cref(LLFolderBridge::sSelf)))));
(new LLBeginIMSession())->registerListener(panel, "Inventory.BeginIMSession");
(new LLShare())->registerListener(panel, "Inventory.Share");
(new LLBindMemberListener(panel, "Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, panel)));
}

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@
#include "llcallingcard.h"
#include "llfloaterproperties.h"
#include "llfolderview.h"
#include "llfoldervieweventlistener.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
@@ -77,7 +78,7 @@ public:
// LLInvFVBridge functionality
//--------------------------------------------------------------------
virtual const LLUUID& getUUID() const { return mUUID; }
virtual void clearDisplayName() {}
virtual void clearDisplayName() { mDisplayName.clear(); }
virtual const std::string& getPrefix() { return LLStringUtil::null; }
virtual void restoreItem() {}
virtual void restoreToWorld() {}
@@ -87,9 +88,11 @@ public:
//--------------------------------------------------------------------
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
virtual PermissionMask getPermissionMask() const;
virtual LLFolderType::EType getPreferredType() const;
virtual time_t getCreationDate() const;
virtual void setCreationDate(time_t creation_date_utc);
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
virtual void openItem() {}
@@ -102,8 +105,9 @@ public:
virtual BOOL isItemMovable() const;
virtual BOOL isItemInTrash() const;
virtual BOOL isLink() const;
virtual BOOL isLibraryItem() const;
//virtual BOOL removeItem() = 0;
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
virtual void removeBatch(std::vector<LLFolderViewEventListener*>& batch);
virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const;
@@ -148,7 +152,6 @@ protected:
BOOL isAgentInventory() const; // false if lost or in the inventory library
BOOL isCOFFolder() const; // true if COF or descendant of
BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox
BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
BOOL isOutboxFolderDirectParent() const;
const LLUUID getOutboxFolder() const;
@@ -161,14 +164,19 @@ protected:
LLViewerInventoryCategory* item,
const LLUUID& new_parent,
BOOL restamp);
void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
void removeBatchNoCheck(std::vector<LLFolderViewEventListener*>& batch);
public:
BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
protected:
LLHandle<LLInventoryPanel> mInventoryPanel;
LLFolderView* mRoot;
const LLUUID mUUID; // item id
LLInventoryType::EType mInvType;
bool mIsLink;
mutable std::string mDisplayName;
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
virtual void buildDisplayName() const {}
};
class AIFilePicker;
@@ -206,7 +214,6 @@ public:
virtual void restoreToWorld();
virtual void gotoItem();
virtual LLUIImagePtr getIcon() const;
virtual const std::string& getDisplayName() const;
virtual std::string getLabelSuffix() const;
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual PermissionMask getPermissionMask() const;
@@ -217,19 +224,15 @@ public:
virtual BOOL isItemCopyable() const;
virtual bool hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
virtual LLUIImagePtr getIconOverlay() const;
static void showFloaterImagePreview(LLInventoryItem* item, AIFilePicker* filepicker);
/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
LLViewerInventoryItem* getItem() const;
protected:
BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
virtual BOOL isItemPermissive() const;
static void buildDisplayName(LLInventoryItem* item, std::string& name);
mutable std::string mDisplayName;
virtual void buildDisplayName() const;
};
class LLFolderBridge : public LLInvFVBridge
@@ -246,6 +249,8 @@ public:
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop);
virtual void buildDisplayName() const;
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
virtual void closeItem();
@@ -256,6 +261,8 @@ public:
virtual LLFolderType::EType getPreferredType() const;
virtual LLUIImagePtr getIcon() const;
virtual LLUIImagePtr getIconOpen() const;
virtual LLUIImagePtr getIconOverlay() const;
static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
virtual BOOL renameItem(const std::string& new_name);
@@ -285,8 +292,8 @@ public:
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
protected:
void buildContextMenuBaseOptions(U32 flags);
void buildContextMenuFolderOptions(U32 flags);
void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
//--------------------------------------------------------------------
// Menu callbacks
@@ -315,8 +322,6 @@ protected:
void modifyOutfit(BOOL append);
void determineFolderType();
menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
void dropToFavorites(LLInventoryItem* inv_item);
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
@@ -331,8 +336,6 @@ private:
bool mCallingCards;
bool mWearables;
menuentry_vec_t mItems;
menuentry_vec_t mDisabledItems;
LLRootHandle<LLFolderBridge> mHandle;
};
@@ -365,6 +368,7 @@ public:
virtual void openItem();
virtual void previewItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual void performAction(LLInventoryModel* model, std::string action);
static void openSoundPreview(void*);
};
@@ -660,4 +664,11 @@ void hide_context_entries(LLMenuGL& menu,
const menuentry_vec_t &entries_to_show,
const menuentry_vec_t &disabled_entries);
class LLFolderViewGroupedItemBridge: public LLFolderViewGroupedItemModel
{
public:
LLFolderViewGroupedItemBridge();
virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu);
};
#endif // LL_LLINVENTORYBRIDGE_H

View File

@@ -52,23 +52,23 @@ LLInventoryClipboard::~LLInventoryClipboard()
void LLInventoryClipboard::add(const LLUUID& object)
{
mObjects.put(object);
mObjects.push_back(object);
}
// this stores a single inventory object
void LLInventoryClipboard::store(const LLUUID& object)
{
reset();
mObjects.put(object);
mObjects.push_back(object);
}
void LLInventoryClipboard::store(const LLDynamicArray<LLUUID>& inv_objects)
void LLInventoryClipboard::store(const std::vector<LLUUID>& inv_objects)
{
reset();
S32 count = inv_objects.count();
S32 count = inv_objects.size();
for(S32 i = 0; i < count; i++)
{
mObjects.put(inv_objects[i]);
mObjects.push_back(inv_objects[i]);
}
}
@@ -82,26 +82,26 @@ void LLInventoryClipboard::cut(const LLUUID& object)
mCutMode = true;
add(object);
}
void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const
void LLInventoryClipboard::retrieve(std::vector<LLUUID>& inv_objects) const
{
inv_objects.reset();
S32 count = mObjects.count();
inv_objects.clear();
S32 count = mObjects.size();
for(S32 i = 0; i < count; i++)
{
inv_objects.put(mObjects[i]);
inv_objects.push_back(mObjects[i]);
}
}
void LLInventoryClipboard::reset()
{
mObjects.reset();
mObjects.clear();
mCutMode = false;
}
// returns true if the clipboard has something pasteable in it.
BOOL LLInventoryClipboard::hasContents() const
{
return (mObjects.count() > 0);
return (mObjects.size() > 0);
}
// returns true if the input uuid is in the list of clipboard objects.

View File

@@ -27,7 +27,6 @@
#ifndef LL_LLINVENTORYCLIPBOARD_H
#define LL_LLINVENTORYCLIPBOARD_H
#include "lldarray.h"
#include "lluuid.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -52,12 +51,12 @@ public:
void store(const LLUUID& object);
// this method stores an array of objects
void store(const LLDynamicArray<LLUUID>& inventory_objects);
void store(const std::vector<LLUUID>& inventory_objects);
void cut(const LLUUID& object);
// this method gets the objects in the clipboard by copying them
// into the array provided.
void retrieve(LLDynamicArray<LLUUID>& inventory_objects) const;
void retrieve(std::vector<LLUUID>& inventory_objects) const;
// this method empties out the clipboard
void reset();
@@ -73,7 +72,7 @@ public:
protected:
static LLInventoryClipboard sInstance;
LLDynamicArray<LLUUID> mObjects;
std::vector<LLUUID> mObjects;
bool mCutMode;
public:

View File

@@ -254,7 +254,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
S32 descendents_actual = 0;
if (cat_array && item_array)
{
descendents_actual = cat_array->count() + item_array->count();
descendents_actual = cat_array->size() + item_array->size();
}
if (descendents_actual == 0)
{

View File

@@ -154,12 +154,9 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
return;
}
LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
new_cat->rename(new_name);
new_cat->updateServer(FALSE);
model->updateCategory(new_cat);
model->notifyObservers();
LLSD updates;
updates["name"] = new_name;
update_inventory_category(cat_id, updates, NULL);
}
void copy_inventory_category(LLInventoryModel* model,
@@ -740,6 +737,13 @@ bool LLIsOfAssetType::operator()(LLInventoryCategory* cat, LLInventoryItem* item
return FALSE;
}
bool LLIsValidItemLink::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
if (!vitem) return false;
return (vitem->getActualType() == LLAssetType::AT_LINK && !vitem->getIsBrokenLink());
}
bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)

View File

@@ -186,6 +186,13 @@ protected:
LLAssetType::EType mType;
};
class LLIsValidItemLink : public LLInventoryCollectFunctor
{
public:
virtual bool operator()(LLInventoryCategory* cat,
LLInventoryItem* item);
};
class LLIsTypeWithPermissions : public LLInventoryCollectFunctor
{
public:

File diff suppressed because it is too large Load Diff

View File

@@ -27,33 +27,28 @@
#ifndef LL_LLINVENTORYMODEL_H
#define LL_LLINVENTORYMODEL_H
#include "llassettype.h"
#include "llfoldertype.h"
#include "lldarray.h"
#include "llframetimer.h"
#include "llhttpclient.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
#include "llmd5.h"
#include <map>
#include <set>
#include <string>
#include <vector>
#include "llassettype.h"
#include "llfoldertype.h"
#include "llframetimer.h"
#include "llhttpclient.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llviewerinventory.h"
#include "llstring.h"
#include "llmd5.h"
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy fetchInventoryResponder_timeout;
extern AIHTTPTimeoutPolicy FetchItemHttpHandler_timeout;
class LLInventoryObserver;
class LLInventoryObject;
class LLInventoryItem;
class LLInventoryCategory;
class LLViewerInventoryItem;
class LLViewerInventoryCategory;
class LLViewerInventoryItem;
class LLViewerInventoryCategory;
class LLMessageSystem;
class LLInventoryCollectFunctor;
@@ -79,19 +74,21 @@ public:
CHILDREN_MAYBE
};
typedef LLDynamicArray<LLPointer<LLViewerInventoryCategory> > cat_array_t;
typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t;
typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
typedef std::set<LLUUID> changed_items_t;
class fetchInventoryResponder : public LLHTTPClient::ResponderWithResult
class FetchItemHttpHandler : public LLHTTPClient::ResponderWithResult
{
public:
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
LOG_CLASS(FetchItemHttpHandler);
FetchItemHttpHandler(const LLSD& request_sd) : mRequestSD(request_sd) {};
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchInventoryResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "fetchInventoryResponder"; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return FetchItemHttpHandler_timeout; }
/*virtual*/ char const* getName(void) const { return "FetchItemHttpHandler"; }
protected:
LLSD mRequestSD;
};
@@ -147,6 +144,8 @@ public:
// during authentication. Returns true if everything parsed.
bool loadSkeleton(const LLSD& options, const LLUUID& owner_id);
void buildParentChildMap(); // brute force method to rebuild the entire parent-child relations
void createCommonSystemCategories();
// Call on logout to save a terse representation.
void cache(const LLUUID& parent_folder_id, const LLUUID& agent_id);
private:
@@ -165,6 +164,15 @@ private:
parent_cat_map_t mParentChildCategoryTree;
parent_item_map_t mParentChildItemTree;
// Track links to items and categories. We do not store item or
// category pointers here, because broken links are also supported.
typedef std::multimap<LLUUID, LLUUID> backlink_mmap_t;
backlink_mmap_t mBacklinkMMap; // key = target_id: ID of item, values = link_ids: IDs of item or folder links referencing it.
// For internal use only
bool hasBacklinkInfo(const LLUUID& link_id, const LLUUID& target_id) const;
void addBacklinkInfo(const LLUUID& link_id, const LLUUID& target_id);
void removeBacklinkInfo(const LLUUID& link_id, const LLUUID& target_id);
//--------------------------------------------------------------------
// Login
//--------------------------------------------------------------------
@@ -216,38 +224,58 @@ public:
EXCLUDE_TRASH = FALSE,
INCLUDE_TRASH = TRUE
};
// Simpler existence test if matches don't actually need to be collected.
bool hasMatchingDirectDescendent(const LLUUID& cat_id,
LLInventoryCollectFunctor& filter, bool follow_folder_links = false);
void collectDescendents(const LLUUID& id,
cat_array_t& categories,
item_array_t& items,
BOOL include_trash);
// [RLVa:KB] - Checked: 2013-04-15 (RLVa-1.4.8)
void collectDescendentsIf(const LLUUID& id,
cat_array_t& categories,
item_array_t& items,
BOOL include_trash,
LLInventoryCollectFunctor& add,
BOOL follow_folder_links = FALSE);
bool follow_folder_links = false);
// [/RLVa:KB]
// void collectDescendentsIf(const LLUUID& id,
// cat_array_t& categories,
// item_array_t& items,
// BOOL include_trash,
// LLInventoryCollectFunctor& add);
// Collect all items in inventory that are linked to item_id.
// Assumes item_id is itself not a linked item.
item_array_t collectLinkedItems(const LLUUID& item_id,
item_array_t collectLinksTo(const LLUUID& item_id,
const LLUUID& start_folder_id = LLUUID::null);
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id, const BOOL break_on_recursion=FALSE) const;
// Follow parent chain to the top.
bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find
//--------------------------------------------------------------------
public:
const LLUUID findCategoryUUIDForTypeInRoot(
LLFolderType::EType preferred_type,
bool create_folder,
const LLUUID& root_id);
// Returns the uuid of the category that specifies 'type' as what it
// defaults to containing. The category is not necessarily only for that type.
// NOTE: If create_folder is true, this will create a new inventory category
// on the fly if one does not exist. *NOTE: if find_in_library is true it
// will search in the user's library folder instead of "My Inventory"
const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type,
bool create_folder = true,
bool find_in_library = false);
bool create_folder = true);
// will search in the user's library folder instead of "My Inventory"
const LLUUID findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type,
bool create_folder = true);
// Get whatever special folder this object is a child of, if any.
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
@@ -309,7 +337,7 @@ public:
// NOTE: In usage, you will want to perform cache accounting
// operations in LLInventoryModel::accountForUpdate() or
// LLViewerInventoryItem::updateServer() before calling this method.
U32 updateItem(const LLViewerInventoryItem* item);
U32 updateItem(const LLViewerInventoryItem* item, U32 mask = 0);
// Change an existing item with the matching id or add
// the category. No notifcation will be sent to observers. This
@@ -318,7 +346,7 @@ public:
// NOTE: In usage, you will want to perform cache accounting
// operations in accountForUpdate() or LLViewerInventoryCategory::
// updateServer() before calling this method.
void updateCategory(const LLViewerInventoryCategory* cat);
void updateCategory(const LLViewerInventoryCategory* cat, U32 mask = 0);
// Move the specified object id to the specified category and
// update the internal structures. No cache accounting,
@@ -339,11 +367,31 @@ public:
// Delete
//--------------------------------------------------------------------
public:
// Update model after an AISv3 update received for any operation.
void onAISUpdateReceived(const std::string& context, const LLSD& update);
// Update model after an item is confirmed as removed from
// server. Works for categories or items.
void onObjectDeletedFromServer(const LLUUID& item_id,
bool fix_broken_links = true,
bool update_parent_version = true,
bool do_notify_observers = true);
// Update model after all descendents removed from server.
void onDescendentsPurgedFromServer(const LLUUID& object_id, bool fix_broken_links = true);
// Update model after an existing item gets updated on server.
void onItemUpdated(const LLUUID& item_id, const LLSD& updates, bool update_parent_version);
// Update model after an existing category gets updated on server.
void onCategoryUpdated(const LLUUID& cat_id, const LLSD& updates);
// Delete a particular inventory object by ID. Will purge one
// object from the internal data structures, maintaining a
// consistent internal state. No cache accounting, observer
// notification, or server update is performed.
void deleteObject(const LLUUID& id);
void deleteObject(const LLUUID& id, bool fix_broken_links = true, bool do_notify_observers = true);
/// move Item item_id to Trash
void removeItem(const LLUUID& item_id);
/// move Category category_id to Trash
@@ -351,17 +399,6 @@ public:
/// removeItem() or removeCategory(), whichever is appropriate
void removeObject(const LLUUID& object_id);
// Delete a particular inventory object by ID, and delete it from
// the server. Also updates linked items.
void purgeObject(const LLUUID& id);
// Collects and purges the descendants of the id
// provided. If the category is not found, no action is
// taken. This method goes through the long winded process of
// removing server representation of folders and items while doing
// cache accounting in a fairly efficient manner. This method does
// not notify observers (though maybe it should...)
void purgeDescendentsOf(const LLUUID& id);
protected:
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
@@ -399,9 +436,8 @@ 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);
public:
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
// should be passed pointers of newly created objects, and the
@@ -477,6 +513,7 @@ public:
// inventory. The next notify will include that notification.
void addChangedMask(U32 mask, const LLUUID& referent);
const changed_items_t& getChangedIDs() const { return mChangedItemIDs; }
const changed_items_t& getAddedIDs() const { return mAddedItemIDs; }
protected:
// Updates all linked items pointing to this id.
void addChangedMaskForLinks(const LLUUID& object_id, U32 mask);
@@ -487,6 +524,8 @@ private:
// Variables used to track what has changed since the last notify.
U32 mModifyMask;
changed_items_t mChangedItemIDs;
changed_items_t mAddedItemIDs;
//--------------------------------------------------------------------
// Observers
@@ -548,7 +587,7 @@ public:
static void processMoveInventoryItem(LLMessageSystem* msg, void**);
static void processFetchInventoryReply(LLMessageSystem* msg, void**);
protected:
bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting);
bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting, U32 mask = 0x0);
//--------------------------------------------------------------------
// Locks
@@ -564,12 +603,14 @@ protected:
private:
std::map<LLUUID, bool> mCategoryLock;
std::map<LLUUID, bool> mItemLock;
public:
// *NOTE: DEBUG functionality
void dumpInventory() const;
//--------------------------------------------------------------------
// Debugging
//--------------------------------------------------------------------
public:
void dumpInventory() const;
bool validate() const;
/** Miscellaneous
** **
*******************************************************************************/

View File

@@ -40,23 +40,112 @@
#include "hippogridmanager.h"
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy inventoryModelFetchDescendentsResponder_timeout;
extern AIHTTPTimeoutPolicy inventoryModelFetchItemResponder_timeout;
extern AIHTTPTimeoutPolicy BGItemHttpHandler_timeout;
extern AIHTTPTimeoutPolicy BGFolderHttpHandler_timeout;
const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
const S32 MAX_FETCH_RETRIES = 10;
///----------------------------------------------------------------------------
/// Class <anonymous>::BGItemHttpHandler
///----------------------------------------------------------------------------
//
// Http request handler class for single inventory item requests.
//
// We'll use a handler-per-request pattern here rather than
// a shared handler. Mainly convenient as this was converted
// from a Responder class model.
//
// Derives from and is identical to the normal FetchItemHttpHandler
// except that: 1) it uses the background request object which is
// updated more slowly than the foreground and 2) keeps a count of
// active requests on the LLInventoryModelBackgroundFetch object
// to indicate outstanding operations are in-flight.
//
class BGItemHttpHandler : public LLInventoryModel::FetchItemHttpHandler
{
LOG_CLASS(BGItemHttpHandler);
public:
BGItemHttpHandler(const LLSD & request_sd)
: LLInventoryModel::FetchItemHttpHandler(request_sd)
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(1);
}
virtual ~BGItemHttpHandler()
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return BGItemHttpHandler_timeout; }
/*virtual*/ char const* getName(void) const { return "BGItemHttpHandler"; }
protected:
BGItemHttpHandler(const BGItemHttpHandler &); // Not defined
void operator=(const BGItemHttpHandler &); // Not defined
};
///----------------------------------------------------------------------------
/// Class <anonymous>::BGFolderHttpHandler
///----------------------------------------------------------------------------
// Http request handler class for folders.
//
// Handler for FetchInventoryDescendents2 and FetchLibDescendents2
// caps requests for folders.
//
class BGFolderHttpHandler : public LLHTTPClient::ResponderWithResult
{
LOG_CLASS(BGFolderHttpHandler);
public:
BGFolderHttpHandler(const LLSD & request_sd, const uuid_vec_t & recursive_cats)
: LLHTTPClient::ResponderWithResult(),
mRequestSD(request_sd),
mRecursiveCatUUIDs(recursive_cats)
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(1);
}
virtual ~BGFolderHttpHandler()
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return BGFolderHttpHandler_timeout; }
/*virtual*/ char const* getName(void) const { return "BGFolderHttpHandler"; }
protected:
BGFolderHttpHandler(const BGFolderHttpHandler &); // Not defined
void operator=(const BGFolderHttpHandler &); // Not defined
BOOL getIsRecursive(const LLUUID& cat_id) const;
private:
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
LLSD mRequestSD;
uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive
};
const char * const LOG_INV("Inventory");
LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() :
mBackgroundFetchActive(FALSE),
mFolderFetchActive(false),
mFetchCount(0),
mAllFoldersFetched(FALSE),
mRecursiveInventoryFetchStarted(FALSE),
mRecursiveLibraryFetchStarted(FALSE),
mNumFetchRetries(0),
mMinTimeBetweenFetches(0.3f),
mMaxTimeBetweenFetches(10.f),
mTimelyFetchPending(FALSE),
mFetchCount(0)
mTimelyFetchPending(FALSE)
{
}
@@ -109,12 +198,24 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const
return mFolderFetchActive;
}
void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, BOOL recursive, bool is_category)
{
mFetchQueue.push_front(FetchQueueInfo(id, recursive, is_category));
}
void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, BOOL recursive, bool is_category)
{
mFetchQueue.push_back(FetchQueueInfo(id, recursive, is_category));
}
void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(id);
if (cat || (id.isNull() && !isEverythingFetched()))
{ // it's a folder, do a bulk fetch
LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
LLViewerInventoryCategory * cat(gInventory.getCategory(id));
if (cat || (id.isNull() && ! isEverythingFetched()))
{
// it's a folder, do a bulk fetch
LL_DEBUGS(LOG_INV) << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
mFolderFetchActive = true;
if (id.isNull())
@@ -181,11 +282,13 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
mAllFoldersFetched = TRUE;
}
mFolderFetchActive = false;
if (mBackgroundFetchActive)
{
gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
mBackgroundFetchActive = FALSE;
}
mBackgroundFetchActive = false;
LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL;
}
void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
@@ -385,241 +488,41 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
}
}
void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching)
void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching)
{
mFetchCount += fetching;
if (mFetchCount < 0)
{
LL_WARNS_ONCE(LOG_INV) << "Inventory fetch count fell below zero (0)." << LL_ENDL;
mFetchCount = 0;
}
}
class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder
{
public:
LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchItemResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchItemResponder"; }
};
void LLInventoryModelFetchItemResponder::httpSuccess(void)
{
LLInventoryModel::fetchInventoryResponder::httpSuccess();
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
void LLInventoryModelFetchItemResponder::httpFailure(void)
{
LLInventoryModel::fetchInventoryResponder::httpFailure();
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
class LLInventoryModelFetchDescendentsResponder : public LLHTTPClient::ResponderWithResult
{
public:
LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) :
mRequestSD(request_sd),
mRecursiveCatUUIDs(recursive_cats)
{};
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchDescendentsResponder"; }
protected:
BOOL getIsRecursive(const LLUUID& cat_id) const;
private:
LLSD mRequestSD;
uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive
};
// If we get back a normal response, handle it here.
void LLInventoryModelFetchDescendentsResponder::httpSuccess(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
if (mContent.has("folders"))
{
for(LLSD::array_const_iterator folder_it = mContent["folders"].beginArray();
folder_it != mContent["folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
//LLUUID agent_id = folder_sd["agent_id"];
//if(agent_id != gAgent.getID()) //This should never happen.
//{
// LL_WARNS() << "Got a UpdateInventoryItem for the wrong agent."
// << LL_ENDL;
// break;
//}
LLUUID parent_id = folder_sd["folder_id"];
LLUUID owner_id = folder_sd["owner_id"];
S32 version = (S32)folder_sd["version"].asInteger();
S32 descendents = (S32)folder_sd["descendents"].asInteger();
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
if (parent_id.isNull())
{
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
item_it != folder_sd["items"].endArray();
++item_it)
{
LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
if (lost_uuid.notNull())
{
LLSD item = *item_it;
titem->unpackMessage(item);
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
titem->setParent(lost_uuid);
titem->updateParentOnServer(FALSE);
gInventory.updateItem(titem);
gInventory.notifyObservers();
}
}
}
LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id);
if (!pcat)
{
continue;
}
for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray();
category_it != folder_sd["categories"].endArray();
++category_it)
{
LLSD category = *category_it;
tcategory->fromLLSD(category);
const BOOL recursive = getIsRecursive(tcategory->getUUID());
if (recursive)
{
fetcher->mFetchQueue.push_back(LLInventoryModelBackgroundFetch::FetchQueueInfo(tcategory->getUUID(), recursive));
}
else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) )
{
gInventory.updateCategory(tcategory);
}
}
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
item_it != folder_sd["items"].endArray();
++item_it)
{
LLSD item = *item_it;
titem->unpackMessage(item);
gInventory.updateItem(titem);
}
// set version and descendentcount according to message.
LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
if(cat)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
cat->determineFolderType();
}
}
}
if (mContent.has("bad_folders"))
{
for(LLSD::array_const_iterator folder_it = mContent["bad_folders"].beginArray();
folder_it != mContent["bad_folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
//These folders failed on the dataserver. We probably don't want to retry them.
LL_INFOS() << "Folder " << folder_sd["folder_id"].asString()
<< "Error: " << folder_sd["error"].asString() << LL_ENDL;
}
}
fetcher->incrFetchCount(-1);
if (fetcher->isBulkFetchProcessingComplete())
{
LL_INFOS() << "Inventory fetch completed" << LL_ENDL;
fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers();
}
//If we get back an error (not found, etc...), handle it here
void LLInventoryModelFetchDescendentsResponder::httpFailure(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
LL_INFOS() << "LLInventoryModelFetchDescendentsResponder::error "
<< mStatus << ": " << mReason << LL_ENDL;
fetcher->incrFetchCount(-1);
if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out
{
for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
LLUUID folder_id = folder_sd["folder_id"];
const BOOL recursive = getIsRecursive(folder_id);
fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive));
}
}
else
{
if (fetcher->isBulkFetchProcessingComplete())
{
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}
BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat_id) const
{
return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
}
// Bundle up a bunch of requests to send all at once.
void LLInventoryModelBackgroundFetch::bulkFetch()
{
//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped.
//If there are items in mFetchQueue, we want to check the time since the last bulkFetch was
//sent. If it exceeds our retry time, go ahead and fire off another batch.
LLViewerRegion* region = gAgent.getRegion();
if (gDisconnected || !region) return;
LLViewerRegion * region(gAgent.getRegion());
if (! region || gDisconnected)
{
return;
}
// *TODO: These values could be tweaked at runtime to effect
// a fast/slow fetch throttle. Once login is complete and the scene
U32 const max_batch_size = 5;
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1;
U32 item_count(0);
U32 folder_count(0);
const U32 sort_order(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1);
uuid_vec_t recursive_cats;
U32 folder_count=0;
U32 folder_lib_count=0;
U32 item_count=0;
U32 item_lib_count=0;
// This function can do up to four requests at once.
@@ -633,15 +536,26 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
LLSD item_request_body;
LLSD item_request_body_lib;
while (!mFetchQueue.empty())
while (! mFetchQueue.empty())
{
const FetchQueueInfo& fetch_info = mFetchQueue.front();
const FetchQueueInfo & fetch_info(mFetchQueue.front());
if (fetch_info.mIsCategory)
{
const LLUUID &cat_id = fetch_info.mUUID;
if (!cat_id.isNull())
const LLUUID & cat_id(fetch_info.mUUID);
if (cat_id.isNull()) //DEV-17797
{
const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
LLSD folder_sd;
folder_sd["folder_id"] = LLUUID::null.asString();
folder_sd["owner_id"] = gAgent.getID();
folder_sd["sort_order"] = LLSD::Integer(sort_order);
folder_sd["fetch_folders"] = LLSD::Boolean(FALSE);
folder_sd["fetch_items"] = LLSD::Boolean(TRUE);
folder_request_body["folders"].append(folder_sd);
folder_count++;
}
else
{
const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id));
if (cat)
{
@@ -650,9 +564,9 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
LLSD folder_sd;
folder_sd["folder_id"] = cat->getUUID();
folder_sd["owner_id"] = cat->getOwnerID();
folder_sd["sort_order"] = (LLSD::Integer)sort_order;
folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted;
folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
folder_sd["sort_order"] = LLSD::Integer(sort_order);
folder_sd["fetch_folders"] = LLSD::Boolean(TRUE); //(LLSD::Boolean)sFullFetchStarted;
folder_sd["fetch_items"] = LLSD::Boolean(TRUE);
if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID())
{
@@ -680,8 +594,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
// May already have this folder, but append child folders to list.
if (fetch_info.mRecursive)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
LLInventoryModel::cat_array_t * categories(NULL);
LLInventoryModel::item_array_t * items(NULL);
gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items);
for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin();
it != categories->end();
@@ -691,13 +605,16 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
}
}
}
if (fetch_info.mRecursive)
recursive_cats.push_back(cat_id);
}
if (fetch_info.mRecursive)
{
recursive_cats.push_back(cat_id);
}
}
else
{
LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID);
LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID));
if (itemp)
{
LLSD item_sd;
@@ -735,39 +652,62 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
{
if (folder_count)
{
std::string url = region->getCapability("FetchInventoryDescendents2");
llassert(!url.empty());
++mFetchCount;
LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
LLHTTPClient::post_approved(url, folder_request_body, fetcher, approved_folder);
if (folder_request_body["folders"].size())
{
const std::string url(region->getCapability("FetchInventoryDescendents2"));
if (! url.empty())
{
BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body, recursive_cats));
LLHTTPClient::post_approved(url, folder_request_body, handler, approved_folder);
}
}
}
if (folder_lib_count)
{
std::string url = gAgent.getRegion()->getCapability("FetchLibDescendents2");
llassert(!url.empty());
++mFetchCount;
LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
LLHTTPClient::post_approved(url, folder_request_body_lib, fetcher, approved_folder_lib);
if (folder_request_body_lib["folders"].size())
{
const std::string url(region->getCapability("FetchLibDescendents2"));
if (! url.empty())
{
BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body_lib, recursive_cats));
LLHTTPClient::post_approved(url, folder_request_body_lib, handler, approved_folder_lib);
}
}
}
if (item_count)
{
std::string url = region->getCapability("FetchInventory2");
llassert(!url.empty());
++mFetchCount;
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body;
LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item);
if (item_request_body.size())
{
const std::string url(region->getCapability("FetchInventory2"));
if (! url.empty())
{
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body;
BGItemHttpHandler * handler(new BGItemHttpHandler(body));
LLHTTPClient::post_approved(url, body, handler, approved_item);
}
}
}
if (item_lib_count)
{
std::string url = region->getCapability("FetchLib2");
llassert(!url.empty());
++mFetchCount;
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body_lib;
LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item_lib);
if (item_request_body_lib.size())
{
const std::string url(region->getCapability("FetchLib2"));
if (! url.empty())
{
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body_lib;
BGItemHttpHandler * handler(new BGItemHttpHandler(body));
LLHTTPClient::post_approved(url, body, handler, approved_item_lib);
}
}
}
mFetchTimer.reset();
}
@@ -781,7 +721,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const
{
for (fetch_queue_t::const_iterator it = mFetchQueue.begin();
it != mFetchQueue.end(); ++it)
it != mFetchQueue.end();
++it)
{
const LLUUID& fetch_id = (*it).mUUID;
if (gInventory.isObjectDescendentOf(fetch_id, cat_id))
@@ -789,4 +730,175 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL
}
return true;
}
// If we get back a normal response, handle it here.
void BGFolderHttpHandler::httpSuccess(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
const LLSD& content = mContent;
// in response as an application-level error.
// Instead, we assume success and attempt to extract information.
if (content.has("folders"))
{
LLSD folders(content["folders"]);
for (LLSD::array_const_iterator folder_it = folders.beginArray();
folder_it != folders.endArray();
++folder_it)
{
LLSD folder_sd(*folder_it);
//LLUUID agent_id = folder_sd["agent_id"];
//if(agent_id != gAgent.getID()) //This should never happen.
//{
// LL_WARNS(LOG_INV) << "Got a UpdateInventoryItem for the wrong agent."
// << LL_ENDL;
// break;
//}
LLUUID parent_id(folder_sd["folder_id"].asUUID());
LLUUID owner_id(folder_sd["owner_id"].asUUID());
S32 version(folder_sd["version"].asInteger());
S32 descendents(folder_sd["descendents"].asInteger());
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
if (parent_id.isNull())
{
LLSD items(folder_sd["items"]);
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for (LLSD::array_const_iterator item_it = items.beginArray();
item_it != items.endArray();
++item_it)
{
const LLUUID lost_uuid(gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
if (lost_uuid.notNull())
{
LLSD item(*item_it);
titem->unpackMessage(item);
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
titem->setParent(lost_uuid);
titem->updateParentOnServer(FALSE);
gInventory.updateItem(titem);
gInventory.notifyObservers();
}
}
}
LLViewerInventoryCategory * pcat(gInventory.getCategory(parent_id));
if (! pcat)
{
continue;
}
LLSD categories(folder_sd["categories"]);
for (LLSD::array_const_iterator category_it = categories.beginArray();
category_it != categories.endArray();
++category_it)
{
LLSD category(*category_it);
tcategory->fromLLSD(category);
const bool recursive(getIsRecursive(tcategory->getUUID()));
if (recursive)
{
fetcher->addRequestAtBack(tcategory->getUUID(), recursive, true);
}
else if (! gInventory.isCategoryComplete(tcategory->getUUID()))
{
gInventory.updateCategory(tcategory);
}
}
LLSD items(folder_sd["items"]);
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for (LLSD::array_const_iterator item_it = items.beginArray();
item_it != items.endArray();
++item_it)
{
LLSD item(*item_it);
titem->unpackMessage(item);
gInventory.updateItem(titem);
}
// Set version and descendentcount according to message.
LLViewerInventoryCategory * cat(gInventory.getCategory(parent_id));
if (cat)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
cat->determineFolderType();
}
}
}
if (content.has("bad_folders"))
{
LLSD bad_folders(content["bad_folders"]);
for (LLSD::array_const_iterator folder_it = bad_folders.beginArray();
folder_it != bad_folders.endArray();
++folder_it)
{
// *TODO: Stop copying data [ed: this isn't copying data]
LLSD folder_sd(*folder_it);
// These folders failed on the dataserver. We probably don't want to retry them.
LL_WARNS(LOG_INV) << "Folder " << folder_sd["folder_id"].asString()
<< "Error: " << folder_sd["error"].asString() << LL_ENDL;
}
}
if (fetcher->isBulkFetchProcessingComplete())
{
LL_INFOS() << "Inventory fetch completed" << LL_ENDL;
fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers();
}
//If we get back an error (not found, etc...), handle it here
void BGFolderHttpHandler::httpFailure(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
LL_INFOS() << "BGFolderHttpHandler::error "
<< mStatus << ": " << mReason << LL_ENDL;
if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out
{
for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
++folder_it)
{
LLSD folder_sd(*folder_it);
LLUUID folder_id(folder_sd["folder_id"].asUUID());
const BOOL recursive = getIsRecursive(folder_id);
fetcher->addRequestAtFront(folder_id, recursive, true);
}
}
else
{
if (fetcher->isBulkFetchProcessingComplete())
{
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}
BOOL BGFolderHttpHandler::getIsRecursive(const LLUUID& cat_id) const
{
return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
}

View File

@@ -39,8 +39,6 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch>
{
friend class LLInventoryModelFetchDescendentsResponder;
public:
LLInventoryModelBackgroundFetch();
~LLInventoryModelBackgroundFetch();
@@ -61,16 +59,22 @@ public:
bool inventoryFetchInProgress() const;
void findLostItems();
void incrFetchCount(S16 fetching);
protected:
void incrFetchCount(S32 fetching);
bool isBulkFetchProcessingComplete() const;
void setAllFoldersFetched();
void addRequestAtFront(const LLUUID & id, BOOL recursive, bool is_category);
void addRequestAtBack(const LLUUID & id, BOOL recursive, bool is_category);
protected:
void bulkFetch();
void backgroundFetch();
static void backgroundFetchCB(void*); // background fetch idle function
void setAllFoldersFetched();
bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;
private:
BOOL mRecursiveInventoryFetchStarted;
BOOL mRecursiveLibraryFetchStarted;
@@ -78,7 +82,7 @@ private:
BOOL mBackgroundFetchActive; // TRUE if LLInventoryModelBackgroundFetch::backgroundFetchCB is being called from idle().
bool mFolderFetchActive;
S16 mFetchCount;
S32 mFetchCount;
BOOL mTimelyFetchPending;
S32 mNumFetchRetries;
@@ -90,8 +94,10 @@ private:
struct FetchQueueInfo
{
FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true) :
mUUID(id), mRecursive(recursive), mIsCategory(is_category)
FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true)
: mUUID(id),
mIsCategory(is_category),
mRecursive(recursive)
{}
LLUUID mUUID;
bool mIsCategory;

View File

@@ -38,6 +38,7 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llfloater.h"
#include "llfolderview.h"
#include "llfocusmgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@@ -237,7 +238,7 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
if (!url.empty())
{
body[i]["agent_id"] = gAgent.getID();
LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
LLHTTPClient::post(url, body[i], new LLInventoryModel::FetchItemHttpHandler(body[i]));
continue;
}
@@ -398,7 +399,7 @@ BOOL LLInventoryFetchDescendentsObserver::isCategoryComplete(const LLViewerInven
// from memory.
return TRUE;
}
const S32 current_num_known_descendents = cats->count() + items->count();
const S32 current_num_known_descendents = cats->size() + items->size();
// Got the number of descendents that we were expecting, so we're done.
if (current_num_known_descendents == expected_num_descendents)
@@ -464,42 +465,13 @@ void LLInventoryFetchComboObserver::startFetch()
mFetchItems->startFetch();
mFetchDescendents->startFetch();
}
void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
{
if (id.notNull())
{
mMIA.push_back(id);
}
}
void LLInventoryExistenceObserver::changed(U32 mask)
{
// scan through the incomplete items and move or erase them as
// appropriate.
if (!mMIA.empty())
{
for (uuid_vec_t::iterator it = mMIA.begin(); it < mMIA.end(); )
{
LLViewerInventoryItem* item = gInventory.getItem(*it);
if (!item)
{
++it;
continue;
}
mExist.push_back(*it);
it = mMIA.erase(it);
}
if (mMIA.empty())
{
done();
}
}
}
// See comment preceding LLInventoryAddedObserver::changed() for some
// concerns that also apply to this observer.
void LLInventoryAddItemByAssetObserver::changed(U32 mask)
{
if(!(mask & LLInventoryObserver::ADD))
if(!(mask & LLInventoryObserver::ADD) ||
!(mask & LLInventoryObserver::CREATE) ||
!(mask & LLInventoryObserver::UPDATE_CREATE))
{
return;
}
@@ -510,20 +482,12 @@ void LLInventoryAddItemByAssetObserver::changed(U32 mask)
return;
}
LLMessageSystem* msg = gMessageSystem;
if (!(msg->getMessageName() && (0 == strcmp(msg->getMessageName(), "UpdateCreateInventoryItem"))))
const uuid_set_t& added = gInventory.getAddedIDs();
for (uuid_set_t::iterator it = added.begin(); it != added.end(); ++it)
{
// this is not our message
return; // to prevent a crash. EXT-7921;
}
LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem;
S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
for(S32 i = 0; i < num_blocks; ++i)
{
item->unpackMessage(msg, _PREHASH_InventoryData, i);
LLInventoryItem *item = gInventory.getItem(*it);
const LLUUID& asset_uuid = item->getAssetUUID();
if (item->getUUID().notNull() && asset_uuid.notNull())
if (item && item->getUUID().notNull() && asset_uuid.notNull())
{
if (isAssetWatched(asset_uuid))
{
@@ -532,11 +496,11 @@ void LLInventoryAddItemByAssetObserver::changed(U32 mask)
}
}
}
if (mAddedItems.size() == mWatchedAssets.size())
{
done();
LL_DEBUGS("Inventory_Move") << "All watched items are added & processed." << LL_ENDL;
done();
mAddedItems.clear();
// Unable to clean watched items here due to somebody can require to check them in current frame.
@@ -566,41 +530,28 @@ bool LLInventoryAddItemByAssetObserver::isAssetWatched( const LLUUID& asset_id )
return std::find(mWatchedAssets.begin(), mWatchedAssets.end(), asset_id) != mWatchedAssets.end();
}
// This observer used to explicitly check for whether it was being
// called as a result of an UpdateCreateInventoryItem message. It has
// now been decoupled enough that it's not actually checking the
// message system, but now we have the special UPDATE_CREATE flag
// being used for the same purpose. Fixing this, as we would need to
// do to get rid of the message, is somewhat subtle because there's no
// particular obvious criterion for when creating a new item should
// trigger this observer and when it shouldn't. For example, creating
// a new notecard with new->notecard causes a preview window to pop up
// via the derived class LLOpenTaskOffer, but creating a new notecard
// by copy and paste does not, solely because one goes through
// UpdateCreateInventoryItem and the other doesn't.
void LLInventoryAddedObserver::changed(U32 mask)
{
if (!(mask & LLInventoryObserver::ADD))
if (!(mask & LLInventoryObserver::ADD) ||
!(mask & LLInventoryObserver::CREATE) ||
!(mask & LLInventoryObserver::UPDATE_CREATE))
{
return;
}
// *HACK: If this was in response to a packet off
// the network, figure out which item was updated.
LLMessageSystem* msg = gMessageSystem;
std::string msg_name = msg->getMessageName();
if (msg_name.empty())
{
return;
}
// We only want newly created inventory items. JC
if ( msg_name != "UpdateCreateInventoryItem")
{
return;
}
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
for (S32 i = 0; i < num_blocks; ++i)
{
titem->unpackMessage(msg, _PREHASH_InventoryData, i);
if (!(titem->getUUID().isNull()))
{
//we don't do anything with null keys
mAdded.push_back(titem->getUUID());
}
}
if (!mAdded.empty())
if (!gInventory.getAddedIDs().empty())
{
done();
}
@@ -613,9 +564,9 @@ void LLInventoryCategoryAddedObserver::changed(U32 mask)
return;
}
const LLInventoryModel::changed_items_t& changed_ids = gInventory.getChangedIDs();
const LLInventoryModel::changed_items_t& added_ids = gInventory.getChangedIDs();
for (LLInventoryModel::changed_items_t::const_iterator cit = changed_ids.begin(); cit != changed_ids.end(); ++cit)
for (LLInventoryModel::changed_items_t::const_iterator cit = added_ids.begin(); cit != added_ids.end(); ++cit)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(*cit);
@@ -633,58 +584,6 @@ void LLInventoryCategoryAddedObserver::changed(U32 mask)
}
}
LLInventoryTransactionObserver::LLInventoryTransactionObserver(const LLTransactionID& transaction_id) :
mTransactionID(transaction_id)
{
}
void LLInventoryTransactionObserver::changed(U32 mask)
{
if (mask & LLInventoryObserver::ADD)
{
// This could be it - see if we are processing a bulk update
LLMessageSystem* msg = gMessageSystem;
if (msg->getMessageName()
&& (0 == strcmp(msg->getMessageName(), "BulkUpdateInventory")))
{
// we have a match for the message - now check the
// transaction id.
LLUUID id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, id);
if (id == mTransactionID)
{
// woo hoo, we found it
uuid_vec_t folders;
uuid_vec_t items;
S32 count;
count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
S32 i;
for (i = 0; i < count; ++i)
{
msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_FolderID, id, i);
if (id.notNull())
{
folders.push_back(id);
}
}
count = msg->getNumberOfBlocksFast(_PREHASH_ItemData);
for (i = 0; i < count; ++i)
{
msg->getUUIDFast(_PREHASH_ItemData, _PREHASH_ItemID, id, i);
if (id.notNull())
{
items.push_back(id);
}
}
// call the derived class the implements this method.
done(folders, items);
}
}
}
}
void LLInventoryCategoriesObserver::changed(U32 mask)
{
if (!mCategoryMap.size())
@@ -733,7 +632,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
continue;
}
const S32 current_num_known_descendents = cats->count() + items->count();
const S32 current_num_known_descendents = cats->size() + items->size();
bool cat_changed = false;
@@ -804,7 +703,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t
}
else
{
current_num_known_descendents = cats->count() + items->count();
current_num_known_descendents = cats->size() + items->size();
}
}
@@ -833,3 +732,23 @@ LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData(
{
mItemNameHash.finalize();
}
void LLScrollOnRenameObserver::changed(U32 mask)
{
if (mask & LLInventoryObserver::LABEL)
{
const uuid_set_t& changed_item_ids = gInventory.getChangedIDs();
for (uuid_set_t::const_iterator it = changed_item_ids.begin(); it != changed_item_ids.end(); ++it)
{
const LLUUID& id = *it;
if (id == mUUID)
{
mView->scrollToShowSelection();
gInventory.removeObserver(this);
delete this;
return;
}
}
}
}

View File

@@ -58,7 +58,10 @@ public:
GESTURE = 64,
REBUILD = 128, // Item UI changed (e.g. item type different)
SORT = 256, // Folder needs to be resorted.
DESCRIPTION = 0x10000, // Singu extension to keep track of description changes.
CREATE = 512, // With ADD, item has just been created.
// unfortunately a particular message is still associated with some unique semantics.
UPDATE_CREATE = 1024, // With ADD, item added via UpdateCreateInventoryItem
DESCRIPTION = 2048, // Singu extension to keep track of description changes.
ALL = 0xffffffff
};
LLInventoryObserver();
@@ -152,25 +155,6 @@ protected:
LLInventoryFetchDescendentsObserver *mFetchDescendents;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryExistenceObserver
//
// Used as a base class for doing something when all the
// observed item ids exist in the inventory somewhere.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryExistenceObserver : public LLInventoryObserver
{
public:
LLInventoryExistenceObserver() {}
/*virtual*/ void changed(U32 mask);
void watchItem(const LLUUID& id);
protected:
virtual void done() = 0;
uuid_vec_t mExist;
uuid_vec_t mMIA;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryMovedObserver
//
@@ -210,13 +194,11 @@ private:
class LLInventoryAddedObserver : public LLInventoryObserver
{
public:
LLInventoryAddedObserver() : mAdded() {}
LLInventoryAddedObserver() {}
/*virtual*/ void changed(U32 mask);
protected:
virtual void done() = 0;
uuid_vec_t mAdded;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -241,25 +223,6 @@ protected:
cat_vec_t mAddedCategories;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryTransactionObserver
//
// Base class for doing something when an inventory transaction completes.
// NOTE: This class is not quite complete. Avoid using unless you fix up its
// functionality gaps.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryTransactionObserver : public LLInventoryObserver
{
public:
LLInventoryTransactionObserver(const LLTransactionID& transaction_id);
/*virtual*/ void changed(U32 mask);
protected:
virtual void done(const uuid_vec_t& folders, const uuid_vec_t& items) = 0;
LLTransactionID mTransactionID;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryCompletionObserver
//
@@ -326,4 +289,23 @@ protected:
category_map_t mCategoryMap;
};
class LLFolderView;
// Force a FolderView to scroll after an item in the corresponding view has been renamed.
class LLScrollOnRenameObserver: public LLInventoryObserver
{
public:
LLFolderView *mView;
LLUUID mUUID;
LLScrollOnRenameObserver(const LLUUID& uuid, LLFolderView *view):
mUUID(uuid),
mView(view)
{
}
/* virtual */ void changed(U32 mask);
};
#endif // LL_LLINVENTORYOBSERVERS_H

View File

@@ -145,7 +145,8 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name,
mInventory(inventory),
mAllowMultiSelect(allow_multi_select),
mViewsInitialized(false),
mInvFVBridgeBuilder(NULL)
mInvFVBridgeBuilder(NULL),
mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@@ -172,7 +173,7 @@ void LLInventoryPanel::buildFolderView()
else
{
root_id = (preferred_type != LLFolderType::FT_NONE)
? gInventory.findCategoryUUIDForType(preferred_type, false, false)
? gInventory.findCategoryUUIDForType(preferred_type, false)
: gInventory.getCategory(static_cast<LLUUID>(mStartFolder)) ? static_cast<LLUUID>(mStartFolder) // Singu Note: if start folder is an id of a folder, use it
: LLUUID::null;
}
@@ -695,7 +696,8 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
folder_rect,
LLUUID::null,
this,
bridge);
bridge,
mGroupedItemBridge);
ret->setAllowMultiSelect(mAllowMultiSelect);
return ret;
}

View File

@@ -35,7 +35,6 @@
#define LL_LLINVENTORYPANEL_H
#include "llassetstorage.h"
#include "lldarray.h"
#include "llfloater.h"
#include "llinventory.h"
#include "llfolderview.h"
@@ -62,6 +61,7 @@ class LLTextBox;
class LLIconCtrl;
class LLSaveFolderState;
class LLInvPanelComplObserver;
class LLFolderViewGroupedItemBridge;
class LLInventoryPanel : public LLPanel
{
@@ -170,6 +170,7 @@ protected:
LLHandle<LLFolderView> mFolderRoot;
LLScrollContainer* mScroller;
LLPointer<LLFolderViewGroupedItemBridge> mGroupedItemBridge;
/**
* Pointer to LLInventoryFVBridgeBuilder.
*

View File

@@ -917,13 +917,13 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& tool_tip, LLRect* stick
tool_tip.assign("");
if (region->mMapAvatarIDs.count())
if (region->mMapAvatarIDs.size())
{
if (mClosestAgentsToCursor.size())
{
bool single_agent(mClosestAgentsToCursor.size() == 1); // Singu note: For old look, only add the count if we have more than one
if (!single_agent)
tool_tip.append(llformat("Agents under cursor (%d/%d)\n", mClosestAgentsToCursor.size(), region->mMapAvatarIDs.count() + 1));
tool_tip.append(llformat("Agents under cursor (%d/%d)\n", mClosestAgentsToCursor.size(), region->mMapAvatarIDs.size() + 1));
LLVector3d myPosition = gAgent.getPositionGlobal();

View File

@@ -235,7 +235,7 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType
std::string font_style("NORMAL"); // Set normal color if not found or if group is visible in profile
if (pAvatarGroups->avatar_id == pAvatarGroups->agent_id) // own avatar
for (LLDynamicArray<LLGroupData>::iterator i = gAgent.mGroups.begin(); i != gAgent.mGroups.end(); ++i) // Search for this group in the agent's groups list
for (std::vector<LLGroupData>::iterator i = gAgent.mGroups.begin(); i != gAgent.mGroups.end(); ++i) // Search for this group in the agent's groups list
if (i->mID == it->group_id)
{
if (i->mListInProfile)

View File

@@ -32,8 +32,6 @@
#include "llviewerprecompiledheaders.h"
#include "llenum.h"
#include "llpaneldirclassified.h"
#include "llclassifiedflags.h"

View File

@@ -37,7 +37,6 @@
#include <sstream>
// linden library includes
#include "llenum.h"
#include "message.h"
#include "llqueryflags.h"

View File

@@ -771,7 +771,8 @@ BOOL LLPanelEditWearable::postBuild()
if (mTab = findChild<LLTabContainer>("layer_tabs"))
{
for(U32 i = 1; i <= LLAgentWearables::MAX_CLOTHING_PER_TYPE; ++i)
LL_COMPILE_TIME_MESSAGE("layer_tabs needs re-implemented");
for(U32 i = 1; i <= 6/*LLAgentWearables::MAX_CLOTHING_PER_TYPE*/; ++i)
{
LLPanel* new_panel = new LLPanel(llformat("%i",i));
mTab->addTabPanel(new_panel, llformat("Layer %i",i));
@@ -1008,15 +1009,13 @@ void LLPanelEditWearable::refreshWearables(bool force_immediate)
U32 index;
if (mPendingWearable)
{
index = gAgentWearables.getWearableIndex(mPendingWearable);
if (index == LLAgentWearables::MAX_CLOTHING_PER_TYPE)
if (!gAgentWearables.getWearableIndex(mPendingWearable, index))
return;
mPendingWearable = NULL;
}
else
{
index = gAgentWearables.getWearableIndex(getWearable());
if (index == LLAgentWearables::MAX_CLOTHING_PER_TYPE)
if (!gAgentWearables.getWearableIndex(mPendingWearable, index))
{
index = gAgentWearables.getWearableCount(mType);
if (index)
@@ -1026,7 +1025,8 @@ void LLPanelEditWearable::refreshWearables(bool force_immediate)
if (mTab)
{
for(U32 i = 0; i < LLAgentWearables::MAX_CLOTHING_PER_TYPE; ++i)
LL_COMPILE_TIME_MESSAGE("layer_tabs needs re-implemented");
for(U32 i = 0; i < 6/*LLAgentWearables::MAX_CLOTHING_PER_TYPE*/; ++i)
{
mTab->enableTabButton(i, i < gAgentWearables.getWearableCount(mType));
}
@@ -1168,10 +1168,13 @@ void LLPanelEditWearable::setNewImageID(ETextureIndex te_index, LLUUID const& uu
}
if (getWearable())
{
U32 index = gAgentWearables.getWearableIndex(getWearable());
gAgentAvatarp->setLocalTexture(te_index, image, FALSE, index);
LLVisualParamHint::requestHintUpdates();
gAgentAvatarp->wearableUpdated(mType, FALSE);
U32 index;
if (gAgentWearables.getWearableIndex(getWearable(), index))
{
gAgentAvatarp->setLocalTexture(te_index, image, FALSE, index);
LLVisualParamHint::requestHintUpdates();
gAgentAvatarp->wearableUpdated(mType, FALSE);
}
}
if (mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE)
{
@@ -1230,7 +1233,8 @@ void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name)
return;
}
U32 index = gAgentWearables.getWearableIndex(getWearable());
U32 index;
gAgentWearables.getWearableIndex(getWearable(), index);
// Find an existing link to this wearable's inventory item, if any, and its description field.
LLInventoryItem *link_item = NULL;
@@ -1242,7 +1246,7 @@ void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name)
LLAppearanceMgr::instance().findCOFItemLinks(getWearable()->getItemID());
if (links.size()>0)
{
link_item = links.get(0).get();
link_item = links.at(0).get();
if (link_item && link_item->getIsLinkType())
{
description = link_item->getActualDescription();
@@ -1271,15 +1275,11 @@ void LLPanelEditWearable::saveChanges(bool force_save_as, std::string new_name)
if (link_item)
{
// Create new link
link_inventory_item( gAgent.getID(),
link_item->getLinkedUUID(),
LLAppearanceMgr::instance().getCOF(),
link_item->getName(),
description,
LLAssetType::AT_LINK,
link_inventory_object( LLAppearanceMgr::instance().getCOF(),
link_item,
NULL);
// Remove old link
gInventory.purgeObject(link_item->getUUID());
remove_inventory_item(link_item, NULL);
}
gAgentWearables.saveWearable(mType, index, TRUE, new_name);
}
@@ -1543,9 +1543,12 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, LLAvatarAppearanc
mPreviousAlphaTexture[te] = lto->getID();
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_INVISIBLE );
U32 index = gAgentWearables.getWearableIndex(getWearable());
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
U32 index;
if (gAgentWearables.getWearableIndex(getWearable(), index))
{
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
}
}
else
{
@@ -1563,9 +1566,12 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, LLAvatarAppearanc
if (!image)
return;
U32 index = gAgentWearables.getWearableIndex(getWearable());
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
U32 index;
if (gAgentWearables.getWearableIndex(getWearable(), index))
{
gAgentAvatarp->setLocalTexture(te, image, FALSE, index);
gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE);
}
}
}

View File

@@ -51,7 +51,7 @@
const std::string FILTERS_FILENAME("filters.xml");
LLDynamicArray<LLInventoryView*> LLInventoryView::sActiveViews;
std::vector<LLInventoryView*> LLInventoryView::sActiveViews;
const S32 INV_MIN_WIDTH = 240;
const S32 INV_MIN_HEIGHT = 150;
const S32 INV_FINDER_WIDTH = 160;
@@ -214,7 +214,7 @@ BOOL LLInventoryView::postBuild()
}
sActiveViews.put(this);
sActiveViews.push_back(this);
getChild<LLTabContainer>("inventory filter tabs")->setCommitCallback(boost::bind(&LLInventoryView::onFilterSelected,this));
@@ -275,7 +275,7 @@ LLInventoryView::~LLInventoryView( void )
else
filtersFile.close();
sActiveViews.removeObj(this);
vector_replace_with_last(sActiveViews, this);
gInventory.removeObserver(this);
delete mSavedFolderState;
}
@@ -303,9 +303,9 @@ void LLInventoryView::onClose(bool app_quitting)
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
// See LLInventoryView::closeAll() on why we're doing it this way
S32 count = 0;
for (S32 idx = 0, cnt = sActiveViews.count(); idx < cnt; idx++)
for (S32 idx = 0, cnt = sActiveViews.size(); idx < cnt; idx++)
{
if (!sActiveViews.get(idx)->isDead())
if (!sActiveViews.at(idx)->isDead())
count++;
}
// [/RLVa:KB]
@@ -418,16 +418,16 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
LLInventoryView* LLInventoryView::getActiveInventory()
{
LLInventoryView* iv = NULL;
S32 count = sActiveViews.count();
S32 count = sActiveViews.size();
if(count > 0)
{
iv = sActiveViews.get(0);
iv = sActiveViews.at(0);
S32 z_order = gFloaterView->getZOrder(iv);
S32 z_next = 0;
LLInventoryView* next_iv = NULL;
for(S32 i = 1; i < count; ++i)
{
next_iv = sActiveViews.get(i);
next_iv = sActiveViews.at(i);
z_next = gFloaterView->getZOrder(next_iv);
if(z_next < z_order)
{
@@ -442,7 +442,7 @@ LLInventoryView* LLInventoryView::getActiveInventory()
// static
void LLInventoryView::toggleVisibility()
{
S32 count = sActiveViews.count();
S32 count = sActiveViews.size();
if (0 == count)
{
// We're using the inventory, possibly for the first time.
@@ -451,9 +451,9 @@ void LLInventoryView::toggleVisibility()
}
else if (1 == count)
{
if (sActiveViews.get(0)->getVisible())
if (sActiveViews.at(0)->getVisible())
{
sActiveViews.get(0)->close();
sActiveViews.at(0)->close();
gSavedSettings.setBOOL("ShowInventory", FALSE);
}
else
@@ -467,18 +467,18 @@ void LLInventoryView::toggleVisibility()
// is visible.
// Close all the last one spawned.
S32 last_index = sActiveViews.count() - 1;
sActiveViews.get(last_index)->close();
S32 last_index = sActiveViews.size() - 1;
sActiveViews.at(last_index)->close();
}
}
// static
void LLInventoryView::cleanup()
{
S32 count = sActiveViews.count();
S32 count = sActiveViews.size();
for (S32 i = 0; i < count; i++)
{
sActiveViews.get(i)->destroy();
sActiveViews.at(i)->destroy();
}
}
@@ -903,6 +903,11 @@ void LLInventoryView::toggleFindOptions()
}
}
LLFolderView* LLInventoryView::getRootFolder() const
{
return mActivePanel ? (mActivePanel->getRootFolder()) : NULL;
}
void LLInventoryView::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
{
getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);

View File

@@ -87,6 +87,7 @@ public:
LLInventoryPanel* getPanel() { return mActivePanel; }
LLInventoryPanel* getActivePanel() { return mActivePanel; }
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
LLFolderView* getRootFolder() const;
const std::string& getFilterText() const { return mFilterText; }
@@ -143,9 +144,9 @@ public:
// Workaround: "fix" onClose() to count only views that aren't marked as "dead"
LLInventoryView* pView; U8 flagsSound;
for (S32 idx = sActiveViews.count() - 1; idx >= 0; idx--)
for (S32 idx = sActiveViews.size() - 1; idx >= 0; idx--)
{
pView = sActiveViews.get(idx);
pView = sActiveViews.at(idx);
flagsSound = pView->getSoundFlags();
pView->setSoundFlags(LLView::SILENT); // Suppress the window close sound
pView->close(); // onClose() protects against closing the last inventory floater
@@ -174,7 +175,7 @@ protected:
// This container is used to hold all active inventory views. This
// is here to support the inventory toggle show button.
static LLDynamicArray<LLInventoryView*> sActiveViews;
static std::vector<LLInventoryView*> sActiveViews;
};

View File

@@ -68,7 +68,7 @@ void LLOutboxInventoryPanel::buildFolderView(/*const LLInventoryPanel::Params& p
// Determine the root folder in case specified, and
// build the views starting with that folder.
LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if (root_id == LLUUID::null)
{

View File

@@ -404,10 +404,10 @@ const LLUUID& LLPanelObject::findItemID(const LLUUID& asset_id)
LLInventoryModel::INCLUDE_TRASH,
asset_id_matches);
if (items.count())
if (items.size())
{
// search for copyable version first
for (S32 i = 0; i < items.count(); i++)
for (S32 i = 0; i < items.size(); i++)
{
LLInventoryItem* itemp = items[i];
LLPermissions item_permissions = itemp->getPermissions();

View File

@@ -126,7 +126,7 @@ public:
virtual BOOL isItemMovable() const;
virtual BOOL isItemRemovable() const;
virtual BOOL removeItem();
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
virtual void removeBatch(std::vector<LLFolderViewEventListener*>& batch);
virtual void move(LLFolderViewEventListener* parent_listener);
virtual BOOL isItemCopyable() const;
virtual BOOL copyToClipboard() const;
@@ -539,7 +539,7 @@ BOOL LLTaskInvFVBridge::removeItem()
return FALSE;
}
void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewEventListener*>& batch)
{
if (!mPanel)
{
@@ -1713,7 +1713,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
// temporary object because we cannot iterate through the
// object inventory twice... A pox on stateful iteration!
LLFloaterProperties* floater = NULL;
LLDynamicArray<LLFloaterProperties*> refresh;
std::vector<LLFloaterProperties*> refresh;
LLInventoryObject::object_list_t::const_iterator it = inventory->begin();
LLInventoryObject::object_list_t::const_iterator end = inventory->end();
@@ -1723,13 +1723,13 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
object->getID());
if(floater)
{
refresh.put(floater);
refresh.push_back(floater);
}
}
S32 count = refresh.count();
S32 count = refresh.size();
for(S32 i = 0; i < count; ++i)
{
refresh.get(i)->refresh();
refresh.at(i)->refresh();
}
}
}
@@ -1839,7 +1839,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
LLFolderViewFolder* folder)
{
// Find all in the first pass
LLDynamicArray<obj_folder_pair*> child_categories;
std::vector<obj_folder_pair*> child_categories;
LLTaskInvFVBridge* bridge;
LLFolderViewItem* view;
@@ -1864,7 +1864,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
NULL,
mFolders,
bridge);
child_categories.put(new obj_folder_pair(obj,
child_categories.push_back(new obj_folder_pair(obj,
(LLFolderViewFolder*)view));
}
else
@@ -1882,7 +1882,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
}
// now, for each category, do the second pass
for(S32 i = 0; i < child_categories.count(); i++)
for(S32 i = 0; i < child_categories.size(); i++)
{
createViewsForCategory(inventory, child_categories[i]->first,
child_categories[i]->second );

View File

@@ -92,7 +92,7 @@ bool is_asset_exportable(const LLUUID& asset_id)
LLAssetIDMatches asset_id_matches(asset_id);
gInventory.collectDescendentsIf(LLUUID::null, cats, items, true, asset_id_matches, false);
for (int i = 0; i < items.count(); ++i)
for (int i = 0; i < items.size(); ++i)
{
if (perms_allow_export(items[i]->getPermissions())) return true;
}

View File

@@ -289,7 +289,7 @@ void LLParticipantList::refreshSpeakers()
{
// Are they in this sim?
if (const LLViewerRegion* regionp = *iter)
if (regionp->mMapAvatarIDs.find(speakerp->mID) != -1)
if (std::find(regionp->mMapAvatarIDs.begin(), regionp->mMapAvatarIDs.end(), speakerp->mID) != regionp->mMapAvatarIDs.end())
found = true;
}
if (!found)

View File

@@ -495,13 +495,6 @@ void LLPreview::onDiscardBtn(void* data)
self->mForceClose = TRUE;
self->close();
// Delete the item entirely
/*
item->removeFromServer();
gInventory.deleteObject(item->getUUID());
gInventory.notifyObservers();
*/
// Move the item to the trash
LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
if (item->getParentUUID() != trash_id)

View File

@@ -595,10 +595,10 @@ void LLPreviewGesture::addAnimations()
// Copy into something we can sort
std::vector<LLInventoryItem*> animations;
S32 count = items.count();
S32 count = items.size();
for(i = 0; i < count; ++i)
{
animations.push_back( items.get(i) );
animations.push_back( items.at(i) );
}
// Do the sort
@@ -641,10 +641,10 @@ void LLPreviewGesture::addSounds()
std::vector<LLInventoryItem*> sounds;
S32 i;
S32 count = items.count();
S32 count = items.size();
for(i = 0; i < count; ++i)
{
sounds.push_back( items.get(i) );
sounds.push_back( items.at(i) );
}
// Do the sort

View File

@@ -1120,15 +1120,15 @@ struct LLEntryAndEdCore
void LLScriptEdCore::deleteBridges()
{
S32 count = mBridges.count();
S32 count = mBridges.size();
LLEntryAndEdCore* eandc;
for(S32 i = 0; i < count; i++)
{
eandc = mBridges.get(i);
eandc = mBridges.at(i);
delete eandc;
mBridges[i] = NULL;
}
mBridges.reset();
mBridges.clear();
}
// virtual

View File

@@ -33,7 +33,6 @@
#ifndef LL_LLPREVIEWSCRIPT_H
#define LL_LLPREVIEWSCRIPT_H
#include "lldarray.h"
#include "llpreview.h"
#include "lltabcontainer.h"
#include "llinventory.h"
@@ -162,7 +161,7 @@ private:
BOOL mForceClose;
LLPanel* mCodePanel;
LLScrollListCtrl* mErrorList;
LLDynamicArray<LLEntryAndEdCore*> mBridges;
std::vector<LLEntryAndEdCore*> mBridges;
LLHandle<LLFloater> mLiveHelpHandle;
LLKeywordToken* mLastHelpToken;
LLFrameTimer mLiveHelpTimer;

File diff suppressed because it is too large Load Diff

View File

@@ -52,20 +52,15 @@
#define SG_STATE_INHERIT_MASK (OCCLUDED)
#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
class LLViewerOctreePartition;
class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
class LLViewerRegion;
S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad);
S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared);
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
void pushVerts(LLFace* face, U32 mask);
// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
class LLDrawInfo : public LLRefCount
{
@@ -213,13 +208,13 @@ public:
};
LL_ALIGN_PREFIX(64)
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
class LLSpatialGroup : public LLOcclusionCullingGroup
{
friend class LLSpatialPartition;
friend class LLOctreeStateCheck;
public:
LLSpatialGroup(const LLSpatialGroup& rhs)
LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)
{
*this = rhs;
}
@@ -240,7 +235,6 @@ public:
return *this;
}
static std::set<GLuint> sPendingQueries; //pending occlusion queries
static U32 sNodeCount;
static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
@@ -252,14 +246,7 @@ public:
typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
typedef LLOctreeListener<LLDrawable> BaseType;
typedef LLOctreeListener<LLDrawable> OctreeListener;
typedef LLTreeNode<LLDrawable> TreeNode;
typedef LLOctreeNode<LLDrawable> OctreeNode;
typedef LLOctreeRoot<LLDrawable> OctreeRoot;
typedef LLOctreeTraveler<LLDrawable> OctreeTraveler;
typedef LLOctreeNode<LLDrawable>::element_iter element_iter;
typedef LLOctreeNode<LLDrawable>::element_list element_list;
struct CompareDistanceGreater
{
@@ -287,119 +274,59 @@ public:
typedef enum
{
OCCLUDED = 0x00010000,
QUERY_PENDING = 0x00020000,
ACTIVE_OCCLUSION = 0x00040000,
DISCARD_QUERY = 0x00080000,
EARLY_FAIL = 0x00100000,
} eOcclusionState;
typedef enum
{
DEAD = 0x00000001,
DIRTY = 0x00000002,
OBJECT_DIRTY = 0x00000004,
GEOM_DIRTY = 0x00000008,
ALPHA_DIRTY = 0x00000010,
SKIP_FRUSTUM_CHECK = 0x00000020,
IN_IMAGE_QUEUE = 0x00000040,
IMAGE_DIRTY = 0x00000080,
MESH_DIRTY = 0x00000100,
NEW_DRAWINFO = 0x00000200,
IN_BUILD_Q1 = 0x00000400,
IN_BUILD_Q2 = 0x00000800,
GEOM_DIRTY = LLViewerOctreeGroup::INVALID_STATE,
ALPHA_DIRTY = (GEOM_DIRTY << 1),
IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1),
IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1),
MESH_DIRTY = (IMAGE_DIRTY << 1),
NEW_DRAWINFO = (MESH_DIRTY << 1),
IN_BUILD_Q1 = (NEW_DRAWINFO << 1),
IN_BUILD_Q2 = (IN_BUILD_Q1 << 1),
STATE_MASK = 0x0000FFFF,
} eSpatialState;
typedef enum
{
STATE_MODE_SINGLE = 0, //set one node
STATE_MODE_BRANCH, //set entire branch
STATE_MODE_DIFF, //set entire branch as long as current state is different
STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras
} eSetStateMode;
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
BOOL isHUDGroup() ;
BOOL isDead() { return isState(DEAD); }
BOOL isState(eSpatialState state) const; //Using enum type here and below to force type-safeness.
BOOL isOcclusionState(eOcclusionState state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
U32 getState() { return mState; }
void setState(eSpatialState state);
void clearState(eSpatialState state);
void clearDrawMap();
void validate();
void checkStates();
void validateDrawMap();
void setState(eSpatialState state, S32 mode);
void clearState(eSpatialState state, S32 mode);
void setOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE);
void clearOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE);
void clearState(eSpatialState state) {mState &= ~state;}
bool hasState(eSpatialState state) const {return mState & state;}
LLSpatialGroup* getParent();
BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
BOOL addObject(LLDrawable *drawablep);
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
BOOL isVisible() const;
BOOL isRecentlyVisible() const;
void setVisible();
void shift(const LLVector4a &offset);
BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
void unbound();
BOOL rebound();
void checkOcclusion(); //read back last occlusion query (if any)
void doOcclusion(LLCamera* camera); //issue occlusion query
void destroyGL(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
BOOL needsUpdate();
F32 getUpdateUrgency() const;
BOOL changeLOD();
void rebuildGeom();
void rebuildMesh();
void setState(eSpatialState state) {mState |= state;}
void dirtyGeom() { setState(GEOM_DIRTY); }
void dirtyMesh() { setState(MESH_DIRTY); }
//octree wrappers to make code more readable
//element_list& getData() { return mOctreeNode->getData(); } //unused
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
bool isEmpty() const { return mOctreeNode->isEmpty(); }
void drawObjectBox(LLColor4 col);
LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
//LISTENER FUNCTIONS
virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face);
virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
virtual void handleDestruction(const TreeNode* node);
virtual void handleStateChange(const TreeNode* node);
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
typedef enum
{
BOUNDS = 0,
EXTENTS = 2,
OBJECT_BOUNDS = 4,
OBJECT_EXTENTS = 6,
VIEW_ANGLE = 8,
LAST_VIEW_ANGLE = 9,
V4_COUNT = 10
} eV4Index;
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
LL_ALIGN_16(LLVector4a mViewAngle);
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
@@ -408,10 +335,6 @@ public:
protected:
virtual ~LLSpatialGroup();
U32 mState;
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
S32 mLODHash;
static S32 sLODSeed;
public:
@@ -422,16 +345,12 @@ public:
F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
F32 mBuilt;
OctreeNode* mOctreeNode;
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
draw_map_t mDrawMap;
S32 mVisible[LLViewerCamera::NUM_CAMERAS];
F32 mDistance;
F32 mDepth;
F32 mLastUpdateDistance;
@@ -463,7 +382,7 @@ public:
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
class LLSpatialPartition: public LLGeometryManager
class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
{
public:
//static BOOL sFreezeState; //if true, no spatialgroup state updates will be made
@@ -494,7 +413,8 @@ public:
virtual void rebuildMesh(LLSpatialGroup* group);
BOOL visibleObjectsInFrustum(LLCamera& camera);
S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
/*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion=false); // Cull on arbitrary frustum
S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results); // Cull on arbitrary frustum
BOOL isVisible(const LLVector3& v);
bool isHUDPartition() ;
@@ -507,25 +427,19 @@ public:
void renderIntersectingBBoxes(LLCamera* camera);
void restoreGL();
void resetVertexBuffers();
BOOL isOcclusionEnabled();
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
public:
LLSpatialGroup::OctreeNode* mOctree;
LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
// to call asBridge() from the destructor
BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
U32 mBufferUsage;
const BOOL mRenderByGroup;
U32 mLODSeed;
U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
U32 mVertexDataMask;
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
U32 mDrawableType;
U32 mPartitionType;
};
// class for creating bridges between spatial partitions
@@ -707,7 +621,6 @@ class LLVolumeGeometryManager: public LLGeometryManager
DISTANCE_SORT
} eSortType;
virtual ~LLVolumeGeometryManager() { }
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);

View File

@@ -380,6 +380,13 @@ void update_texture_fetch()
gTextureList.updateImages(0.10f);
}
void set_flags_and_update_appearance()
{
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
LLAppearanceMgr::instance().updateAppearanceFromCOF(true, true, no_op);
}
void hooked_process_sound_trigger(LLMessageSystem *msg, void **)
{
process_sound_trigger(msg,NULL);
@@ -2247,12 +2254,17 @@ bool idle_startup()
// This method MUST be called before gInventory.findCategoryUUIDForType because of
// gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.
gInventory.buildParentChildMap();
gInventory.createCommonSystemCategories();
// It's debatable whether this flag is a good idea - sets all
// bits, and in general it isn't true that inventory
// initialization generates all types of changes. Maybe add an
// INITIALIZE mask bit instead?
gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null);
gInventory.notifyObservers();
display_startup();
/*llinfos << "Setting Inventory changed mask and notifying observers" << llendl;
gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null);
gInventory.notifyObservers();*/
//all categories loaded. lets create "My Favorites" category
gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
@@ -2565,15 +2577,35 @@ bool idle_startup()
// Start loading the wearables, textures, gestures
LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
}
// If not first login, we need to fetch COF contents and
// compute appearance from that.
if (isAgentAvatarValid() && !gAgent.isFirstLogin() && !gAgent.isGenderChosen())
{
gAgentWearables.notifyLoadingStarted();
gAgent.setGenderChosen(TRUE);
gAgentWearables.sendDummyAgentWearablesUpdate();
callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(), set_flags_and_update_appearance);
}
display_startup();
// wait precache-delay and for agent's avatar or a lot longer.
if(((timeout_frac > 1.f) && isAgentAvatarValid())
|| (timeout_frac > 3.f))
if((timeout_frac > 1.f) && isAgentAvatarValid())
{
LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
}
else if (timeout_frac > 10.f)
{
// If we exceed the wait above while isAgentAvatarValid is
// not true yet, we will change startup state and
// eventually (once avatar does get created) wind up at
// the gender chooser. This should occur only in very
// unusual circumstances, so set the timeout fairly high
// to minimize mistaken hits here.
LL_WARNS() << "Wait for valid avatar state exceeded "
<< timeout.getElapsedTimeF32() << " will invoke gender chooser" << LL_ENDL;
LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
}
else
{
update_texture_fetch();
@@ -4096,7 +4128,10 @@ bool process_login_success_response(std::string& password, U32& first_sim_size_x
flag = login_flags["gendered"].asString();
if(flag == "Y")
{
gAgent.setGenderChosen(TRUE);
// We don't care about this flag anymore; now base whether
// outfit is chosen on COF contents, initial outfit
// requested and available, etc.
//gAgent.setGenderChosen(TRUE);
}
flag = login_flags["daylight_savings"].asString();

View File

@@ -751,10 +751,10 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co
LLInventoryModel::INCLUDE_TRASH,
asset_id_matches);
if (items.count())
if (items.size())
{
// search for copyable version first
for (S32 i = 0; i < items.count(); i++)
for (S32 i = 0; i < items.size(); i++)
{
LLInventoryItem* itemp = items[i];
LLPermissions item_permissions = itemp->getPermissions();

View File

@@ -282,13 +282,13 @@ void LLCategoryDropDescendentsObserver::done()
LLInventoryModel::EXCLUDE_TRASH);
}
S32 count = items.count();
S32 count = items.size();
if(count)
{
std::set<LLUUID> unique_ids;
for(S32 i = 0; i < count; ++i)
{
unique_ids.insert(items.get(i)->getUUID());
unique_ids.insert(items.at(i)->getUUID());
}
uuid_vec_t ids;
std::back_insert_iterator<uuid_vec_t> copier(ids);
@@ -433,16 +433,16 @@ void LLToolDragAndDrop::beginDrag(EDragAndDropType type,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_not_preferred);
S32 count = cats.count();
S32 count = cats.size();
S32 i;
for(i = 0; i < count; ++i)
{
folder_ids.push_back(cats.get(i)->getUUID());
folder_ids.push_back(cats.at(i)->getUUID());
}
count = items.count();
count = items.size();
for(i = 0; i < count; ++i)
{
item_ids.push_back(items.get(i)->getUUID());
item_ids.push_back(items.at(i)->getUUID());
}
if(!folder_ids.empty() || !item_ids.empty())
{
@@ -504,7 +504,7 @@ void LLToolDragAndDrop::beginMultiDrag(
items,
LLInventoryModel::EXCLUDE_TRASH,
is_not_preferred);
S32 cat_count = cats.count();
S32 cat_count = cats.size();
for(S32 i = 0; i < cat_count; ++i)
{
cat_ids.insert(cat->getUUID());
@@ -803,7 +803,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
if ( !handled )
{
// Disallow drag and drop to 3D from the outbox
const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if (outbox_id.notNull())
{
for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
@@ -1778,7 +1778,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
// LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
// Make this behave consistent with dad3dWearItem
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, !(mask & MASK_CONTROL)));
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, fReplace));
// [/SL:KB]
copy_inventory_item(
gAgent.getID(),
@@ -2341,7 +2341,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
items,
LLInventoryModel::EXCLUDE_TRASH,
droppable);
cats.put(cat);
cats.push_back(cat);
if(droppable.countNoCopy() > 0)
{
LL_WARNS() << "*** Need to confirm this step" << LL_ENDL;
@@ -2583,7 +2583,7 @@ EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand(
items,
LLInventoryModel::EXCLUDE_TRASH,
droppable);
if(items.count() > 0)
if(items.size() > 0)
{
rv = ACCEPT_YES_SINGLE;
}
@@ -2610,14 +2610,14 @@ EAcceptance LLToolDragAndDrop::dad3dAssetOnLand(
LLViewerInventoryItem::item_array_t items;
LLViewerInventoryItem::item_array_t copyable_items;
locateMultipleInventory(items, cats);
if(!items.count()) return ACCEPT_NO;
if(!items.size()) return ACCEPT_NO;
EAcceptance rv = ACCEPT_NO;
for (S32 i = 0; i < items.count(); i++)
for (S32 i = 0; i < items.size(); i++)
{
LLInventoryItem* item = items[i];
if(item->getPermissions().allowCopyBy(gAgent.getID()))
{
copyable_items.put(item);
copyable_items.push_back(item);
rv = ACCEPT_YES_SINGLE;
}
}
@@ -2692,12 +2692,12 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
LLInventoryItem* item = gInventory.getItem(mCargoIDs[i]);
if (item)
{
items.put(item);
items.push_back(item);
}
LLInventoryCategory* category = gInventory.getCategory(mCargoIDs[i]);
if (category)
{
cats.put(category);
cats.push_back(category);
}
}
}
@@ -2716,7 +2716,7 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
LLInventoryCategory* category = (LLInventoryCategory*)obj->getInventoryObject(mCargoIDs[i]);
if (category)
{
cats.put(category);
cats.push_back(category);
}
}
}
@@ -2727,7 +2727,7 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
LLInventoryItem* item = (LLInventoryItem*)obj->getInventoryObject(mCargoIDs[i]);
if (item)
{
items.put(item);
items.push_back(item);
}
}
}
@@ -2739,11 +2739,11 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
card = (LLPreviewNotecard*)LLPreview::find(mSourceID);
if(card)
{
items.put((LLInventoryItem*)card->getDragItem());
items.push_back((LLInventoryItem*)card->getDragItem());
}
}
if(items.count()) return items[0];
if(cats.count()) return cats[0];
if(items.size()) return items[0];
if(cats.size()) return cats[0];
return NULL;
}
*/

View File

@@ -38,7 +38,6 @@
#include "lluuid.h"
#include "stdenums.h"
#include "llassetstorage.h"
#include "lldarray.h"
#include "llpermissions.h"
#include "llwindow.h"
#include "llviewerinventory.h"

Some files were not shown because too many files have changed in this diff Show More