diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5cc53f024bc701b05c9670b3f2d5d823597d9fa0..9117d8da6021c57c5c49a1150a0adabf5b100b87 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5446,6 +5446,10 @@ void LLAppViewer::disconnectViewer() LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false); // [/SL:KB] +// [RLVa:KB] - Checked: RLVa-2.3 (Housekeeping) + SUBSYSTEM_CLEANUP(RlvHandler); +// [/RLVa:KB] + gAgentWearables.cleanup(); gAgentCamera.cleanup(); // Also writes cached agent settings to gSavedSettings diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index db9e182b83c6b4931020c6d0e096d218ee31633e..83a46f3452cf0e9ad70dc71f4f18584fb0b75037 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -145,14 +145,58 @@ RlvHandler::RlvHandler() : m_fCanCancelTp(true), m_posSitSource(), m_pGCTimer(NU RlvHandler::~RlvHandler() { + cleanup(); +} + +void RlvHandler::cleanup() +{ + // Nothing to clean if we're not enabled (or already cleaned up) + if (!m_fEnabled) + return; + + // + // Clean up any restrictions that are still active + // + RLV_ASSERT(LLApp::isQuitting()); // Several commands toggle debug settings but won't if they know the viewer is quitting + + // Assume we have no way to predict how m_Objects will change so make a copy ahead of time + uuid_vec_t idRlvObjects; + idRlvObjects.reserve(m_Objects.size()); + std::transform(m_Objects.begin(), m_Objects.end(), std::back_inserter(idRlvObjects), [](const rlv_object_map_t::value_type& kvPair) {return kvPair.first; }); + for (const LLUUID & idRlvObj : idRlvObjects) + { + processCommand(idRlvObj, "clear", true); + } + + // Sanity check + RLV_ASSERT(m_Objects.empty()); + RLV_ASSERT(m_Exceptions.empty()); + RLV_ASSERT(std::all_of(m_Behaviours, m_Behaviours + RLV_BHVR_COUNT, [](S16 cnt) { return !cnt; })); + RLV_ASSERT(m_CurCommandStack.empty()); + RLV_ASSERT(m_CurObjectStack.empty()); + RLV_ASSERT(m_pOverlayImage.isNull()); + + // + // Clean up what's left + // gAgent.removeListener(this); + m_Retained.clear(); + //delete m_pGCTimer; // <- deletes itself + if (m_PendingGroupChange.first.notNull()) { - LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + if (LLGroupMgr::instanceExists()) + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); } - //delete m_pGCTimer; // <- deletes itself + for (RlvExtCommandHandler* pCmdHandler : m_CommandHandlers) + { + delete pCmdHandler; + } + m_CommandHandlers.clear(); + + m_fEnabled = false; } // ============================================================================ @@ -1032,6 +1076,12 @@ bool RlvHandler::onGC() return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do } +// static +void RlvHandler::cleanupClass() +{ + gRlvHandler.cleanup(); +} + // Checked: 2009-11-26 (RLVa-1.1.0f) | Added: RLVa-1.1.0f void RlvHandler::onIdleStartup(void* pParam) { diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 85acec1bcebc757a72b30b8a5892e23bafa4f999..5a6e5508eb55b8c87eb69983ad53d29db561d672 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -173,6 +173,7 @@ class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGrou // Externally invoked event handlers public: + void cleanup(); void onActiveGroupChanged(); void onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); void onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); @@ -183,6 +184,7 @@ class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGrou void onSitOrStand(bool fSitting); void onTeleportFailed(); void onTeleportFinished(const LLVector3d& posArrival); + static void cleanupClass(); static void onIdleStartup(void* pParam); protected: void getAttachmentResourcesCoro(const std::string& strUrl);