@@ -432,6 +432,10 @@ LLInventoryModel gInventory;
432432LLInventoryModel::LLInventoryModel ()
433433: // These are now ordered, keep them that way.
434434 mBacklinkMMap(),
435+ mAllowAsyncInventoryUpdates(false ),
436+ mAsyncNotifyPending(false ),
437+ mAsyncNotifyTimer(),
438+ mAsyncNotifyIntervalSec(0 .05f ),
435439 mIsAgentInvUsable(false ),
436440 mRootFolderID(),
437441 mLibraryRootFolderID(),
@@ -2209,6 +2213,18 @@ void LLInventoryModel::notifyObservers()
22092213 return ;
22102214 }
22112215
2216+ if (mAllowAsyncInventoryUpdates )
2217+ {
2218+ if (mAsyncNotifyTimer .getElapsedTimeF32 () < mAsyncNotifyIntervalSec )
2219+ {
2220+ mAsyncNotifyPending = true ;
2221+ return ;
2222+ }
2223+
2224+ mAsyncNotifyTimer .reset ();
2225+ mAsyncNotifyPending = false ;
2226+ }
2227+
22122228 mIsNotifyObservers = true ;
22132229 for (observer_list_t ::iterator iter = mObservers .begin ();
22142230 iter != mObservers .end (); )
@@ -3153,6 +3169,23 @@ void LLInventoryModel::buildParentChildMap(bool run_validation)
31533169{
31543170 LL_INFOS (LOG_INV) << " LLInventoryModel::buildParentChildMap()" << LL_ENDL;
31553171
3172+ // Rebuild from scratch so we do not accumulate duplicate children
3173+ // across consecutive calls triggered during async skeleton hydration.
3174+ std::for_each (
3175+ mParentChildCategoryTree .begin (),
3176+ mParentChildCategoryTree .end (),
3177+ DeletePairedPointer ());
3178+ mParentChildCategoryTree .clear ();
3179+
3180+ std::for_each (
3181+ mParentChildItemTree .begin (),
3182+ mParentChildItemTree .end (),
3183+ DeletePairedPointer ());
3184+ mParentChildItemTree .clear ();
3185+
3186+ mCategoryLock .clear ();
3187+ mItemLock .clear ();
3188+
31563189 // *NOTE: I am skipping the logic around folder version
31573190 // synchronization here because it seems if a folder is lost, we
31583191 // might actually want to invalidate it at that point - not
@@ -3423,6 +3456,21 @@ void LLInventoryModel::setAsyncInventoryLoading(bool in_progress)
34233456 }
34243457
34253458 mAllowAsyncInventoryUpdates = in_progress;
3459+ if (mAllowAsyncInventoryUpdates )
3460+ {
3461+ if (gSavedSettings .controlExists (" AsyncInventoryNotifyMinInterval" ))
3462+ {
3463+ mAsyncNotifyIntervalSec = std::clamp (gSavedSettings .getF32 (" AsyncInventoryNotifyMinInterval" ), 0 .0f , 0 .5f );
3464+ }
3465+ mAsyncNotifyTimer .reset ();
3466+ mAsyncNotifyTimer .setAge (mAsyncNotifyIntervalSec );
3467+ mAsyncNotifyPending = false ;
3468+ }
3469+ else
3470+ {
3471+ mAsyncNotifyPending = false ;
3472+ }
3473+
34263474 LL_DEBUGS (LOG_INV) << " Async skeleton loading " << (in_progress ? " enabled" : " disabled" ) << LL_ENDL;
34273475}
34283476
0 commit comments